Merge pull request #276 from Frooodle/pipelineStuff

Start of v0.11
This commit is contained in:
Anthony Stirling 2023-07-19 23:26:57 +01:00 committed by GitHub
commit 37e2cd40da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
73 changed files with 12846 additions and 8464 deletions

7
.gitignore vendored
View file

@ -15,6 +15,13 @@ local.properties
.classpath
.project
version.properties
pipeline/
#### Stirling-PDF Files ###
customFiles/
config/
watchedFolders/
# Gradle
.gradle

View file

@ -10,6 +10,12 @@ RUN apt-get update && \
unoconv && \
rm -rf /var/lib/apt/lists/*
#Install fonts
RUN mkdir /usr/share/fonts/opentype/noto/
COPY src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/
COPY src/main/resources/static/fonts/*.otf /usr/share/fonts/opentype/noto/
RUN fc-cache -f -v
# Copy the application JAR file
COPY build/libs/*.jar app.jar

View file

@ -1,5 +1,8 @@
| Operation | PageOps | Convert | Security | Other | CLI | Python | OpenCV | LibreOffice | OCRmyPDF | Java | Javascript |
|---------------------|---------|---------|----------|-------|------|--------|--------|-------------|----------|----------|------------|
| adjust-contrast | ✔️ | | | | | | | | | | ✔️ |
| auto-split-pdf | ✔️ | | | | | | | | | ✔️ | |
| crop | ✔️ | | | | | | | | | ✔️ | |
| merge-pdfs | ✔️ | | | | | | | | | ✔️ | |
| multi-page-layout | ✔️ | | | | | | | | | ✔️ | |
| pdf-organizer | ✔️ | | | | | | | | | ✔️ | ✔️ |
@ -22,7 +25,10 @@
| cert-sign | | | ✔️ | | | | | | | ✔️ | |
| change-permissions | | | ✔️ | | | | | | | ✔️ | |
| remove-password | | | ✔️ | | | | | | | ✔️ | |
| sanitize-pdf | | | ✔️ | | | | | | | ✔️ | |
| add-image | | | | ✔️ | | | | | | ✔️ | |
| add-page-numbers | | | | ✔️ | | | | | | ✔️ | |
| auto-rename | | | | ✔️ | | | | | | ✔️ | |
| change-metadata | | | | ✔️ | | | | | | ✔️ | |
| compare | | | | ✔️ | | | | | | | ✔️ |
| compress-pdf | | | | ✔️ | ✔️ | | | | ✔️ | | |

View file

@ -86,6 +86,8 @@ docker run -d \
Can also add these for customisation but are not required
-v /location/of/extraConfigs:/configs \
-v /location/of/customFiles:/customFiles \
-e APP_HOME_NAME="Stirling PDF" \
-e APP_HOME_DESCRIPTION="Your locally hosted one-stop-shop for all your PDF needs." \
-e APP_NAVBAR_NAME="Stirling PDF" \
@ -104,6 +106,7 @@ services:
volumes:
- /location/of/trainingData:/usr/share/tesseract-ocr/4.00/tessdata #Required for extra OCR languages
# - /location/of/extraConfigs:/configs
# - /location/of/customFiles:/customFiles/
# environment:
# APP_LOCALE: en_GB
# APP_HOME_NAME: Stirling PDF
@ -161,10 +164,11 @@ Using the same method you can also change
- Change root URI for Stirling-PDF ie change server.com/ to server.com/pdf-app by running APP_ROOT_PATH as pdf-app
- Disable and remove endpoints and functionality from Stirling-PDF. Currently the endpoints ENDPOINTS_TO_REMOVE and GROUPS_TO_REMOVE can include comma seperated lists of endpoints and groups to disable as example ENDPOINTS_TO_REMOVE=img-to-pdf,remove-pages would disable both image to pdf and remove pages, GROUPS_TO_REMOVE=LibreOffice Would disable all things that use LibreOffice. You can see a list of all endpoints and groups [here](https://github.com/Frooodle/Stirling-PDF/blob/main/groups.md)
- Change the max file size allowed through the server with the environment variable MAX_FILE_SIZE. default 2000MB
- Customise static files such as app logo by placing files in the /customFiles/static/ directory. Example to customise app logo is placing a /customFiles/static/favicon.svg to override current SVG. This can be used to change any images/icons/css/fonts/js etc in Stirling-PDF
## API
For those wanting to use Stirling-PDFs backend API to link with their own custom scripting to edit PDFs you can view all existing API documentation
[here](https://app.swaggerhub.com/apis-docs/Frooodle/Stirling-PDF/) or navigate to /swagger-ui/index.html of your stirling-pdf instance for your versions documentation
[here](https://app.swaggerhub.com/apis-docs/Frooodle/Stirling-PDF/) or navigate to /swagger-ui/index.html of your stirling-pdf instance for your versions documentation (Or by following the API button in your settings of Stirling-PDF)
## FAQ

View file

@ -13,9 +13,14 @@
Operation | Ultra-Lite | Lite | Full
--------------------|------------|------|-----
add-page-numbers | ✔️ | ✔️ | ✔️
add-password | ✔️ | ✔️ | ✔️
add-watermark | ✔️ | ✔️ | ✔️
adjust-contrast | ✔️ | ✔️ | ✔️
auto-split-pdf | ✔️ | ✔️ | ✔️
auto-rename | ✔️ | ✔️ | ✔️
cert-sign | ✔️ | ✔️ | ✔️
crop | ✔️ | ✔️ | ✔️
change-metadata | ✔️ | ✔️ | ✔️
change-permissions | ✔️ | ✔️ | ✔️
compare | ✔️ | ✔️ | ✔️
@ -29,6 +34,7 @@ pdf-to-img | ✔️ | ✔️ | ✔️
remove-pages | ✔️ | ✔️ | ✔️
remove-password | ✔️ | ✔️ | ✔️
rotate-pdf | ✔️ | ✔️ | ✔️
sanitize-pdf | ✔️ | ✔️ | ✔️
scale-pages | ✔️ | ✔️ | ✔️
sign | ✔️ | ✔️ | ✔️
split-pdfs | ✔️ | ✔️ | ✔️

View file

@ -8,7 +8,7 @@ plugins {
}
group = 'stirling.software'
version = '0.10.3'
version = '0.11.0'
sourceCompatibility = '17'
repositories {
@ -62,6 +62,8 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-core'
implementation group: 'com.google.zxing', name: 'core', version: '3.5.1'
developmentOnly("org.springframework.boot:spring-boot-devtools")
}

View file

@ -1,5 +1,10 @@
package stirling.software.SPDF;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@ -7,6 +12,7 @@ import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.EnableScheduling;
import jakarta.annotation.PostConstruct;
import stirling.software.SPDF.utils.GeneralUtils;
@SpringBootApplication
//@EnableScheduling
@ -49,6 +55,13 @@ public class SPdfApplication {
// TODO Auto-generated catch block
e.printStackTrace();
}
GeneralUtils.createDir("customFiles/static/");
GeneralUtils.createDir("customFiles/templates/");
GeneralUtils.createDir("config");
System.out.println("Stirling-PDF Started.");
String port = System.getProperty("local.server.port");

View file

@ -68,6 +68,9 @@ public class EndpointConfiguration {
addEndpointToGroup("PageOps", "rotate-pdf");
addEndpointToGroup("PageOps", "multi-page-layout");
addEndpointToGroup("PageOps", "scale-pages");
addEndpointToGroup("PageOps", "adjust-contrast");
addEndpointToGroup("PageOps", "crop");
addEndpointToGroup("PageOps", "auto-split-pdf");
// Adding endpoints to "Convert" group
addEndpointToGroup("Convert", "pdf-to-img");
@ -87,7 +90,7 @@ public class EndpointConfiguration {
addEndpointToGroup("Security", "change-permissions");
addEndpointToGroup("Security", "add-watermark");
addEndpointToGroup("Security", "cert-sign");
addEndpointToGroup("Security", "sanitize-pdf");
// Adding endpoints to "Other" group
@ -102,9 +105,8 @@ public class EndpointConfiguration {
addEndpointToGroup("Other", "repair");
addEndpointToGroup("Other", "remove-blanks");
addEndpointToGroup("Other", "compare");
addEndpointToGroup("Other", "add-page-numbers");
addEndpointToGroup("Other", "auto-rename");
@ -168,12 +170,18 @@ public class EndpointConfiguration {
addEndpointToGroup("Java", "cert-sign");
addEndpointToGroup("Java", "multi-page-layout");
addEndpointToGroup("Java", "scale-pages");
addEndpointToGroup("Java", "add-page-numbers");
addEndpointToGroup("Java", "auto-rename");
addEndpointToGroup("Java", "auto-split-pdf");
addEndpointToGroup("Java", "sanitize-pdf");
addEndpointToGroup("Java", "crop");
//Javascript
addEndpointToGroup("Javascript", "pdf-organizer");
addEndpointToGroup("Javascript", "sign");
addEndpointToGroup("Javascript", "compare");
addEndpointToGroup("Javascript", "adjust-contrast");
}

View file

@ -3,6 +3,7 @@ package stirling.software.SPDF.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@ -15,4 +16,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(endpointInterceptor);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// Handler for external static resources
registry.addResourceHandler("/**")
.addResourceLocations("file:customFiles/static/", "classpath:/static/")
.setCachePeriod(0); // Optional: disable caching
}
}

View file

@ -0,0 +1,132 @@
package stirling.software.SPDF.controller.api;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.utils.GeneralUtils;
import stirling.software.SPDF.utils.WebResponseUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.kernel.pdf.canvas.parser.EventType;
import com.itextpdf.kernel.pdf.canvas.parser.PdfCanvasProcessor;
import com.itextpdf.kernel.pdf.canvas.parser.data.IEventData;
import com.itextpdf.kernel.pdf.canvas.parser.data.TextRenderInfo;
import com.itextpdf.kernel.pdf.canvas.parser.listener.IEventListener;
import com.itextpdf.kernel.pdf.xobject.PdfFormXObject;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.utils.WebResponseUtils;
@RestController
@Tag(name = "General", description = "General APIs")
public class CropController {
private static final Logger logger = LoggerFactory.getLogger(CropController.class);
@PostMapping(value = "/crop", consumes = "multipart/form-data")
@Operation(summary = "Crops a PDF document", description = "This operation takes an input PDF file and crops it according to the given coordinates. Input:PDF Output:PDF Type:SISO")
public ResponseEntity<byte[]> cropPdf(
@Parameter(description = "The input PDF file", required = true) @RequestParam("file") MultipartFile file,
@Parameter(description = "The x-coordinate of the top-left corner of the crop area", required = true, schema = @Schema(type = "number")) @RequestParam("x") float x,
@Parameter(description = "The y-coordinate of the top-left corner of the crop area", required = true, schema = @Schema(type = "number")) @RequestParam("y") float y,
@Parameter(description = "The width of the crop area", required = true, schema = @Schema(type = "number")) @RequestParam("width") float width,
@Parameter(description = "The height of the crop area", required = true, schema = @Schema(type = "number")) @RequestParam("height") float height) throws IOException {
byte[] bytes = file.getBytes();
System.out.println("x=" + x + ", " + "y=" + y + ", " + "width=" + width + ", " +"height=" + height );
PdfReader reader = new PdfReader(new ByteArrayInputStream(bytes));
PdfDocument pdfDoc = new PdfDocument(reader);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(baos);
PdfDocument outputPdf = new PdfDocument(writer);
int totalPages = pdfDoc.getNumberOfPages();
for (int i = 1; i <= totalPages; i++) {
PdfPage page = outputPdf.addNewPage(new PageSize(width, height));
PdfCanvas pdfCanvas = new PdfCanvas(page);
PdfFormXObject formXObject = pdfDoc.getPage(i).copyAsFormXObject(outputPdf);
// Save the graphics state, apply the transformations, add the object, and then
// restore the graphics state
pdfCanvas.saveState();
pdfCanvas.rectangle(x, y, width, height);
pdfCanvas.clip();
pdfCanvas.addXObject(formXObject, -x, -y);
pdfCanvas.restoreState();
}
outputPdf.close();
byte[] pdfContent = baos.toByteArray();
pdfDoc.close();
return WebResponseUtils.bytesToWebResponse(pdfContent,
file.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_cropped.pdf");
}
}

View file

@ -52,11 +52,11 @@ public class ScalePagesController {
@Operation(summary = "Change the size of a PDF page/document", description = "This operation takes an input PDF file and the size to scale the pages to in the output PDF file. Input:PDF Output:PDF Type:SISO")
public ResponseEntity<byte[]> scalePages(
@Parameter(description = "The input PDF file", required = true) @RequestParam("fileInput") MultipartFile file,
@Parameter(description = "The scale of pages in the output PDF. Acceptable values are A0-A10, B0-B9, LETTER, TABLOID, LEDGER, LEGAL, EXECUTIVE.", required = true, schema = @Schema(type = "String", allowableValues = {
@Parameter(description = "The scale of pages in the output PDF. Acceptable values are A0-A10, B0-B9, LETTER, TABLOID, LEDGER, LEGAL, EXECUTIVE.", required = true, schema = @Schema(type = "string", allowableValues = {
"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10", "B0", "B1", "B2", "B3", "B4",
"B5", "B6", "B7", "B8", "B9", "LETTER", "TABLOID", "LEDGER", "LEGAL",
"EXECUTIVE" })) @RequestParam("pageSize") String targetPageSize,
@Parameter(description = "The scale of the content on the pages of the output PDF. Acceptable values are floats.", required = true, schema = @Schema(type = "float")) @RequestParam("scaleFactor") float scaleFactor)
@Parameter(description = "The scale of the content on the pages of the output PDF. Acceptable values are floats.", required = true, schema = @Schema(type = "integer")) @RequestParam("scaleFactor") float scaleFactor)
throws IOException {
Map<String, PageSize> sizeMap = new HashMap<>();

View file

@ -21,62 +21,78 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.utils.PdfUtils;
import stirling.software.SPDF.utils.ProcessExecutor;
import stirling.software.SPDF.utils.WebResponseUtils;
import io.swagger.v3.oas.annotations.media.Schema;
@RestController
@Tag(name = "Filter", description = "Filter APIs")
public class FilterController {
@PostMapping(consumes = "multipart/form-data", value = "/contains-text")
@PostMapping(consumes = "multipart/form-data", value = "/filter-contains-text")
@Operation(summary = "Checks if a PDF contains set text, returns true if does", description = "Input:PDF Output:Boolean Type:SISO")
public Boolean containsText(
public ResponseEntity<byte[]> containsText(
@RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file to be converted to a PDF/A file", required = true) MultipartFile inputFile,
@Parameter(description = "The text to check for", required = true) String text,
@Parameter(description = "The page number to check for text on accepts 'All', ranges like '1-4'", required = false) String pageNumber)
throws IOException, InterruptedException {
PDDocument pdfDocument = PDDocument.load(inputFile.getInputStream());
return PdfUtils.hasText(pdfDocument, pageNumber);
if (PdfUtils.hasText(pdfDocument, pageNumber, text))
return WebResponseUtils.pdfDocToWebResponse(pdfDocument, inputFile.getOriginalFilename());
return null;
}
@PostMapping(consumes = "multipart/form-data", value = "/contains-image")
// TODO
@PostMapping(consumes = "multipart/form-data", value = "/filter-contains-image")
@Operation(summary = "Checks if a PDF contains an image", description = "Input:PDF Output:Boolean Type:SISO")
public Boolean containsImage(
public ResponseEntity<byte[]> containsImage(
@RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file to be converted to a PDF/A file", required = true) MultipartFile inputFile,
@Parameter(description = "The page number to check for image on accepts 'All', ranges like '1-4'", required = false) String pageNumber)
throws IOException, InterruptedException {
PDDocument pdfDocument = PDDocument.load(inputFile.getInputStream());
return PdfUtils.hasImagesOnPage(null);
if (PdfUtils.hasImages(pdfDocument, pageNumber))
return WebResponseUtils.pdfDocToWebResponse(pdfDocument, inputFile.getOriginalFilename());
return null;
}
@PostMapping(consumes = "multipart/form-data", value = "/page-count")
@PostMapping(consumes = "multipart/form-data", value = "/filter-page-count")
@Operation(summary = "Checks if a PDF is greater, less or equal to a setPageCount", description = "Input:PDF Output:Boolean Type:SISO")
public Boolean pageCount(
public ResponseEntity<byte[]> pageCount(
@RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file", required = true) MultipartFile inputFile,
@Parameter(description = "Page Count", required = true) String pageCount,
@Parameter(description = "Comparison type, accepts Greater, Equal, Less than", required = false) String comparator)
@Parameter(description = "Comparison type", schema = @Schema(description = "The comparison type, accepts Greater, Equal, Less than", allowableValues = {
"Greater", "Equal", "Less" })) String comparator)
throws IOException, InterruptedException {
// Load the PDF
PDDocument document = PDDocument.load(inputFile.getInputStream());
int actualPageCount = document.getNumberOfPages();
boolean valid = false;
// Perform the comparison
switch (comparator) {
case "Greater":
return actualPageCount > Integer.parseInt(pageCount);
valid = actualPageCount > Integer.parseInt(pageCount);
break;
case "Equal":
return actualPageCount == Integer.parseInt(pageCount);
valid = actualPageCount == Integer.parseInt(pageCount);
break;
case "Less":
return actualPageCount < Integer.parseInt(pageCount);
valid = actualPageCount < Integer.parseInt(pageCount);
break;
default:
throw new IllegalArgumentException("Invalid comparator: " + comparator);
}
if (valid)
return WebResponseUtils.multiPartFileToWebResponse(inputFile);
return null;
}
@PostMapping(consumes = "multipart/form-data", value = "/page-size")
@PostMapping(consumes = "multipart/form-data", value = "/filter-page-size")
@Operation(summary = "Checks if a PDF is of a certain size", description = "Input:PDF Output:Boolean Type:SISO")
public Boolean pageSize(
public ResponseEntity<byte[]> pageSize(
@RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file", required = true) MultipartFile inputFile,
@Parameter(description = "Standard Page Size", required = true) String standardPageSize,
@Parameter(description = "Comparison type, accepts Greater, Equal, Less than", required = false) String comparator)
@Parameter(description = "Comparison type", schema = @Schema(description = "The comparison type, accepts Greater, Equal, Less than", allowableValues = {
"Greater", "Equal", "Less" })) String comparator)
throws IOException, InterruptedException {
// Load the PDF
@ -92,51 +108,67 @@ public class FilterController {
PDRectangle standardSize = PdfUtils.textToPageSize(standardPageSize);
float standardArea = standardSize.getWidth() * standardSize.getHeight();
boolean valid = false;
// Perform the comparison
switch (comparator) {
case "Greater":
return actualArea > standardArea;
valid = actualArea > standardArea;
break;
case "Equal":
return actualArea == standardArea;
valid = actualArea == standardArea;
break;
case "Less":
return actualArea < standardArea;
valid = actualArea < standardArea;
break;
default:
throw new IllegalArgumentException("Invalid comparator: " + comparator);
}
if (valid)
return WebResponseUtils.multiPartFileToWebResponse(inputFile);
return null;
}
@PostMapping(consumes = "multipart/form-data", value = "/file-size")
@PostMapping(consumes = "multipart/form-data", value = "/filter-file-size")
@Operation(summary = "Checks if a PDF is a set file size", description = "Input:PDF Output:Boolean Type:SISO")
public Boolean fileSize(
public ResponseEntity<byte[]> fileSize(
@RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file", required = true) MultipartFile inputFile,
@Parameter(description = "File Size", required = true) String fileSize,
@Parameter(description = "Comparison type, accepts Greater, Equal, Less than", required = false) String comparator)
@Parameter(description = "Comparison type", schema = @Schema(description = "The comparison type, accepts Greater, Equal, Less than", allowableValues = {
"Greater", "Equal", "Less" })) String comparator)
throws IOException, InterruptedException {
// Get the file size
long actualFileSize = inputFile.getSize();
boolean valid = false;
// Perform the comparison
switch (comparator) {
case "Greater":
return actualFileSize > Long.parseLong(fileSize);
valid = actualFileSize > Long.parseLong(fileSize);
break;
case "Equal":
return actualFileSize == Long.parseLong(fileSize);
valid = actualFileSize == Long.parseLong(fileSize);
break;
case "Less":
return actualFileSize < Long.parseLong(fileSize);
valid = actualFileSize < Long.parseLong(fileSize);
break;
default:
throw new IllegalArgumentException("Invalid comparator: " + comparator);
}
if (valid)
return WebResponseUtils.multiPartFileToWebResponse(inputFile);
return null;
}
@PostMapping(consumes = "multipart/form-data", value = "/page-rotation")
@PostMapping(consumes = "multipart/form-data", value = "/filter-page-rotation")
@Operation(summary = "Checks if a PDF is of a certain rotation", description = "Input:PDF Output:Boolean Type:SISO")
public Boolean pageRotation(
public ResponseEntity<byte[]> pageRotation(
@RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file", required = true) MultipartFile inputFile,
@Parameter(description = "Rotation in degrees", required = true) int rotation,
@Parameter(description = "Comparison type, accepts Greater, Equal, Less than", required = false) String comparator)
@Parameter(description = "Comparison type", schema = @Schema(description = "The comparison type, accepts Greater, Equal, Less than", allowableValues = {
"Greater", "Equal", "Less" })) String comparator)
throws IOException, InterruptedException {
// Load the PDF
@ -145,18 +177,26 @@ public class FilterController {
// Get the rotation of the first page
PDPage firstPage = document.getPage(0);
int actualRotation = firstPage.getRotation();
boolean valid = false;
// Perform the comparison
switch (comparator) {
case "Greater":
return actualRotation > rotation;
valid = actualRotation > rotation;
break;
case "Equal":
return actualRotation == rotation;
valid = actualRotation == rotation;
break;
case "Less":
return actualRotation < rotation;
valid = actualRotation < rotation;
break;
default:
throw new IllegalArgumentException("Invalid comparator: " + comparator);
}
if (valid)
return WebResponseUtils.multiPartFileToWebResponse(inputFile);
return null;
}
}

View file

@ -0,0 +1,177 @@
package stirling.software.SPDF.controller.api.other;
import java.io.IOException;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.utils.GeneralUtils;
import stirling.software.SPDF.utils.PdfUtils;
import stirling.software.SPDF.utils.WebResponseUtils;
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.pdmodel.common.*;
import org.apache.pdfbox.pdmodel.PDPageContentStream.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.*;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.*;
import io.swagger.v3.oas.annotations.media.*;
import io.swagger.v3.oas.annotations.parameters.*;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.text.TextPosition;
import org.apache.tomcat.util.http.ResponseUtil;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.ArrayList;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import com.itextpdf.io.font.constants.StandardFonts;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.properties.TextAlignment;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.*;
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.text.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.*;
import io.swagger.v3.oas.annotations.media.Schema;
import org.springframework.http.ResponseEntity;
@RestController
@Tag(name = "Other", description = "Other APIs")
public class AutoRenameController {
private static final Logger logger = LoggerFactory.getLogger(AutoRenameController.class);
private static final float TITLE_FONT_SIZE_THRESHOLD = 20.0f;
private static final int LINE_LIMIT = 11;
@PostMapping(consumes = "multipart/form-data", value = "/auto-rename")
@Operation(summary = "Extract header from PDF file", description = "This endpoint accepts a PDF file and attempts to extract its title or header based on heuristics. Input:PDF Output:PDF Type:SISO")
public ResponseEntity<byte[]> extractHeader(
@RequestPart(value = "fileInput") @Parameter(description = "The input PDF file from which the header is to be extracted.", required = true) MultipartFile file,
@RequestParam(required = false, defaultValue = "false") @Parameter(description = "Flag indicating whether to use the first text as a fallback if no suitable title is found. Defaults to false.", required = false) Boolean useFirstTextAsFallback)
throws Exception {
PDDocument document = PDDocument.load(file.getInputStream());
PDFTextStripper reader = new PDFTextStripper() {
class LineInfo {
String text;
float fontSize;
LineInfo(String text, float fontSize) {
this.text = text;
this.fontSize = fontSize;
}
}
List<LineInfo> lineInfos = new ArrayList<>();
StringBuilder lineBuilder = new StringBuilder();
float lastY = -1;
float maxFontSizeInLine = 0.0f;
int lineCount = 0;
@Override
protected void processTextPosition(TextPosition text) {
if (lastY != text.getY() && lineCount < LINE_LIMIT) {
processLine();
lineBuilder = new StringBuilder(text.getUnicode());
maxFontSizeInLine = text.getFontSizeInPt();
lastY = text.getY();
lineCount++;
} else if (lineCount < LINE_LIMIT) {
lineBuilder.append(text.getUnicode());
if (text.getFontSizeInPt() > maxFontSizeInLine) {
maxFontSizeInLine = text.getFontSizeInPt();
}
}
}
private void processLine() {
if (lineBuilder.length() > 0 && lineCount < LINE_LIMIT) {
lineInfos.add(new LineInfo(lineBuilder.toString(), maxFontSizeInLine));
}
}
@Override
public String getText(PDDocument doc) throws IOException {
this.lineInfos.clear();
this.lineBuilder = new StringBuilder();
this.lastY = -1;
this.maxFontSizeInLine = 0.0f;
this.lineCount = 0;
super.getText(doc);
processLine(); // Process the last line
// Merge lines with same font size
List<LineInfo> mergedLineInfos = new ArrayList<>();
for (int i = 0; i < lineInfos.size(); i++) {
String mergedText = lineInfos.get(i).text;
float fontSize = lineInfos.get(i).fontSize;
while (i + 1 < lineInfos.size() && lineInfos.get(i + 1).fontSize == fontSize) {
mergedText += " " + lineInfos.get(i + 1).text;
i++;
}
mergedLineInfos.add(new LineInfo(mergedText, fontSize));
}
// Sort lines by font size in descending order and get the first one
mergedLineInfos.sort(Comparator.comparing((LineInfo li) -> li.fontSize).reversed());
String title = mergedLineInfos.isEmpty() ? null : mergedLineInfos.get(0).text;
return title != null ? title : (useFirstTextAsFallback ? (mergedLineInfos.isEmpty() ? null : mergedLineInfos.get(mergedLineInfos.size() - 1).text) : null);
}
};
String header = reader.getText(document);
// Sanitize the header string by removing characters not allowed in a filename.
if (header != null && header.length() < 255) {
header = header.replaceAll("[/\\\\?%*:|\"<>]", "");
return WebResponseUtils.pdfDocToWebResponse(document, header + ".pdf");
} else {
logger.info("File has no good title to be found");
return WebResponseUtils.pdfDocToWebResponse(document, file.getOriginalFilename());
}
}
}

View file

@ -0,0 +1,137 @@
package stirling.software.SPDF.controller.api.other;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import stirling.software.SPDF.utils.WebResponseUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@RestController
public class AutoSplitPdfController {
private static final String QR_CONTENT = "https://github.com/Frooodle/Stirling-PDF";
@PostMapping(value = "/auto-split-pdf", consumes = "multipart/form-data")
@Operation(summary = "Auto split PDF pages into separate documents", description = "This endpoint accepts a PDF file, scans each page for a specific QR code, and splits the document at the QR code boundaries. The output is a zip file containing each separate PDF document. Input:PDF Output:ZIP Type:SISO")
public ResponseEntity<byte[]> autoSplitPdf(
@RequestParam("fileInput") @Parameter(description = "The input PDF file which needs to be split into separate documents based on QR code boundaries.", required = true) MultipartFile file)
throws IOException {
InputStream inputStream = file.getInputStream();
PDDocument document = PDDocument.load(inputStream);
PDFRenderer pdfRenderer = new PDFRenderer(document);
List<PDDocument> splitDocuments = new ArrayList<>();
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>(); // create this list to store ByteArrayOutputStreams for zipping
for (int page = 0; page < document.getNumberOfPages(); ++page) {
BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 150);
String result = decodeQRCode(bim);
if(QR_CONTENT.equals(result) && page != 0) {
splitDocuments.add(new PDDocument());
}
if (!splitDocuments.isEmpty() && !QR_CONTENT.equals(result)) {
splitDocuments.get(splitDocuments.size() - 1).addPage(document.getPage(page));
} else if (page == 0) {
PDDocument firstDocument = new PDDocument();
firstDocument.addPage(document.getPage(page));
splitDocuments.add(firstDocument);
}
}
// After all pages are added to splitDocuments, convert each to ByteArrayOutputStream and add to splitDocumentsBoas
for (PDDocument splitDocument : splitDocuments) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
splitDocument.save(baos);
splitDocumentsBoas.add(baos);
splitDocument.close();
}
document.close();
// After this line, you can find your zip logic integrated
Path zipFile = Files.createTempFile("split_documents", ".zip");
String filename = file.getOriginalFilename().replaceFirst("[.][^.]+$", "");
byte[] data;
try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(zipFile))) {
// loop through the split documents and write them to the zip file
for (int i = 0; i < splitDocumentsBoas.size(); i++) {
String fileName = filename + "_" + (i + 1) + ".pdf"; // You should replace "originalFileName" with the real file name
ByteArrayOutputStream baos = splitDocumentsBoas.get(i);
byte[] pdf = baos.toByteArray();
// Add PDF file to the zip
ZipEntry pdfEntry = new ZipEntry(fileName);
zipOut.putNextEntry(pdfEntry);
zipOut.write(pdf);
zipOut.closeEntry();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
data = Files.readAllBytes(zipFile);
Files.delete(zipFile);
}
// return the Resource in the response
return WebResponseUtils.bytesToWebResponse(data, filename + ".zip", MediaType.APPLICATION_OCTET_STREAM);
}
private static String decodeQRCode(BufferedImage bufferedImage) {
LuminanceSource source;
if (bufferedImage.getRaster().getDataBuffer() instanceof DataBufferByte) {
byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData();
source = new PlanarYUVLuminanceSource(pixels, bufferedImage.getWidth(), bufferedImage.getHeight(), 0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), false);
} else if (bufferedImage.getRaster().getDataBuffer() instanceof DataBufferInt) {
int[] pixels = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData();
byte[] newPixels = new byte[pixels.length];
for (int i = 0; i < pixels.length; i++) {
newPixels[i] = (byte) (pixels[i] & 0xff);
}
source = new PlanarYUVLuminanceSource(newPixels, bufferedImage.getWidth(), bufferedImage.getHeight(), 0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), false);
} else {
throw new IllegalArgumentException("BufferedImage must have 8-bit gray scale, 24-bit RGB, 32-bit ARGB (packed int), byte gray, or 3-byte/4-byte RGB image data");
}
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
Result result = new MultiFormatReader().decode(bitmap);
return result.getText();
} catch (NotFoundException e) {
return null; // there is no QR code in the image
}
}
}

View file

@ -221,6 +221,15 @@ public class CompressController {
// Read the optimized PDF file
byte[] pdfBytes = Files.readAllBytes(tempOutputFile);
// Check if optimized file is larger than the original
if(pdfBytes.length > inputFileSize) {
// Log the occurrence
logger.warn("Optimized file is larger than the original. Returning the original file instead.");
// Read the original file again
pdfBytes = Files.readAllBytes(tempInputFile);
}
// Clean up the temporary files
Files.delete(tempInputFile);
Files.delete(tempOutputFile);

View file

@ -0,0 +1,176 @@
package stirling.software.SPDF.controller.api.other;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.utils.GeneralUtils;
import stirling.software.SPDF.utils.PdfUtils;
import stirling.software.SPDF.utils.WebResponseUtils;
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.pdmodel.common.*;
import org.apache.pdfbox.pdmodel.PDPageContentStream.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.*;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.*;
import io.swagger.v3.oas.annotations.media.*;
import io.swagger.v3.oas.annotations.parameters.*;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.tomcat.util.http.ResponseUtil;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import com.itextpdf.io.font.constants.StandardFonts;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.properties.TextAlignment;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.*;
@RestController
@Tag(name = "Other", description = "Other APIs")
public class PageNumbersController {
private static final Logger logger = LoggerFactory.getLogger(PageNumbersController.class);
@PostMapping(value = "/add-page-numbers", consumes = "multipart/form-data")
@Operation(summary = "Add page numbers to a PDF document", description = "This operation takes an input PDF file and adds page numbers to it. Input:PDF Output:PDF Type:SISO")
public ResponseEntity<byte[]> addPageNumbers(
@Parameter(description = "The input PDF file", required = true) @RequestParam("fileInput") MultipartFile file,
@Parameter(description = "Custom margin: small/medium/large", required = true, schema = @Schema(type = "string", allowableValues = {"small", "medium", "large"})) @RequestParam("customMargin") String customMargin,
@Parameter(description = "Position: 1 of 9 positions", required = true, schema = @Schema(type = "integer", minimum = "1", maximum = "9")) @RequestParam("position") int position,
@Parameter(description = "Starting number", required = true, schema = @Schema(type = "integer", minimum = "1")) @RequestParam("startingNumber") int startingNumber,
@Parameter(description = "Which pages to number, default all", required = false, schema = @Schema(type = "string")) @RequestParam(value = "pagesToNumber", required = false) String pagesToNumber,
@Parameter(description = "Custom text: defaults to just number but can have things like \"Page {n} of {p}\"", required = false, schema = @Schema(type = "string")) @RequestParam(value = "customText", required = false) String customText)
throws IOException {
byte[] fileBytes = file.getBytes();
ByteArrayInputStream bais = new ByteArrayInputStream(fileBytes);
int pageNumber = startingNumber;
float marginFactor;
switch (customMargin.toLowerCase()) {
case "small":
marginFactor = 0.02f;
break;
case "medium":
marginFactor = 0.035f;
break;
case "large":
marginFactor = 0.05f;
break;
case "x-large":
marginFactor = 0.1f;
break;
default:
marginFactor = 0.035f;
break;
}
float fontSize = 12.0f;
PdfReader reader = new PdfReader(bais);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(baos);
PdfDocument pdfDoc = new PdfDocument(reader, writer);
List<Integer> pagesToNumberList = GeneralUtils.parsePageList(pagesToNumber.split(","), pdfDoc.getNumberOfPages());
for (int i : pagesToNumberList) {
PdfPage page = pdfDoc.getPage(i+1);
Rectangle pageSize = page.getPageSize();
PdfCanvas pdfCanvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), pdfDoc);
String text = customText != null ? customText.replace("{n}", String.valueOf(pageNumber)).replace("{total}", String.valueOf(pdfDoc.getNumberOfPages())) : String.valueOf(pageNumber);
PdfFont font = PdfFontFactory.createFont(StandardFonts.HELVETICA);
float textWidth = font.getWidth(text, fontSize);
float textHeight = font.getAscent(text, fontSize) - font.getDescent(text, fontSize);
float x, y;
TextAlignment alignment;
int xGroup = (position - 1) % 3;
int yGroup = 2 - (position - 1) / 3;
switch (xGroup) {
case 0: // left
x = pageSize.getLeft() + marginFactor * pageSize.getWidth();
alignment = TextAlignment.LEFT;
break;
case 1: // center
x = pageSize.getLeft() + (pageSize.getWidth()) / 2;
alignment = TextAlignment.CENTER;
break;
default: // right
x = pageSize.getRight() - marginFactor * pageSize.getWidth();
alignment = TextAlignment.RIGHT;
break;
}
switch (yGroup) {
case 0: // bottom
y = pageSize.getBottom() + marginFactor * pageSize.getHeight();
break;
case 1: // middle
y = pageSize.getBottom() + (pageSize.getHeight() ) / 2;
break;
default: // top
y = pageSize.getTop() - marginFactor * pageSize.getHeight();
break;
}
new Canvas(pdfCanvas, page.getPageSize())
.showTextAligned(new Paragraph(text).setFont(font).setFontSize(fontSize), x, y, alignment);
pageNumber++;
}
pdfDoc.close();
byte[] resultBytes = baos.toByteArray();
return ResponseEntity.ok()
.header("Content-Type", "application/pdf; charset=UTF-8")
.header("Content-Disposition", "inline; filename=" + URLEncoder.encode(file.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_numbersAdded.pdf", "UTF-8"))
.body(resultBytes);
}
}

View file

@ -1,399 +0,0 @@
package stirling.software.SPDF.controller.api.pipeline;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.PipelineConfig;
import stirling.software.SPDF.model.PipelineOperation;
import stirling.software.SPDF.utils.WebResponseUtils;
@RestController
@Tag(name = "Pipeline", description = "Pipeline APIs")
public class Controller {
@Autowired
private ObjectMapper objectMapper;
final String jsonFileName = "pipelineCofig.json";
final String watchedFoldersDir = "watchedFolders/";
@Scheduled(fixedRate = 5000)
public void scanFolders() {
Path watchedFolderPath = Paths.get(watchedFoldersDir);
if (!Files.exists(watchedFolderPath)) {
try {
Files.createDirectories(watchedFolderPath);
} catch (IOException e) {
e.printStackTrace();
return;
}
}
try (Stream<Path> paths = Files.walk(watchedFolderPath)) {
paths.filter(Files::isDirectory).forEach(t -> {
try {
if (!t.equals(watchedFolderPath) && !t.endsWith("processing")) {
handleDirectory(t);
}
} catch (Exception e) {
e.printStackTrace();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
private void handleDirectory(Path dir) throws Exception {
Path jsonFile = dir.resolve(jsonFileName);
Path processingDir = dir.resolve("processing"); // Directory to move files during processing
if (!Files.exists(processingDir)) {
Files.createDirectory(processingDir);
}
if (Files.exists(jsonFile)) {
// Read JSON file
String jsonString;
try {
jsonString = new String(Files.readAllBytes(jsonFile));
} catch (IOException e) {
e.printStackTrace();
return;
}
// Decode JSON to PipelineConfig
PipelineConfig config;
try {
config = objectMapper.readValue(jsonString, PipelineConfig.class);
// Assuming your PipelineConfig class has getters for all necessary fields, you can perform checks here
if (config.getOperations() == null || config.getOutputDir() == null || config.getName() == null) {
throw new IOException("Invalid JSON format");
}
} catch (IOException e) {
e.printStackTrace();
return;
}
// For each operation in the pipeline
for (PipelineOperation operation : config.getOperations()) {
// Collect all files based on fileInput
File[] files;
String fileInput = (String) operation.getParameters().get("fileInput");
if ("automated".equals(fileInput)) {
// If fileInput is "automated", process all files in the directory
try (Stream<Path> paths = Files.list(dir)) {
files = paths.filter(path -> !path.equals(jsonFile))
.map(Path::toFile)
.toArray(File[]::new);
} catch (IOException e) {
e.printStackTrace();
return;
}
} else {
// If fileInput contains a path, process only this file
files = new File[]{new File(fileInput)};
}
// Prepare the files for processing
File[] filesToProcess = files.clone();
for (File file : filesToProcess) {
Files.move(file.toPath(), processingDir.resolve(file.getName()));
}
// Process the files
try {
List<Resource> resources = handleFiles(filesToProcess, jsonString);
// Move resultant files and rename them as per config in JSON file
for (Resource resource : resources) {
String outputFileName = config.getOutputPattern().replace("{filename}", resource.getFile().getName());
outputFileName = outputFileName.replace("{pipelineName}", config.getName());
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
outputFileName = outputFileName.replace("{date}", LocalDate.now().format(dateFormatter));
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HHmmss");
outputFileName = outputFileName.replace("{time}", LocalTime.now().format(timeFormatter));
// {filename} {folder} {date} {tmime} {pipeline}
Files.move(resource.getFile().toPath(), Paths.get(config.getOutputDir(), outputFileName));
}
// If successful, delete the original files
for (File file : filesToProcess) {
Files.deleteIfExists(processingDir.resolve(file.getName()));
}
} catch (Exception e) {
// If an error occurs, move the original files back
for (File file : filesToProcess) {
Files.move(processingDir.resolve(file.getName()), file.toPath());
}
throw e;
}
}
}
}
List<Resource> processFiles(List<Resource> outputFiles, String jsonString) throws Exception{
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(jsonString);
JsonNode pipelineNode = jsonNode.get("pipeline");
ByteArrayOutputStream logStream = new ByteArrayOutputStream();
PrintStream logPrintStream = new PrintStream(logStream);
boolean hasErrors = false;
for (JsonNode operationNode : pipelineNode) {
String operation = operationNode.get("operation").asText();
JsonNode parametersNode = operationNode.get("parameters");
String inputFileExtension = "";
if(operationNode.has("inputFileType")) {
inputFileExtension = operationNode.get("inputFileType").asText();
} else {
inputFileExtension=".pdf";
}
List<Resource> newOutputFiles = new ArrayList<>();
boolean hasInputFileType = false;
for (Resource file : outputFiles) {
if (file.getFilename().endsWith(inputFileExtension)) {
hasInputFileType = true;
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("fileInput", file);
Iterator<Map.Entry<String, JsonNode>> parameters = parametersNode.fields();
while (parameters.hasNext()) {
Map.Entry<String, JsonNode> parameter = parameters.next();
body.add(parameter.getKey(), parameter.getValue().asText());
}
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(body, headers);
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8080/" + operation;
ResponseEntity<byte[]> response = restTemplate.exchange(url, HttpMethod.POST, entity, byte[].class);
if (!response.getStatusCode().equals(HttpStatus.OK)) {
logPrintStream.println("Error: " + response.getBody());
hasErrors = true;
continue;
}
// Check if the response body is a zip file
if (isZip(response.getBody())) {
// Unzip the file and add all the files to the new output files
newOutputFiles.addAll(unzip(response.getBody()));
} else {
Resource outputResource = new ByteArrayResource(response.getBody()) {
@Override
public String getFilename() {
return file.getFilename(); // Preserving original filename
}
};
newOutputFiles.add(outputResource);
}
}
if (!hasInputFileType) {
logPrintStream.println("No files with extension " + inputFileExtension + " found for operation " + operation);
hasErrors = true;
}
outputFiles = newOutputFiles;
}
logPrintStream.close();
}
return outputFiles;
}
List<Resource> handleFiles(File[] files, String jsonString) throws Exception{
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(jsonString);
JsonNode pipelineNode = jsonNode.get("pipeline");
ByteArrayOutputStream logStream = new ByteArrayOutputStream();
PrintStream logPrintStream = new PrintStream(logStream);
boolean hasErrors = false;
List<Resource> outputFiles = new ArrayList<>();
for (File file : files) {
Path path = Paths.get(file.getAbsolutePath());
Resource fileResource = new ByteArrayResource(Files.readAllBytes(path)) {
@Override
public String getFilename() {
return file.getName();
}
};
outputFiles.add(fileResource);
}
return processFiles(outputFiles, jsonString);
}
List<Resource> handleFiles(MultipartFile[] files, String jsonString) throws Exception{
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(jsonString);
JsonNode pipelineNode = jsonNode.get("pipeline");
ByteArrayOutputStream logStream = new ByteArrayOutputStream();
PrintStream logPrintStream = new PrintStream(logStream);
boolean hasErrors = false;
List<Resource> outputFiles = new ArrayList<>();
for (MultipartFile file : files) {
Resource fileResource = new ByteArrayResource(file.getBytes()) {
@Override
public String getFilename() {
return file.getOriginalFilename();
}
};
outputFiles.add(fileResource);
}
return processFiles(outputFiles, jsonString);
}
@PostMapping("/handleData")
public ResponseEntity<byte[]> handleData(@RequestPart("fileInput") MultipartFile[] files,
@RequestParam("json") String jsonString) {
try {
List<Resource> outputFiles = handleFiles(files, jsonString);
if (outputFiles.size() == 1) {
// If there is only one file, return it directly
Resource singleFile = outputFiles.get(0);
InputStream is = singleFile.getInputStream();
byte[] bytes = new byte[(int)singleFile.contentLength()];
is.read(bytes);
is.close();
return WebResponseUtils.bytesToWebResponse(bytes, singleFile.getFilename(), MediaType.APPLICATION_OCTET_STREAM);
}
// Create a ByteArrayOutputStream to hold the zip
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zipOut = new ZipOutputStream(baos);
// Loop through each file and add it to the zip
for (Resource file : outputFiles) {
ZipEntry zipEntry = new ZipEntry(file.getFilename());
zipOut.putNextEntry(zipEntry);
// Read the file into a byte array
InputStream is = file.getInputStream();
byte[] bytes = new byte[(int)file.contentLength()];
is.read(bytes);
// Write the bytes of the file to the zip
zipOut.write(bytes, 0, bytes.length);
zipOut.closeEntry();
is.close();
}
zipOut.close();
return WebResponseUtils.boasToWebResponse(baos, "output.zip", MediaType.APPLICATION_OCTET_STREAM);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private boolean isZip(byte[] data) {
if (data == null || data.length < 4) {
return false;
}
// Check the first four bytes of the data against the standard zip magic number
return data[0] == 0x50 && data[1] == 0x4B && data[2] == 0x03 && data[3] == 0x04;
}
private List<Resource> unzip(byte[] data) throws IOException {
List<Resource> unzippedFiles = new ArrayList<>();
try (ByteArrayInputStream bais = new ByteArrayInputStream(data);
ZipInputStream zis = new ZipInputStream(bais)) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int count;
while ((count = zis.read(buffer)) != -1) {
baos.write(buffer, 0, count);
}
final String filename = entry.getName();
Resource fileResource = new ByteArrayResource(baos.toByteArray()) {
@Override
public String getFilename() {
return filename;
}
};
// If the unzipped file is a zip file, unzip it
if (isZip(baos.toByteArray())) {
unzippedFiles.addAll(unzip(baos.toByteArray()));
} else {
unzippedFiles.add(fileResource);
}
}
}
return unzippedFiles;
}
}

View file

@ -0,0 +1,516 @@
package stirling.software.SPDF.controller.api.pipeline;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.PipelineConfig;
import stirling.software.SPDF.model.PipelineOperation;
import stirling.software.SPDF.utils.WebResponseUtils;
@RestController
@Tag(name = "Pipeline", description = "Pipeline APIs")
public class PipelineController {
private static final Logger logger = LoggerFactory.getLogger(PipelineController.class);
@Autowired
private ObjectMapper objectMapper;
final String jsonFileName = "pipelineConfig.json";
final String watchedFoldersDir = "./pipeline/watchedFolders/";
final String finishedFoldersDir = "./pipeline/finishedFolders/";
@Scheduled(fixedRate = 25000)
public void scanFolders() {
logger.info("Scanning folders...");
Path watchedFolderPath = Paths.get(watchedFoldersDir);
if (!Files.exists(watchedFolderPath)) {
try {
Files.createDirectories(watchedFolderPath);
logger.info("Created directory: {}", watchedFolderPath);
} catch (IOException e) {
logger.error("Error creating directory: {}", watchedFolderPath, e);
return;
}
}
try (Stream<Path> paths = Files.walk(watchedFolderPath)) {
paths.filter(Files::isDirectory).forEach(t -> {
try {
if (!t.equals(watchedFolderPath) && !t.endsWith("processing")) {
handleDirectory(t);
}
} catch (Exception e) {
logger.error("Error handling directory: {}", t, e);
}
});
} catch (Exception e) {
logger.error("Error walking through directory: {}", watchedFolderPath, e);
}
}
private void handleDirectory(Path dir) throws Exception {
logger.info("Handling directory: {}", dir);
Path jsonFile = dir.resolve(jsonFileName);
Path processingDir = dir.resolve("processing"); // Directory to move files during processing
if (!Files.exists(processingDir)) {
Files.createDirectory(processingDir);
logger.info("Created processing directory: {}", processingDir);
}
if (Files.exists(jsonFile)) {
// Read JSON file
String jsonString;
try {
jsonString = new String(Files.readAllBytes(jsonFile));
logger.info("Read JSON file: {}", jsonFile);
} catch (IOException e) {
logger.error("Error reading JSON file: {}", jsonFile, e);
return;
}
// Decode JSON to PipelineConfig
PipelineConfig config;
try {
config = objectMapper.readValue(jsonString, PipelineConfig.class);
// Assuming your PipelineConfig class has getters for all necessary fields, you
// can perform checks here
if (config.getOperations() == null || config.getOutputDir() == null || config.getName() == null) {
throw new IOException("Invalid JSON format");
}
} catch (IOException e) {
logger.error("Error parsing PipelineConfig: {}", jsonString, e);
return;
}
// For each operation in the pipeline
for (PipelineOperation operation : config.getOperations()) {
// Collect all files based on fileInput
File[] files;
String fileInput = (String) operation.getParameters().get("fileInput");
if ("automated".equals(fileInput)) {
// If fileInput is "automated", process all files in the directory
try (Stream<Path> paths = Files.list(dir)) {
files = paths
.filter(path -> !Files.isDirectory(path)) // exclude directories
.filter(path -> !path.equals(jsonFile)) // exclude jsonFile
.map(Path::toFile)
.toArray(File[]::new);
} catch (IOException e) {
e.printStackTrace();
return;
}
} else {
// If fileInput contains a path, process only this file
files = new File[] { new File(fileInput) };
}
// Prepare the files for processing
List<File> filesToProcess = new ArrayList<>();
for (File file : files) {
logger.info(file.getName());
logger.info("{} to {}",file.toPath(), processingDir.resolve(file.getName()));
Files.move(file.toPath(), processingDir.resolve(file.getName()));
filesToProcess.add(processingDir.resolve(file.getName()).toFile());
}
// Process the files
try {
List<Resource> resources = handleFiles(filesToProcess.toArray(new File[0]), jsonString);
if(resources == null) {
return;
}
// Move resultant files and rename them as per config in JSON file
for (Resource resource : resources) {
String resourceName = resource.getFilename();
String baseName = resourceName.substring(0, resourceName.lastIndexOf("."));
String extension = resourceName.substring(resourceName.lastIndexOf(".")+1);
String outputFileName = config.getOutputPattern().replace("{filename}", baseName);
outputFileName = outputFileName.replace("{pipelineName}", config.getName());
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
outputFileName = outputFileName.replace("{date}", LocalDate.now().format(dateFormatter));
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HHmmss");
outputFileName = outputFileName.replace("{time}", LocalTime.now().format(timeFormatter));
outputFileName += "." + extension;
// {filename} {folder} {date} {tmime} {pipeline}
String outputDir = config.getOutputDir();
// Check if the environment variable 'automatedOutputFolder' is set
String outputFolder = System.getenv("automatedOutputFolder");
if (outputFolder == null || outputFolder.isEmpty()) {
// If the environment variable is not set, use the default value
outputFolder = finishedFoldersDir;
}
logger.info("outputDir 0={}", outputDir);
// Replace the placeholders in the outputDir string
outputDir = outputDir.replace("{outputFolder}", outputFolder);
outputDir = outputDir.replace("{folderName}", dir.toString());
logger.info("outputDir 1={}", outputDir);
outputDir = outputDir.replace("\\watchedFolders", "");
outputDir = outputDir.replace("//watchedFolders", "");
outputDir = outputDir.replace("\\\\watchedFolders", "");
outputDir = outputDir.replace("/watchedFolders", "");
Path outputPath;
logger.info("outputDir 2={}", outputDir);
if (Paths.get(outputDir).isAbsolute()) {
// If it's an absolute path, use it directly
outputPath = Paths.get(outputDir);
} else {
// If it's a relative path, make it relative to the current working directory
outputPath = Paths.get(".", outputDir);
}
logger.info("outputPath={}", outputPath);
if (!Files.exists(outputPath)) {
try {
Files.createDirectories(outputPath);
logger.info("Created directory: {}", outputPath);
} catch (IOException e) {
logger.error("Error creating directory: {}", outputPath, e);
return;
}
}
logger.info("outputPath {}", outputPath);
logger.info("outputPath.resolve(outputFileName).toString() {}", outputPath.resolve(outputFileName).toString());
File newFile = new File(outputPath.resolve(outputFileName).toString());
OutputStream os = new FileOutputStream(newFile);
os.write(((ByteArrayResource)resource).getByteArray());
os.close();
logger.info("made {}", outputPath.resolve(outputFileName));
}
// If successful, delete the original files
for (File file : filesToProcess) {
Files.deleteIfExists(processingDir.resolve(file.getName()));
}
} catch (Exception e) {
// If an error occurs, move the original files back
for (File file : filesToProcess) {
Files.move(processingDir.resolve(file.getName()), file.toPath());
}
throw e;
}
}
}
}
List<Resource> processFiles(List<Resource> outputFiles, String jsonString) throws Exception {
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(jsonString);
JsonNode pipelineNode = jsonNode.get("pipeline");
logger.info("Running pipelineNode: {}", pipelineNode);
ByteArrayOutputStream logStream = new ByteArrayOutputStream();
PrintStream logPrintStream = new PrintStream(logStream);
boolean hasErrors = false;
for (JsonNode operationNode : pipelineNode) {
String operation = operationNode.get("operation").asText();
logger.info("Running operation: {}", operation);
JsonNode parametersNode = operationNode.get("parameters");
String inputFileExtension = "";
if (operationNode.has("inputFileType")) {
inputFileExtension = operationNode.get("inputFileType").asText();
} else {
inputFileExtension = ".pdf";
}
List<Resource> newOutputFiles = new ArrayList<>();
boolean hasInputFileType = false;
for (Resource file : outputFiles) {
if (file.getFilename().endsWith(inputFileExtension)) {
hasInputFileType = true;
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("fileInput", file);
Iterator<Map.Entry<String, JsonNode>> parameters = parametersNode.fields();
while (parameters.hasNext()) {
Map.Entry<String, JsonNode> parameter = parameters.next();
body.add(parameter.getKey(), parameter.getValue().asText());
}
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(body, headers);
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8080/" + operation;
ResponseEntity<byte[]> response = restTemplate.exchange(url, HttpMethod.POST, entity, byte[].class);
// If the operation is filter and the response body is null or empty, skip this file
if (operation.startsWith("filter-") && (response.getBody() == null || response.getBody().length == 0)) {
logger.info("Skipping file due to failing {}", operation);
continue;
}
if (!response.getStatusCode().equals(HttpStatus.OK)) {
logPrintStream.println("Error: " + response.getBody());
hasErrors = true;
continue;
}
// Define filename
String filename;
if ("auto-rename".equals(operation)) {
// If the operation is "auto-rename", generate a new filename.
// This is a simple example of generating a filename using current timestamp.
// Modify as per your needs.
filename = "file_" + System.currentTimeMillis();
} else {
// Otherwise, keep the original filename.
filename = file.getFilename();
}
// Check if the response body is a zip file
if (isZip(response.getBody())) {
// Unzip the file and add all the files to the new output files
newOutputFiles.addAll(unzip(response.getBody()));
} else {
Resource outputResource = new ByteArrayResource(response.getBody()) {
@Override
public String getFilename() {
return filename;
}
};
newOutputFiles.add(outputResource);
}
}
if (!hasInputFileType) {
logPrintStream.println(
"No files with extension " + inputFileExtension + " found for operation " + operation);
hasErrors = true;
}
outputFiles = newOutputFiles;
}
logPrintStream.close();
}
if (hasErrors) {
logger.error("Errors occurred during processing. Log: {}", logStream.toString());
}
return outputFiles;
}
List<Resource> handleFiles(File[] files, String jsonString) throws Exception {
if(files == null || files.length == 0) {
logger.info("No files");
return null;
}
logger.info("Handling files: {} files, with JSON string of length: {}", files.length, jsonString.length());
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(jsonString);
JsonNode pipelineNode = jsonNode.get("pipeline");
boolean hasErrors = false;
List<Resource> outputFiles = new ArrayList<>();
for (File file : files) {
Path path = Paths.get(file.getAbsolutePath());
System.out.println("Reading file: " + path); // debug statement
if (Files.exists(path)) {
Resource fileResource = new ByteArrayResource(Files.readAllBytes(path)) {
@Override
public String getFilename() {
return file.getName();
}
};
outputFiles.add(fileResource);
} else {
System.out.println("File not found: " + path); // debug statement
}
}
logger.info("Files successfully loaded. Starting processing...");
return processFiles(outputFiles, jsonString);
}
List<Resource> handleFiles(MultipartFile[] files, String jsonString) throws Exception {
if(files == null || files.length == 0) {
logger.info("No files");
return null;
}
logger.info("Handling files: {} files, with JSON string of length: {}", files.length, jsonString.length());
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(jsonString);
JsonNode pipelineNode = jsonNode.get("pipeline");
boolean hasErrors = false;
List<Resource> outputFiles = new ArrayList<>();
for (MultipartFile file : files) {
Resource fileResource = new ByteArrayResource(file.getBytes()) {
@Override
public String getFilename() {
return file.getOriginalFilename();
}
};
outputFiles.add(fileResource);
}
logger.info("Files successfully loaded. Starting processing...");
return processFiles(outputFiles, jsonString);
}
@PostMapping("/handleData")
public ResponseEntity<byte[]> handleData(@RequestPart("fileInput") MultipartFile[] files,
@RequestParam("json") String jsonString) {
logger.info("Received POST request to /handleData with {} files", files.length);
try {
List<Resource> outputFiles = handleFiles(files, jsonString);
if (outputFiles != null && outputFiles.size() == 1) {
// If there is only one file, return it directly
Resource singleFile = outputFiles.get(0);
InputStream is = singleFile.getInputStream();
byte[] bytes = new byte[(int) singleFile.contentLength()];
is.read(bytes);
is.close();
logger.info("Returning single file response...");
return WebResponseUtils.bytesToWebResponse(bytes, singleFile.getFilename(),
MediaType.APPLICATION_OCTET_STREAM);
} else if (outputFiles == null) {
return null;
}
// Create a ByteArrayOutputStream to hold the zip
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zipOut = new ZipOutputStream(baos);
// Loop through each file and add it to the zip
for (Resource file : outputFiles) {
ZipEntry zipEntry = new ZipEntry(file.getFilename());
zipOut.putNextEntry(zipEntry);
// Read the file into a byte array
InputStream is = file.getInputStream();
byte[] bytes = new byte[(int) file.contentLength()];
is.read(bytes);
// Write the bytes of the file to the zip
zipOut.write(bytes, 0, bytes.length);
zipOut.closeEntry();
is.close();
}
zipOut.close();
logger.info("Returning zipped file response...");
return WebResponseUtils.boasToWebResponse(baos, "output.zip", MediaType.APPLICATION_OCTET_STREAM);
} catch (Exception e) {
logger.error("Error handling data: ", e);
return null;
}
}
private boolean isZip(byte[] data) {
if (data == null || data.length < 4) {
return false;
}
// Check the first four bytes of the data against the standard zip magic number
return data[0] == 0x50 && data[1] == 0x4B && data[2] == 0x03 && data[3] == 0x04;
}
private List<Resource> unzip(byte[] data) throws IOException {
logger.info("Unzipping data of length: {}", data.length);
List<Resource> unzippedFiles = new ArrayList<>();
try (ByteArrayInputStream bais = new ByteArrayInputStream(data);
ZipInputStream zis = new ZipInputStream(bais)) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int count;
while ((count = zis.read(buffer)) != -1) {
baos.write(buffer, 0, count);
}
final String filename = entry.getName();
Resource fileResource = new ByteArrayResource(baos.toByteArray()) {
@Override
public String getFilename() {
return filename;
}
};
// If the unzipped file is a zip file, unzip it
if (isZip(baos.toByteArray())) {
logger.info("File {} is a zip file. Unzipping...", filename);
unzippedFiles.addAll(unzip(baos.toByteArray()));
} else {
unzippedFiles.add(fileResource);
}
}
}
logger.info("Unzipping completed. {} files were unzipped.", unzippedFiles.size());
return unzippedFiles;
}
}

View file

@ -0,0 +1,140 @@
package stirling.software.SPDF.controller.api.security;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.PDPageTree;
import org.apache.pdfbox.pdmodel.common.PDMetadata;
import org.apache.pdfbox.pdmodel.common.PDStream;
import org.apache.pdfbox.pdmodel.interactive.action.*;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.pdmodel.interactive.form.PDNonTerminalField;
import org.apache.pdfbox.pdmodel.interactive.form.PDTerminalField;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import stirling.software.SPDF.utils.WebResponseUtils;
import java.io.IOException;
import java.io.InputStream;
@RestController
public class SanitizeController {
@PostMapping(consumes = "multipart/form-data", value = "/sanitize-pdf")
@Operation(summary = "Sanitize a PDF file",
description = "This endpoint processes a PDF file and removes specific elements based on the provided options. Input:PDF Output:PDF Type:SISO")
public ResponseEntity<byte[]> sanitizePDF(
@RequestPart(required = true, value = "fileInput")
@Parameter(description = "The input PDF file to be sanitized")
MultipartFile inputFile,
@RequestParam(name = "removeJavaScript", required = false, defaultValue = "true")
@Parameter(description = "Remove JavaScript actions from the PDF if set to true")
Boolean removeJavaScript,
@RequestParam(name = "removeEmbeddedFiles", required = false, defaultValue = "true")
@Parameter(description = "Remove embedded files from the PDF if set to true")
Boolean removeEmbeddedFiles,
@RequestParam(name = "removeMetadata", required = false, defaultValue = "true")
@Parameter(description = "Remove metadata from the PDF if set to true")
Boolean removeMetadata,
@RequestParam(name = "removeLinks", required = false, defaultValue = "true")
@Parameter(description = "Remove links from the PDF if set to true")
Boolean removeLinks,
@RequestParam(name = "removeFonts", required = false, defaultValue = "true")
@Parameter(description = "Remove fonts from the PDF if set to true")
Boolean removeFonts) throws IOException {
try (PDDocument document = PDDocument.load(inputFile.getInputStream())) {
if (removeJavaScript) {
sanitizeJavaScript(document);
}
if (removeEmbeddedFiles) {
sanitizeEmbeddedFiles(document);
}
if (removeMetadata) {
sanitizeMetadata(document);
}
if (removeLinks) {
sanitizeLinks(document);
}
if (removeFonts) {
sanitizeFonts(document);
}
return WebResponseUtils.pdfDocToWebResponse(document, inputFile.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_sanitized.pdf");
}
}
private void sanitizeJavaScript(PDDocument document) throws IOException {
for (PDPage page : document.getPages()) {
for (PDAnnotation annotation : page.getAnnotations()) {
if (annotation instanceof PDAnnotationWidget) {
PDAnnotationWidget widget = (PDAnnotationWidget) annotation;
PDAction action = widget.getAction();
if (action instanceof PDActionJavaScript) {
widget.setAction(null);
}
}
}
PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();
if (acroForm != null) {
for (PDField field : acroForm.getFields()) {
if (field.getActions().getF() instanceof PDActionJavaScript) {
field.getActions().setF(null);
}
}
}
}
}
private void sanitizeEmbeddedFiles(PDDocument document) {
PDPageTree allPages = document.getPages();
for (PDPage page : allPages) {
PDResources res = page.getResources();
// Remove embedded files from the PDF
res.getCOSObject().removeItem(COSName.getPDFName("EmbeddedFiles"));
}
}
private void sanitizeMetadata(PDDocument document) {
PDMetadata metadata = document.getDocumentCatalog().getMetadata();
if (metadata != null) {
document.getDocumentCatalog().setMetadata(null);
}
}
private void sanitizeLinks(PDDocument document) throws IOException {
for (PDPage page : document.getPages()) {
for (PDAnnotation annotation : page.getAnnotations()) {
if (annotation instanceof PDAnnotationLink) {
PDAction action = ((PDAnnotationLink) annotation).getAction();
if (action instanceof PDActionLaunch || action instanceof PDActionURI) {
((PDAnnotationLink) annotation).setAction(null);
}
}
}
}
}
private void sanitizeFonts(PDDocument document) {
for (PDPage page : document.getPages()) {
page.getResources().getCOSObject().removeItem(COSName.getPDFName("Font"));
}
}
}

View file

@ -1,12 +1,15 @@
package stirling.software.SPDF.controller.api.security;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import javax.imageio.ImageIO;
import org.apache.commons.io.IOUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
@ -15,6 +18,8 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.util.Matrix;
import org.springframework.core.io.ClassPathResource;
@ -30,57 +35,63 @@ import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.utils.WebResponseUtils;
import io.swagger.v3.oas.annotations.media.Schema;
@RestController
@Tag(name = "Security", description = "Security APIs")
public class WatermarkController {
@PostMapping(consumes = "multipart/form-data", value = "/add-watermark")
@Operation(summary = "Add watermark to a PDF file",
description = "This endpoint adds a watermark to a given PDF file. Users can specify the watermark text, font size, rotation, opacity, width spacer, and height spacer. Input:PDF Output:PDF Type:SISO")
@Operation(summary = "Add watermark to a PDF file", description = "This endpoint adds a watermark to a given PDF file. Users can specify the watermark type (text or image), rotation, opacity, width spacer, and height spacer. Input:PDF Output:PDF Type:SISO")
public ResponseEntity<byte[]> addWatermark(
@RequestPart(required = true, value = "fileInput")
@Parameter(description = "The input PDF file to add a watermark")
MultipartFile pdfFile,
@RequestParam(defaultValue = "roman", name = "alphabet")
@Parameter(description = "The selected alphabet",
@RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file to add a watermark") MultipartFile pdfFile,
@RequestPart(required = true) @Parameter(description = "The watermark type (text or image)") String watermarkType,
@RequestPart(required = false) @Parameter(description = "The watermark text") String watermarkText,
@RequestPart(required = false) @Parameter(description = "The watermark image") MultipartFile watermarkImage,
@RequestParam(defaultValue = "roman", name = "alphabet") @Parameter(description = "The selected alphabet",
schema = @Schema(type = "string",
allowableValues = {"roman","arabic","japanese","korean","chinese"},
defaultValue = "roman"))
String alphabet,
@RequestParam("watermarkText")
@Parameter(description = "The watermark text to add to the PDF file")
String watermarkText,
@RequestParam(defaultValue = "30", name = "fontSize")
@Parameter(description = "The font size of the watermark text", example = "30")
float fontSize,
@RequestParam(defaultValue = "0", name = "rotation")
@Parameter(description = "The rotation of the watermark text in degrees", example = "0")
float rotation,
@RequestParam(defaultValue = "0.5", name = "opacity")
@Parameter(description = "The opacity of the watermark text (0.0 - 1.0)", example = "0.5")
float opacity,
@RequestParam(defaultValue = "50", name = "widthSpacer")
@Parameter(description = "The width spacer between watermark texts", example = "50")
int widthSpacer,
@RequestParam(defaultValue = "50", name = "heightSpacer")
@Parameter(description = "The height spacer between watermark texts", example = "50")
int heightSpacer) throws IOException, Exception {
defaultValue = "roman")) String alphabet,
@RequestParam(defaultValue = "30", name = "fontSize") @Parameter(description = "The font size of the watermark text", example = "30") float fontSize,
@RequestParam(defaultValue = "0", name = "rotation") @Parameter(description = "The rotation of the watermark in degrees", example = "0") float rotation,
@RequestParam(defaultValue = "0.5", name = "opacity") @Parameter(description = "The opacity of the watermark (0.0 - 1.0)", example = "0.5") float opacity,
@RequestParam(defaultValue = "50", name = "widthSpacer") @Parameter(description = "The width spacer between watermark elements", example = "50") int widthSpacer,
@RequestParam(defaultValue = "50", name = "heightSpacer") @Parameter(description = "The height spacer between watermark elements", example = "50") int heightSpacer)
throws IOException, Exception {
// Load the input PDF
PDDocument document = PDDocument.load(pdfFile.getInputStream());
String producer = document.getDocumentInformation().getProducer();
// Create a page in the document
for (PDPage page : document.getPages()) {
// Get the page's content stream
PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true);
PDPageContentStream contentStream = new PDPageContentStream(document, page,
PDPageContentStream.AppendMode.APPEND, true);
// Set transparency
PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();
graphicsState.setNonStrokingAlphaConstant(opacity);
contentStream.setGraphicsStateParameters(graphicsState);
if (watermarkType.equalsIgnoreCase("text")) {
addTextWatermark(contentStream, watermarkText, document, page, rotation, widthSpacer, heightSpacer,
fontSize, alphabet);
} else if (watermarkType.equalsIgnoreCase("image")) {
addImageWatermark(contentStream, watermarkImage, document, page, rotation, widthSpacer, heightSpacer,
fontSize);
}
// Close the content stream
contentStream.close();
}
return WebResponseUtils.pdfDocToWebResponse(document,
pdfFile.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_watermarked.pdf");
}
private void addTextWatermark(PDPageContentStream contentStream, String watermarkText, PDDocument document,
PDPage page, float rotation, int widthSpacer, int heightSpacer, float fontSize, String alphabet) throws IOException {
String resourceDir = "";
PDFont font = PDType1Font.HELVETICA_BOLD;
switch (alphabet) {
@ -114,40 +125,74 @@ public class WatermarkController {
font = PDType0Font.load(document, tempFile);
tempFile.deleteOnExit();
}
contentStream.beginText();
contentStream.setFont(font, fontSize);
contentStream.setNonStrokingColor(Color.LIGHT_GRAY);
// Set size and location of watermark
float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight();
// Set size and location of text watermark
float watermarkWidth = widthSpacer + font.getStringWidth(watermarkText) * fontSize / 1000;
float watermarkHeight = heightSpacer + fontSize;
float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight();
int watermarkRows = (int) (pageHeight / watermarkHeight + 1);
int watermarkCols = (int) (pageWidth / watermarkWidth + 1);
// Add the watermark text
// Add the text watermark
for (int i = 0; i < watermarkRows; i++) {
for (int j = 0; j < watermarkCols; j++) {
if(producer.contains("Google Docs")) {
//This fixes weird unknown google docs y axis rotation/flip issue
//TODO: Long term fix one day
//contentStream.setTextMatrix(1, 0, 0, -1, j * watermarkWidth, pageHeight - i * watermarkHeight);
Matrix matrix = new Matrix(1, 0, 0, -1, j * watermarkWidth, pageHeight - i * watermarkHeight);
contentStream.setTextMatrix(matrix);
} else {
contentStream.setTextMatrix(Matrix.getRotateInstance((float) Math.toRadians(rotation), j * watermarkWidth, i * watermarkHeight));
}
contentStream.showTextWithPositioning(new Object[] { watermarkText });
}
}
contentStream.beginText();
contentStream.setTextMatrix(Matrix.getRotateInstance((float) Math.toRadians(rotation),
j * watermarkWidth, i * watermarkHeight));
contentStream.showText(watermarkText);
contentStream.endText();
// Close the content stream
contentStream.close();
}
return WebResponseUtils.pdfDocToWebResponse(document, pdfFile.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_watermarked.pdf");
}
}
private void addImageWatermark(PDPageContentStream contentStream, MultipartFile watermarkImage, PDDocument document, PDPage page, float rotation,
int widthSpacer, int heightSpacer, float fontSize) throws IOException {
// Load the watermark image
BufferedImage image = ImageIO.read(watermarkImage.getInputStream());
// Compute width based on original aspect ratio
float aspectRatio = (float) image.getWidth() / (float) image.getHeight();
// Desired physical height (in PDF points)
float desiredPhysicalHeight = fontSize ;
// Desired physical width based on the aspect ratio
float desiredPhysicalWidth = desiredPhysicalHeight * aspectRatio;
// Convert the BufferedImage to PDImageXObject
PDImageXObject xobject = LosslessFactory.createFromImage(document, image);
// Calculate the number of rows and columns for watermarks
float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight();
int watermarkRows = (int) ((pageHeight + heightSpacer) / (desiredPhysicalHeight + heightSpacer));
int watermarkCols = (int) ((pageWidth + widthSpacer) / (desiredPhysicalWidth + widthSpacer));
for (int i = 0; i < watermarkRows; i++) {
for (int j = 0; j < watermarkCols; j++) {
float x = j * (desiredPhysicalWidth + widthSpacer);
float y = i * (desiredPhysicalHeight + heightSpacer);
// Save the graphics state
contentStream.saveGraphicsState();
// Create rotation matrix and rotate
contentStream.transform(Matrix.getTranslateInstance(x + desiredPhysicalWidth / 2, y + desiredPhysicalHeight / 2));
contentStream.transform(Matrix.getRotateInstance(Math.toRadians(rotation), 0, 0));
contentStream.transform(Matrix.getTranslateInstance(-desiredPhysicalWidth / 2, -desiredPhysicalHeight / 2));
// Draw the image and restore the graphics state
contentStream.drawImage(xobject, 0, 0, desiredPhysicalWidth, desiredPhysicalHeight);
contentStream.restoreGraphicsState();
}
}
}
}

View file

@ -1,22 +1,77 @@
package stirling.software.SPDF.controller.web;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.tags.Tag;
@Controller
@Tag(name = "General", description = "General APIs")
public class GeneralWebController {
@GetMapping("/pipeline")
@Hidden
public String pipelineForm(Model model) {
model.addAttribute("currentPage", "pipeline");
List<String> pipelineConfigs = new ArrayList<>();
try (Stream<Path> paths = Files.walk(Paths.get("./pipeline/defaultWebUIConfigs/"))) {
List<Path> jsonFiles = paths
.filter(Files::isRegularFile)
.filter(p -> p.toString().endsWith(".json"))
.collect(Collectors.toList());
for (Path jsonFile : jsonFiles) {
String content = Files.readString(jsonFile, StandardCharsets.UTF_8);
pipelineConfigs.add(content);
}
List<Map<String, String>> pipelineConfigsWithNames = new ArrayList<>();
for (String config : pipelineConfigs) {
Map<String, Object> jsonContent = new ObjectMapper().readValue(config, Map.class);
String name = (String) jsonContent.get("name");
Map<String, String> configWithName = new HashMap<>();
configWithName.put("json", config);
configWithName.put("name", name);
pipelineConfigsWithNames.add(configWithName);
}
model.addAttribute("pipelineConfigsWithNames", pipelineConfigsWithNames);
} catch (IOException e) {
e.printStackTrace();
}
model.addAttribute("pipelineConfigs", pipelineConfigs);
return "pipeline";
}
@GetMapping("/merge-pdfs")
@Hidden
public String mergePdfForm(Model model) {
@ -65,7 +120,35 @@ public class GeneralWebController {
@Hidden
public String signForm(Model model) {
model.addAttribute("currentPage", "sign");
model.addAttribute("fonts", getFontNames());
return "sign";
}
private List<String> getFontNames() {
try {
return Files.list(Paths.get("src/main/resources/static/fonts"))
.map(Path::getFileName)
.map(Path::toString)
.filter(name -> name.endsWith(".woff2"))
.map(name -> name.substring(0, name.length() - 6)) // Remove .woff2 extension
.collect(Collectors.toList());
} catch (IOException e) {
throw new RuntimeException("Failed to read font directory", e);
}
}
@GetMapping("/crop")
@Hidden
public String cropForm(Model model) {
model.addAttribute("currentPage", "crop");
return "crop";
}
@GetMapping("/auto-split-pdf")
@Hidden
public String autoSPlitPDFForm(Model model) {
model.addAttribute("currentPage", "auto-split-pdf");
return "auto-split-pdf";
}
}

View file

@ -32,6 +32,13 @@ public class OtherWebController {
return modelAndView;
}
@GetMapping("/add-page-numbers")
@Hidden
public String addPageNumbersForm(Model model) {
model.addAttribute("currentPage", "add-page-numbers");
return "other/add-page-numbers";
}
@GetMapping("/extract-images")
@Hidden
public String extractImagesForm(Model model) {
@ -133,4 +140,13 @@ public class OtherWebController {
return "other/auto-crop";
}
@GetMapping("/auto-rename")
@Hidden
public String autoRenameForm(Model model) {
model.addAttribute("currentPage", "auto-rename");
return "other/auto-rename";
}
}

View file

@ -43,4 +43,11 @@ public class SecurityWebController {
model.addAttribute("currentPage", "cert-sign");
return "security/cert-sign";
}
@GetMapping("/sanitize-pdf")
@Hidden
public String sanitizeForm(Model model) {
model.addAttribute("currentPage", "sanitize-pdf");
return "security/sanitize-pdf";
}
}

View file

@ -22,4 +22,11 @@ public class PipelineOperation {
public void setParameters(Map<String, Object> parameters) {
this.parameters = parameters;
}
@Override
public String toString() {
return "PipelineOperation [operation=" + operation + ", parameters=" + parameters + "]";
}
}

View file

@ -1,5 +1,9 @@
package stirling.software.SPDF.utils;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
@ -35,8 +39,14 @@ public class GeneralUtils {
// loop through the page order array
for (String element : pageOrderArr) {
// check if the element contains a range of pages
if (element.matches("\\d*n\\+?-?\\d*|\\d*\\+?n")) {
if (element.equalsIgnoreCase("all")) {
for (int i = 0; i < totalPages; i++) {
newPageOrder.add(i);
}
// As all pages are already added, no need to check further
break;
}
else if (element.matches("\\d*n\\+?-?\\d*|\\d*\\+?n")) {
// Handle page order as a function
int coefficient = 0;
int constant = 0;
@ -88,4 +98,16 @@ public class GeneralUtils {
return newPageOrder;
}
public static boolean createDir(String path) {
Path folder = Paths.get(path);
if (!Files.exists(folder)) {
try {
Files.createDirectories(folder);
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
return true;
}
}

View file

@ -44,7 +44,7 @@ public class PdfUtils {
public static PDRectangle textToPageSize(String size) {
switch (size) {
switch (size.toUpperCase()) {
case "A0":
return PDRectangle.A0;
case "A1":
@ -68,44 +68,38 @@ public class PdfUtils {
}
}
public boolean hasImageInFile(PDDocument pdfDocument, String text, String pagesToCheck) throws IOException {
PDFTextStripper textStripper = new PDFTextStripper();
String pdfText = "";
if(pagesToCheck == null || pagesToCheck.equals("all")) {
pdfText = textStripper.getText(pdfDocument);
} else {
// remove whitespaces
pagesToCheck = pagesToCheck.replaceAll("\\s+", "");
String[] splitPoints = pagesToCheck.split(",");
for (String splitPoint : splitPoints) {
if (splitPoint.contains("-")) {
// Handle page ranges
String[] range = splitPoint.split("-");
int startPage = Integer.parseInt(range[0]);
int endPage = Integer.parseInt(range[1]);
for (int i = startPage; i <= endPage; i++) {
textStripper.setStartPage(i);
textStripper.setEndPage(i);
pdfText += textStripper.getText(pdfDocument);
}
} else {
// Handle individual page
int page = Integer.parseInt(splitPoint);
textStripper.setStartPage(page);
textStripper.setEndPage(page);
pdfText += textStripper.getText(pdfDocument);
}
public static boolean hasImages(PDDocument document, String pagesToCheck) throws IOException {
String[] pageOrderArr = pagesToCheck.split(",");
List<Integer> pageList = GeneralUtils.parsePageList(pageOrderArr, document.getNumberOfPages());
for (int pageNumber : pageList) {
PDPage page = document.getPage(pageNumber);
if (hasImagesOnPage(page)) {
return true;
}
}
pdfDocument.close();
return pdfText.contains(text);
return false;
}
public static boolean hasText(PDDocument document, String pageNumbersToCheck, String phrase) throws IOException {
String[] pageOrderArr = pageNumbersToCheck.split(",");
List<Integer> pageList = GeneralUtils.parsePageList(pageOrderArr, document.getNumberOfPages());
for (int pageNumber : pageList) {
PDPage page = document.getPage(pageNumber);
if (hasTextOnPage(page, phrase)) {
return true;
}
}
return false;
}
public static boolean hasImagesOnPage(PDPage page) throws IOException {
ImageFinder imageFinder = new ImageFinder(page);
imageFinder.processPage(page);
@ -113,10 +107,15 @@ public class PdfUtils {
}
public static boolean hasText(PDDocument document, String phrase) throws IOException {
PDFTextStripper pdfStripper = new PDFTextStripper();
String text = pdfStripper.getText(document);
return text.contains(phrase);
public static boolean hasTextOnPage(PDPage page, String phrase) throws IOException {
PDFTextStripper textStripper = new PDFTextStripper();
PDDocument tempDoc = new PDDocument();
tempDoc.addPage(page);
String pageText = textStripper.getText(tempDoc);
tempDoc.close();
return pageText.contains(phrase);
}

View file

@ -10,6 +10,7 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;
public class WebResponseUtils {
@ -21,6 +22,16 @@ public class WebResponseUtils {
return WebResponseUtils.bytesToWebResponse(baos.toByteArray(), docName, mediaType);
}
public static ResponseEntity<byte[]> multiPartFileToWebResponse(MultipartFile file) throws IOException {
String fileName = file.getOriginalFilename();
MediaType mediaType = MediaType.parseMediaType(file.getContentType());
byte[] bytes = file.getBytes();
return bytesToWebResponse(bytes, fileName, mediaType);
}
public static ResponseEntity<byte[]> bytesToWebResponse(byte[] bytes, String docName, MediaType mediaType) throws IOException {
// Return the PDF as a response

View file

@ -15,7 +15,7 @@ server.error.whitelabel.enabled=false
server.error.include-stacktrace=always
server.error.include-exception=true
server.error.include-message=always
\
server.servlet.session.tracking-modes=cookie
server.servlet.context-path=${APP_ROOT_PATH:/}
@ -26,3 +26,7 @@ spring.thymeleaf.encoding=UTF-8
server.connection-timeout=${CONNECTION_TIMEOUT:5m}
spring.mvc.async.request-timeout=${ASYNC_CONNECTION_TIMEOUT:300000}
spring.resources.static-locations=file:customFiles/static/
#spring.thymeleaf.prefix=file:/customFiles/templates/,classpath:/templates/
#spring.thymeleaf.cache=false

View file

@ -1,11 +1,7 @@
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#
# Translated by Google Translate #
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#
###########
# Generic #
###########
# the direction that the language is written (ltr=left to right, rtl=right to left)
# the direction that the language is written (ltr = left to right, rtl = right to left)
language.direction=rtl
pdfPrompt=اختر PDF
@ -21,26 +17,66 @@ false=\u062E\u0637\u0623
unknown=\u063A\u064A\u0631 \u0645\u0639\u0631\u0648\u0641
save=\u062D\u0641\u0638
close=\u0625\u063A\u0644\u0627\u0642
filesSelected = الملفات المحددة
noFavourites = لم تتم إضافة أي مفضلات
bored = الانتظار بالملل؟
filesSelected=الملفات المحددة
noFavourites=لم تتم إضافة أي مفضلات
bored=الانتظار بالملل؟
alphabet=\u0627\u0644\u0623\u0628\u062C\u062F\u064A\u0629
#############
# HOME-PAGE #
#############
home.desc=متجرك الشامل المستضاف محليًا لجميع احتياجات PDF الخاصة بك.
downloadPdf=تنزيل PDF
text=نص
font=الخط
selectFillter=- حدد -
pageNum=رقم الصفحة
##########################
### TODO: Translate ###
##########################
sizes.small=Small
sizes.medium=Medium
sizes.large=Large
sizes.x-large=X-Large
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
#############
# NAVBAR #
#############
navbar.convert=تحويل
navbar.security=الأمان
navbar.other=أخرى
navbar.darkmode=الوضع الداكن
navbar.pageOps=عمليات الصفحة
navbar.settings=\u0625\u0639\u062F\u0627\u062F\u0627\u062A
#############
# SETTINGS #
#############
settings.title=\u0627\u0644\u0625\u0639\u062F\u0627\u062F\u0627\u062A
settings.update=\u0627\u0644\u062A\u062D\u062F\u064A\u062B \u0645\u062A\u0627\u062D
settings.appVersion=\u0625\u0635\u062F\u0627\u0631 \u0627\u0644\u062A\u0637\u0628\u064A\u0642:
settings.downloadOption.title=\u062A\u062D\u062F\u064A\u062F \u062E\u064A\u0627\u0631 \u0627\u0644\u062A\u0646\u0632\u064A\u0644 (\u0644\u0644\u062A\u0646\u0632\u064A\u0644\u0627\u062A \u0630\u0627\u062A \u0627\u0644\u0645\u0644\u0641 \u0627\u0644\u0648\u0627\u062D\u062F \u063A\u064A\u0631 \u0627\u0644\u0645\u0636\u063A\u0648\u0637):
settings.downloadOption.1=\u0641\u062A\u062D \u0641\u064A \u0646\u0641\u0633 \u0627\u0644\u0646\u0627\u0641\u0630\u0629
settings.downloadOption.2=\u0641\u062A\u062D \u0641\u064A \u0646\u0627\u0641\u0630\u0629 \u062C\u062F\u064A\u062F\u0629
settings.downloadOption.3=\u062A\u0646\u0632\u064A\u0644 \u0627\u0644\u0645\u0644\u0641
settings.zipThreshold=\u0645\u0644\u0641\u0627\u062A \u0645\u0636\u063A\u0648\u0637\u0629 \u0639\u0646\u062F \u062A\u062C\u0627\u0648\u0632 \u0639\u062F\u062F \u0627\u0644\u0645\u0644\u0641\u0627\u062A \u0627\u0644\u062A\u064A \u062A\u0645 \u062A\u0646\u0632\u064A\u0644\u0647\u0627
#############
# HOME-PAGE #
#############
home.desc=متجرك الشامل المستضاف محليًا لجميع احتياجات PDF الخاصة بك.
home.multiTool.title=أداة متعددة PDF
home.multiTool.desc=دمج الصفحات وتدويرها وإعادة ترتيبها وإزالتها
##########################
### TODO: Translate ###
##########################
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
home.merge.title=دمج ملفات
home.merge.desc=دمج ملفات PDF متعددة في ملف واحد بسهولة.
##########################
### TODO: Translate ###
##########################
merge.tags=merge,Page operations,Back end,server side
home.split.title=انقسام ملفات
home.split.desc=تقسيم ملفات PDF إلى مستندات متعددة
@ -63,9 +99,6 @@ home.addImage.desc=إضافة صورة إلى موقع معين في PDF (الع
home.watermark.title=إضافة علامة مائية
home.watermark.desc=أضف علامة مائية مخصصة إلى مستند PDF الخاص بك.
home.remove-watermark.title=\u0625\u0632\u0627\u0644\u0629 \u0627\u0644\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0645\u0627\u0626\u064A\u0629
home.remove-watermark.desc=\u0625\u0632\u0627\u0644\u0629 \u0627\u0644\u0639\u0644\u0627\u0645\u0627\u062A \u0627\u0644\u0645\u0627\u0626\u064A\u0629 \u0645\u0646 \u0645\u0633\u062A\u0646\u062F PDF \u0627\u0644\u062E\u0627\u0635 \u0628\u0643.
home.permissions.title=تغيير الأذونات
home.permissions.desc=قم بتغيير أذونات مستند PDF الخاص بك
@ -84,7 +117,6 @@ home.compressPdfs.desc=ضغط ملفات PDF لتقليل حجم الملف.
home.changeMetadata.title=\u062A\u063A\u064A\u064A\u0631 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0648\u0635\u0641\u064A\u0629
home.changeMetadata.desc=\u062A\u063A\u064A\u064A\u0631 / \u0625\u0632\u0627\u0644\u0629 / \u0625\u0636\u0627\u0641\u0629 \u0628\u064A\u0627\u0646\u0627\u062A \u0623\u0648\u0644\u064A\u0629 \u0645\u0646 \u0645\u0633\u062A\u0646\u062F PDF
home.fileToPDF.title=\u062A\u062D\u0648\u064A\u0644 \u0627\u0644\u0645\u0644\u0641 \u0625\u0644\u0649 PDF
home.fileToPDF.desc=\u062A\u062D\u0648\u064A\u0644 \u0623\u064A \u0645\u0644\u0641 \u062A\u0642\u0631\u064A\u0628\u0627 \u0625\u0644\u0649 PDF (DOCX \u0648PNG \u0648XLS \u0648PPT \u0648TXT \u0648\u0627\u0644\u0645\u0632\u064A\u062F)
@ -97,7 +129,6 @@ home.extractImages.desc=\u064A\u0633\u062A\u062E\u0631\u062C \u062C\u0645\u064A\
home.pdfToPDFA.title=\u062A\u062D\u0648\u064A\u0644 \u0645\u0644\u0641\u0627\u062A PDF \u0625\u0644\u0649 PDF / A
home.pdfToPDFA.desc=\u062A\u062D\u0648\u064A\u0644 PDF \u0625\u0644\u0649 PDF / A \u0644\u0644\u062A\u062E\u0632\u064A\u0646 \u0637\u0648\u064A\u0644 \u0627\u0644\u0645\u062F\u0649
home.PDFToWord.title=تحويل PDF إلى Word
home.PDFToWord.desc=تحويل PDF إلى تنسيقات Word (DOC و DOCX و ODT)
@ -113,98 +144,202 @@ home.PDFToHTML.desc=تحويل PDF إلى تنسيق HTML
home.PDFToXML.title=تحويل PDF إلى XML
home.PDFToXML.desc=تحويل PDF إلى تنسيق XML
home.ScannerImageSplit.title=كشف / انقسام الصور الممسوحة ضوئيًا
home.ScannerImageSplit.desc=تقسيم عدة صور من داخل صورة / ملف PDF
home.sign.title = تسجيل الدخول
home.sign.desc = إضافة التوقيع إلى PDF عن طريق الرسم أو النص أو الصورة
home.sign.title=تسجيل الدخول
home.sign.desc=إضافة التوقيع إلى PDF عن طريق الرسم أو النص أو الصورة
home.flatten.title = تسطيح
home.flatten.desc = قم بإزالة كافة العناصر والنماذج التفاعلية من ملف PDF
home.flatten.title=تسطيح
home.flatten.desc=قم بإزالة كافة العناصر والنماذج التفاعلية من ملف PDF
home.repair.title = إصلاح
home.repair.desc = يحاول إصلاح ملف PDF تالف / معطل
home.repair.title=إصلاح
home.repair.desc=يحاول إصلاح ملف PDF تالف / معطل
home.removeBlanks.title = إزالة الصفحات الفارغة
home.removeBlanks.desc = يكتشف ويزيل الصفحات الفارغة من المستند
home.removeBlanks.title=إزالة الصفحات الفارغة
home.removeBlanks.desc=يكتشف ويزيل الصفحات الفارغة من المستند
home.compare.title=قارن
home.compare.desc=يقارن ويظهر الاختلافات بين 2 من مستندات PDF
home.certSign.title=Sign with Certificate
home.certSign.desc=Signs a PDF with a Certificate/Key (PEM/P12)
home.compare.title = قارن
home.compare.desc = يقارن ويظهر الاختلافات بين 2 من مستندات PDF
home.pageLayout.title=Multi-Page Layout
home.pageLayout.desc=Merge multiple pages of a PDF document into a single page
home.scalePages.title=Adjust page size/scale
home.scalePages.desc=Change the size/scale of page and/or its contents.
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
##########################
### TODO: Translate ###
##########################
home.pipeline.title=Pipeline (Advanced)
home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts
downloadPdf = تنزيل PDF
text=نص
font=الخط
selectFillter = - حدد -
pageNum = رقم الصفحة
home.add-page-numbers.title=Add Page Numbers
home.add-page-numbers.desc=Add Page numbers throughout a document in a set location
home.auto-rename.title=Auto Rename PDF File
home.auto-rename.desc=Auto renames a PDF file based on its detected header
home.adjust-contrast.title=Adjust Colors/Contrast
home.adjust-contrast.desc=Adjust Contrast, Saturation and Brightness of a PDF
home.crop.title=Crop PDF
home.crop.desc=Crop a PDF to reduce its size (maintains text!)
home.autoSplitPDF.title=Auto Split Pages
home.autoSplitPDF.desc=Auto Split Scanned PDF with physical scanned page splitter QR Code
home.sanitizePdf.title=Sanitize
home.sanitizePdf.desc=Remove scripts and other elements from PDF files
###########################
# #
# WEB PAGES #
# #
###########################
#sanitizePDF
sanitizePDF.title=Sanitize PDF
sanitizePDF.header=Sanitize a PDF file
sanitizePDF.selectText.1=Remove JavaScript actions
sanitizePDF.selectText.2=Remove embedded files
sanitizePDF.selectText.3=Remove metadata
sanitizePDF.selectText.4=Remove links
sanitizePDF.selectText.5=Remove fonts
sanitizePDF.submit=Sanitize PDF
#addPageNumbers
addPageNumbers.title=Add Page Numbers
addPageNumbers.header=Add Page Numbers
addPageNumbers.selectText.1=Select PDF file:
addPageNumbers.selectText.2=Margin Size
addPageNumbers.selectText.3=Position
addPageNumbers.selectText.4=Starting Number
addPageNumbers.selectText.5=Pages to Number
addPageNumbers.selectText.6=Custom Text
addPageNumbers.submit=Add Page Numbers
#auto-rename
auto-rename.title=Auto Rename
auto-rename.header=Auto Rename PDF
auto-rename.submit=Auto Rename
#adjustContrast
adjustContrast.title=Adjust Contrast
adjustContrast.header=Adjust Contrast
adjustContrast.contrast=Contrast:
adjustContrast.brightness=Brightness:
adjustContrast.saturation=Saturation:
adjustContrast.download=Download
#crop
crop.title=Crop
crop.header=Crop Image
crop.submit=Submit
#autoSplitPDF
autoSplitPDF.title=Auto Split PDF
autoSplitPDF.header=Auto Split PDF
autoSplitPDF.description=Print, Insert, Scan, upload, and let us auto-separate your documents. No manual work sorting needed.
autoSplitPDF.selectText.1=Print out some divider sheets from below (Black and white is fine).
autoSplitPDF.selectText.2=Scan all your documents at once by inserting the divider sheet between them.
autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirling PDF handle the rest.
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
autoSplitPDF.submit=Submit
#pipeline
pipeline.title=Pipeline
#pageLayout
pageLayout.title=Multi Page Layout
pageLayout.header=Multi Page Layout
pageLayout.pagesPerSheet=Pages per sheet:
pageLayout.submit=Submit
#scalePages
scalePages.title=Adjust page-scale
scalePages.header=Adjust page-scale
scalePages.pageSize=Size of a page of the document.
scalePages.scaleFactor=Zoom level (crop) of a page.
scalePages.submit=Submit
certSign.title = توقيع الشهادة
certSign.header = قم بتوقيع ملف PDF بشهادتك (العمل قيد التقدم)
certSign.selectPDF = حدد ملف PDF للتوقيع:
certSign.selectKey = حدد ملف المفتاح الخاص (تنسيق PKCS # 8 ، يمكن أن يكون .pem أو .der):
certSign.selectCert = حدد ملف الشهادة الخاص بك (تنسيق X.509 ، يمكن أن يكون .pem أو .der):
certSign.selectP12 = حدد ملف تخزين المفاتيح PKCS # 12 (.p12 أو .pfx) (اختياري ، إذا تم توفيره ، يجب أن يحتوي على مفتاحك الخاص وشهادتك):
certSign.certType = نوع الشهادة
certSign.password = أدخل ملف تخزين المفاتيح أو كلمة المرور الخاصة (إن وجدت):
certSign.showSig = إظهار التوقيع
certSign.reason = السبب
certSign.location = الموقع
certSign.name = الاسم
certSign.submit = تسجيل PDF
removeBlanks.title = إزالة الفراغات
removeBlanks.header = إزالة الصفحات الفارغة
removeBlanks.threshold = العتبة:
removeBlanks.thresholdDesc = الحد الفاصل لتحديد مدى بياض البكسل الأبيض
removeBlanks.whitePercent = نسبة الأبيض (٪):
removeBlanks.whitePercentDesc = النسبة المئوية للصفحة التي يجب أن تكون بيضاء لتتم إزالتها
removeBlanks.submit = إزالة الفراغات
#certSign
certSign.title=توقيع الشهادة
certSign.header=قم بتوقيع ملف PDF بشهادتك (العمل قيد التقدم)
certSign.selectPDF=حدد ملف PDF للتوقيع:
certSign.selectKey=حدد ملف المفتاح الخاص (تنسيق PKCS # 8 ، يمكن أن يكون .pem أو .der):
certSign.selectCert=حدد ملف الشهادة الخاص بك (تنسيق X.509 ، يمكن أن يكون .pem أو .der):
certSign.selectP12=حدد ملف تخزين المفاتيح PKCS # 12 (.p12 أو .pfx) (اختياري ، إذا تم توفيره ، يجب أن يحتوي على مفتاحك الخاص وشهادتك):
certSign.certType=نوع الشهادة
certSign.password=أدخل ملف تخزين المفاتيح أو كلمة المرور الخاصة (إن وجدت):
certSign.showSig=إظهار التوقيع
certSign.reason=السبب
certSign.location=الموقع
certSign.name=الاسم
certSign.submit=تسجيل PDF
#removeBlanks
removeBlanks.title=إزالة الفراغات
removeBlanks.header=إزالة الصفحات الفارغة
removeBlanks.threshold=العتبة:
removeBlanks.thresholdDesc=الحد الفاصل لتحديد مدى بياض البكسل الأبيض
removeBlanks.whitePercent=نسبة الأبيض (٪):
removeBlanks.whitePercentDesc=النسبة المئوية للصفحة التي يجب أن تكون بيضاء لتتم إزالتها
removeBlanks.submit=إزالة الفراغات
#compare
compare.title=يقارن
compare.header=قارن ملفات PDF
compare.document.1=المستند 1
compare.document.2=المستند 2
compare.submit=يقارن
sign.title = تسجيل الدخول
sign.header = توقيع ملفات PDF
sign.upload = تحميل الصورة
sign.draw = رسم التوقيع
Sign.text = إدخال النص
#sign
sign.title=تسجيل الدخول
sign.header=توقيع ملفات PDF
sign.upload=تحميل الصورة
sign.draw=رسم التوقيع
##########################
### TODO: Translate ###
##########################
sign.text=Text Input
sign.clear=واضح
sign.add = إضافة
sign.add=إضافة
repair.title = إصلاح
repair.header = إصلاح ملفات PDF
repair.submit = الإصلاح
flatten.title = تسطيح
flatten.header = تسوية ملفات PDF
flatten.submit = تسطيح
#repair
repair.title=إصلاح
repair.header=إصلاح ملفات PDF
repair.submit=الإصلاح
#flatten
flatten.title=تسطيح
flatten.header=تسوية ملفات PDF
flatten.submit=تسطيح
#ScannerImageSplit
ScannerImageSplit.selectText.1=عتبة الزاوية:
ScannerImageSplit.selectText.2=تعيين الحد الأدنى للزاوية المطلقة المطلوبة لتدوير الصورة (افتراضي: 10).
ScannerImageSplit.selectText.3=التسامح:
@ -217,16 +352,6 @@ ScannerImageSplit.selectText.9=حجم الحدود:
ScannerImageSplit.selectText.10=يضبط حجم الحدود المضافة والمزالة لمنع الحدود البيضاء في الإخراج (الافتراضي: 1).
navbar.settings=\u0625\u0639\u062F\u0627\u062F\u0627\u062A
settings.title=\u0627\u0644\u0625\u0639\u062F\u0627\u062F\u0627\u062A
settings.update=\u0627\u0644\u062A\u062D\u062F\u064A\u062B \u0645\u062A\u0627\u062D
settings.appVersion=\u0625\u0635\u062F\u0627\u0631 \u0627\u0644\u062A\u0637\u0628\u064A\u0642:
settings.downloadOption.title=\u062A\u062D\u062F\u064A\u062F \u062E\u064A\u0627\u0631 \u0627\u0644\u062A\u0646\u0632\u064A\u0644 (\u0644\u0644\u062A\u0646\u0632\u064A\u0644\u0627\u062A \u0630\u0627\u062A \u0627\u0644\u0645\u0644\u0641 \u0627\u0644\u0648\u0627\u062D\u062F \u063A\u064A\u0631 \u0627\u0644\u0645\u0636\u063A\u0648\u0637):
settings.downloadOption.1=\u0641\u062A\u062D \u0641\u064A \u0646\u0641\u0633 \u0627\u0644\u0646\u0627\u0641\u0630\u0629
settings.downloadOption.2=\u0641\u062A\u062D \u0641\u064A \u0646\u0627\u0641\u0630\u0629 \u062C\u062F\u064A\u062F\u0629
settings.downloadOption.3=\u062A\u0646\u0632\u064A\u0644 \u0627\u0644\u0645\u0644\u0641
settings.zipThreshold=\u0645\u0644\u0641\u0627\u062A \u0645\u0636\u063A\u0648\u0637\u0629 \u0639\u0646\u062F \u062A\u062C\u0627\u0648\u0632 \u0639\u062F\u062F \u0627\u0644\u0645\u0644\u0641\u0627\u062A \u0627\u0644\u062A\u064A \u062A\u0645 \u062A\u0646\u0632\u064A\u0644\u0647\u0627
#OCR
ocr.title=\u0627\u0644\u062A\u0639\u0631\u0641 \u0627\u0644\u0636\u0648\u0626\u064A \u0639\u0644\u0649 \u0627\u0644\u062D\u0631\u0648\u0641 / \u062A\u0646\u0638\u064A\u0641 \u0627\u0644\u0645\u0633\u062D \u0627\u0644\u0636\u0648\u0626\u064A
ocr.header=\u0645\u0633\u062D \u0627\u0644\u0645\u0633\u062D \u0627\u0644\u0636\u0648\u0626\u064A / \u0627\u0644\u062A\u0639\u0631\u0641 \u0627\u0644\u0636\u0648\u0626\u064A \u0639\u0644\u0649 \u0627\u0644\u062D\u0631\u0648\u0641 (\u0627\u0644\u062A\u0639\u0631\u0641 \u0627\u0644\u0636\u0648\u0626\u064A \u0639\u0644\u0649 \u0627\u0644\u062D\u0631\u0648\u0641)
@ -240,19 +365,21 @@ ocr.selectText.7=\u0641\u0631\u0636 \u0627\u0644\u062A\u0639\u0631\u0641 \u0627\
ocr.selectText.8=\u0639\u0627\u062F\u064A (\u062E\u0637\u0623 \u0625\u0630\u0627 \u0643\u0627\u0646 PDF \u064A\u062D\u062A\u0648\u064A \u0639\u0644\u0649 \u0646\u0635)
ocr.selectText.9=\u0625\u0639\u062F\u0627\u062F\u0627\u062A \u0625\u0636\u0627\u0641\u064A\u0629
ocr.selectText.10=\u0648\u0636\u0639 \u0627\u0644\u062A\u0639\u0631\u0641 \u0627\u0644\u0636\u0648\u0626\u064A \u0639\u0644\u0649 \u0627\u0644\u062D\u0631\u0648\u0641
ocr.selectText.11 = إزالة الصور بعد التعرف الضوئي على الحروف (يزيل كل الصور ، يكون مفيدًا فقط إذا كان جزءًا من خطوة التحويل)
ocr.selectText.12 = نوع العرض (متقدم)
ocr.selectText.11=إزالة الصور بعد التعرف الضوئي على الحروف (يزيل كل الصور ، يكون مفيدًا فقط إذا كان جزءًا من خطوة التحويل)
ocr.selectText.12=نوع العرض (متقدم)
ocr.help=\u064A\u0631\u062C\u0649 \u0642\u0631\u0627\u0621\u0629 \u0647\u0630\u0647 \u0627\u0644\u0648\u062B\u0627\u0626\u0642 \u062D\u0648\u0644 \u0643\u064A\u0641\u064A\u0629 \u0627\u0633\u062A\u062E\u062F\u0627\u0645 \u0647\u0630\u0627 \u0644\u0644\u063A\u0627\u062A \u0623\u062E\u0631\u0649 \u0648 / \u0623\u0648 \u0627\u0644\u0627\u0633\u062A\u062E\u062F\u0627\u0645 \u0644\u064A\u0633 \u0641\u064A \u0639\u0627\u0645\u0644 \u0627\u0644\u0625\u0631\u0633\u0627\u0621
ocr.credit=\u062A\u0633\u062A\u062E\u062F\u0645 \u0647\u0630\u0647 \u0627\u0644\u062E\u062F\u0645\u0629 OCRmyPDF \u0648 Tesseract \u0644 OCR.
ocr.submit=\u0645\u0639\u0627\u0644\u062C\u0629 PDF \u0628\u0627\u0633\u062A\u062E\u062F\u0627\u0645 OCR
#extractImages
extractImages.title=\u0627\u0633\u062A\u062E\u0631\u0627\u062C \u0627\u0644\u0635\u0648\u0631
extractImages.header=\u0627\u0633\u062A\u062E\u0631\u0627\u062C \u0627\u0644\u0635\u0648\u0631
extractImages.selectText=\u062D\u062F\u062F \u062A\u0646\u0633\u064A\u0642 \u0627\u0644\u0635\u0648\u0631\u0629 \u0644\u062A\u062D\u0648\u064A\u0644 \u0627\u0644\u0635\u0648\u0631 \u0627\u0644\u0645\u0633\u062A\u062E\u0631\u062C\u0629 \u0625\u0644\u0649
extractImages.submit=\u0627\u0633\u062A\u062E\u0631\u0627\u062C
#File \u0625\u0644\u0649 PDF
#File to PDF
fileToPDF.title=\u0645\u0644\u0641 \u0625\u0644\u0649 PDF
fileToPDF.header=\u062A\u062D\u0648\u064A\u0644 \u0623\u064A \u0645\u0644\u0641 \u0625\u0644\u0649 PDF
fileToPDF.credit=\u062A\u0633\u062A\u062E\u062F\u0645 \u0647\u0630\u0647 \u0627\u0644\u062E\u062F\u0645\u0629 \u0644\u064A\u0628\u0631 \u0623\u0648\u0641\u064A\u0633 \u0648\u0623\u0648\u0646\u0648\u0643\u0648\u0646\u0641 \u0644\u062A\u062D\u0648\u064A\u0644 \u0627\u0644\u0645\u0644\u0641\u0627\u062A.
@ -260,6 +387,18 @@ fileToPDF.supportedFileTypes=\u064A\u062C\u0628 \u0623\u0646 \u062A\u062A\u0636\
fileToPDF.submit=\u062A\u062D\u0648\u064A\u0644 \u0625\u0644\u0649 PDF
#compress
compress.title=ضغط
compress.header=ضغط ملف PDF
compress.credit=تستخدم هذه الخدمة OCRmyPDF لضغط / تحسين PDF.
compress.selectText.1=الوضع اليدوي - من 1 إلى 4
compress.selectText.2=مستوى التحسين:
compress.selectText.3=4 (رهيب للصور النصية)
compress.selectText.4=الوضع التلقائي - يضبط الجودة تلقائيًا للحصول على ملف PDF بالحجم المحدد
compress.selectText.5=حجم PDF المتوقع (على سبيل المثال 25 ميجا بايت ، 10.8 ميجا بايت ، 25 كيلو بايت)
compress.submit=ضغطضغط
#Add image
addImage.title=إضافة صورة
addImage.header=إضافة صورة إلى PDF
@ -267,38 +406,31 @@ addImage.everyPage=كل صفحة؟
addImage.upload=إضافة صورة
addImage.submit=إضافة صورة
#compress
compress.title = ضغط
compress.header = ضغط ملف PDF
compress.credit = تستخدم هذه الخدمة OCRmyPDF لضغط / تحسين PDF.
compress.selectText.1 = الوضع اليدوي - من 1 إلى 4
compress.selectText.2 = مستوى التحسين:
compress.selectText.3 = 4 (رهيب للصور النصية)
compress.selectText.4 = الوضع التلقائي - يضبط الجودة تلقائيًا للحصول على ملف PDF بالحجم المحدد
compress.selectText.5 = حجم PDF المتوقع (على سبيل المثال 25 ميجا بايت ، 10.8 ميجا بايت ، 25 كيلو بايت)
compress.submit = ضغطضغط
#merge
merge.title=دمج
merge.header=دمج ملفات PDF متعددة (2+)
merge.submit=دمج
#pdfOrganiser
pdfOrganiser.title=منظم الصفحة
pdfOrganiser.header=منظم صفحات PDF
pdfOrganiser.submit=إعادة ترتيب الصفحات
#multiTool
multiTool.title=أداة متعددة PDF
multiTool.header=أداة متعددة PDF
#pageRemover
pageRemover.title=مزيل الصفحة
pageRemover.header=مزيل صفحة PDF
pageRemover.pagesToDelete=الصفحات المراد حذفها (أدخل قائمة بأرقام الصفحات مفصولة بفواصل):
pageRemover.submit=حذف الصفحات
#rotate
rotate.title=تدوير PDF
rotate.header=تدوير PDF
@ -306,8 +438,6 @@ rotate.selectAngle=حدد زاوية الدوران (بمضاعفات 90 درج
rotate.submit=استدارة
#merge
split.title=انقسام PDF
split.header=تقسيم PDF
@ -333,6 +463,7 @@ imageToPDF.selectText.3=\u0627\u0644\u0645\u0646\u0637\u0642 \u0627\u0644\u0645\
imageToPDF.selectText.4=\u062F\u0645\u062C \u0641\u064A \u0645\u0644\u0641 PDF \u0648\u0627\u062D\u062F
imageToPDF.selectText.5=\u062A\u062D\u0648\u064A\u0644 \u0625\u0644\u0649 \u0645\u0644\u0641\u0627\u062A PDF \u0645\u0646\u0641\u0635\u0644\u0629
#pdfToImage
pdfToImage.title=تحويل PDF إلى صورة
pdfToImage.header=تحويل PDF إلى صورة
@ -346,6 +477,7 @@ pdfToImage.grey=\u062A\u062F\u0631\u062C \u0627\u0644\u0631\u0645\u0627\u062F\u0
pdfToImage.blackwhite=\u0623\u0628\u064A\u0636 \u0648\u0623\u0633\u0648\u062F (\u0642\u062F \u064A\u0641\u0642\u062F \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A!)
pdfToImage.submit=تحول
#addPassword
addPassword.title=إضافة كلمة مرور
addPassword.header=إضافة كلمة مرور (تشفير)
@ -367,6 +499,7 @@ addPassword.selectText.15=Restricts what can be done with the document once it i
addPassword.selectText.16=Restricts the opening of the document itself
addPassword.submit=تشفير
#watermark
watermark.title=إضافة علامة مائية
watermark.header=إضافة علامة مائية
@ -379,6 +512,7 @@ watermark.selectText.6=heightSpacer (مسافة بين كل علامة مائي
watermark.selectText.7=\u0627\u0644\u062A\u0639\u062A\u064A\u0645 (0\u066A - 100\u066A):
watermark.submit=إضافة علامة مائية
#remove-watermark
remove-watermark.title=\u0625\u0632\u0627\u0644\u0629 \u0627\u0644\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0645\u0627\u0626\u064A\u0629
remove-watermark.header=\u0625\u0632\u0627\u0644\u0629 \u0627\u0644\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0645\u0627\u0626\u064A\u0629
@ -386,6 +520,7 @@ remove-watermark.selectText.1=\u062D\u062F\u062F PDF \u0644\u0625\u0632\u0627\u0
remove-watermark.selectText.2=\u0646\u0635 \u0627\u0644\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0645\u0627\u0626\u064A\u0629:
remove-watermark.submit=\u0625\u0632\u0627\u0644\u0629 \u0627\u0644\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0645\u0627\u0626\u064A\u0629
#Change permissions
permissions.title=تغيير الأذونات
permissions.header=تغيير الأذونات
@ -402,6 +537,7 @@ permissions.selectText.9=منع الطباعة
permissions.selectText.10=منع طباعة التنسيقات المختلفة
permissions.submit=تغيير
#remove password
removePassword.title=إزالة كلمة المرور
removePassword.header=إزالة كلمة المرور (فك التشفير)
@ -409,7 +545,9 @@ removePassword.selectText.1=حدد PDF لفك التشفير
removePassword.selectText.2=كلمة المرور
removePassword.submit=إزالة
changeMetadata.title=\u062A\u063A\u064A\u064A\u0631 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0648\u0635\u0641\u064A\u0629
#changeMetadata
changeMetadata.title=\u0627\u0644\u0639\u0646\u0648\u0627\u0646:
changeMetadata.header=\u062A\u063A\u064A\u064A\u0631 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0648\u0635\u0641\u064A\u0629
changeMetadata.selectText.1=\u064A\u0631\u062C\u0649 \u062A\u0639\u062F\u064A\u0644 \u0627\u0644\u0645\u062A\u063A\u064A\u0631\u0627\u062A \u0627\u0644\u062A\u064A \u062A\u0631\u063A\u0628 \u0641\u064A \u062A\u063A\u064A\u064A\u0631\u0647\u0627
changeMetadata.selectText.2=\u062D\u0630\u0641 \u0643\u0644 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0623\u0648\u0644\u064A\u0629
@ -428,24 +566,29 @@ changeMetadata.selectText.5=\u0625\u0636\u0627\u0641\u0629 \u0625\u062F\u062E\u0
changeMetadata.submit=\u062A\u063A\u064A\u064A\u0631
#xlsToPdf
xlsToPdf.title=\u062A\u062D\u0648\u064A\u0644 Excel \u0625\u0644\u0649 PDF
xlsToPdf.header=\u062A\u062D\u0648\u064A\u0644 Excel \u0625\u0644\u0649 PDF
xlsToPdf.selectText.1=\u062D\u062F\u062F \u0648\u0631\u0642\u0629 \u0625\u0643\u0633\u0644 XLS \u0623\u0648 XLSX \u0644\u0644\u062A\u062D\u0648\u064A\u0644
xlsToPdf.convert=\u062A\u062D\u0648\u064A\u0644
#pdfToPDFA
pdfToPDFA.title=PDF \u0625\u0644\u0649 PDF / A
pdfToPDFA.header=PDF \u0625\u0644\u0649 PDF / A
pdfToPDFA.credit=\u062A\u0633\u062A\u062E\u062F\u0645 \u0647\u0630\u0647 \u0627\u0644\u062E\u062F\u0645\u0629 OCRmyPDF \u0644\u062A\u062D\u0648\u064A\u0644 PDF / A.
pdfToPDFA.submit=\u062A\u062D\u0648\u064A\u0644
#PDFToWord
PDFToWord.title=تحويل PDF إلى Word
PDFToWord.header=تحويل PDF إلى Word
PDFToWord.selectText.1=تنسيق ملف الإخراج
PDFToWord.credit=تستخدم هذه الخدمة LibreOffice لتحويل الملفات.
PDFToWord.submit=تحويل
#PDFToPresentation
PDFToPresentation.title=PDF للعرض التقديمي
PDFToPresentation.header=PDF للعرض التقديمي
PDFToPresentation.selectText.1=تنسيق ملف الإخراج
@ -453,6 +596,7 @@ PDFToPresentation.credit=تستخدم هذه الخدمة LibreOffice لتحوي
PDFToPresentation.submit=تحويل
#PDFToText
PDFToText.title=تحويل PDF إلى نص / RTF
PDFToText.header=تحويل PDF إلى نص / RTF
PDFToText.selectText.1=تنسيق ملف الإخراج
@ -460,11 +604,14 @@ PDFToText.credit=تستخدم هذه الخدمة LibreOffice لتحويل ال
PDFToText.submit=تحويل
#PDFToHTML
PDFToHTML.title=PDF إلى HTML
PDFToHTML.header=PDF إلى HTML
PDFToHTML.credit=تستخدم هذه الخدمة LibreOffice لتحويل الملفات.
PDFToHTML.submit=تحويل
#PDFToXML
PDFToXML.title=تحويل PDF إلى XML
PDFToXML.header=تحويل PDF إلى XML
PDFToXML.credit=تستخدم هذه الخدمة LibreOffice لتحويل الملفات.

View file

@ -21,23 +21,62 @@ filesSelected=fitxers seleccionats
noFavourites=No s'ha afegit cap favorit
bored=Avorrit esperant?
alphabet=Alfabet
downloadPdf=Descarregueu PDF
text=Text
font=Tipus de lletra
selectFillter=-- Selecciona --
pageNum=Número de pàgina
##########################
### TODO: Translate ###
##########################
sizes.small=Small
sizes.medium=Medium
sizes.large=Large
sizes.x-large=X-Large
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
#############
# NAVBAR #
#############
navbar.convert=Converteix
navbar.security=Seguretat
navbar.other=Altres
navbar.darkmode=Mode Fost
navbar.pageOps=Operacions de Pàgina
navbar.settings=Opcions
#############
# SETTINGS #
#############
settings.title=Opcions
settings.update=Actualització Disponible
settings.appVersion=Versió App:
settings.downloadOption.title=Trieu l'opció de descàrrega (per a descàrregues d'un sol fitxer no zip):
settings.downloadOption.1=Obre mateixa finestra
settings.downloadOption.2=Obre mateixa finestra
settings.downloadOption.3=Descarrega Arxiu
settings.zipThreshold=Comprimiu els fitxers quan el nombre de fitxers baixats superi
#############
# HOME-PAGE #
#############
home.desc=L'eina allotjada localment per a necessitats PDF.
navbar.convert=Converteix
navbar.security=Seguretat
navbar.other=Altres
navbar.darkmode=Mode Fost
navbar.pageOps=Operacions de Pàgina
home.multiTool.title=PDF Multi Tool
home.multiTool.desc=Fusiona, Rota, Reorganitza, i Esborra pàgines
##########################
### TODO: Translate ###
##########################
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
home.merge.title=Fusiona
home.merge.desc=Fusiona fàcilment pàgines en una.
##########################
### TODO: Translate ###
##########################
merge.tags=merge,Page operations,Back end,server side
home.split.title=Divideix
home.split.desc=Divideix PDFs en múltiples documents
@ -60,9 +99,6 @@ home.addImage.desc=Afegeix imatge en un PDF (En progrés)
home.watermark.title=Afegir Marca d'aigua
home.watermark.desc=Afegir Marca d'aigua personalitzada en un PDF
home.remove-watermark.title=Treure Marca d'Aigua
home.remove-watermark.desc=Treu Marca d'Aigua d'un PDF
home.permissions.title=Canvia permissos
home.permissions.desc=Canvia permisos del document PDF
@ -123,37 +159,128 @@ home.repair.desc=Intenta reparar un PDF danyat o trencat
home.removeBlanks.title=Elimina les pàgines en blanc
home.removeBlanks.desc=Detecta i elimina les pàgines en blanc d'un document
home.certSign.title=Sign with Certificate
home.certSign.desc=Signs a PDF with a Certificate/Key (PEM/P12)
home.compare.title=Compara
home.compare.desc=Compara i mostra les diferències entre 2 documents PDF
home.certSign.title=Sign with Certificate
home.certSign.desc=Signs a PDF with a Certificate/Key (PEM/P12)
home.pageLayout.title=Multi-Page Layout
home.pageLayout.desc=Merge multiple pages of a PDF document into a single page
home.scalePages.title=Adjust page size/scale
home.scalePages.desc=Change the size/scale of page and/or its contents.
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
##########################
### TODO: Translate ###
##########################
home.pipeline.title=Pipeline (Advanced)
home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts
downloadPdf=Descarregueu PDF
text=Text
font=Tipus de lletra
selectFillter=-- Selecciona --
pageNum=Número de pàgina
home.add-page-numbers.title=Add Page Numbers
home.add-page-numbers.desc=Add Page numbers throughout a document in a set location
home.auto-rename.title=Auto Rename PDF File
home.auto-rename.desc=Auto renames a PDF file based on its detected header
home.adjust-contrast.title=Adjust Colors/Contrast
home.adjust-contrast.desc=Adjust Contrast, Saturation and Brightness of a PDF
home.crop.title=Crop PDF
home.crop.desc=Crop a PDF to reduce its size (maintains text!)
home.autoSplitPDF.title=Auto Split Pages
home.autoSplitPDF.desc=Auto Split Scanned PDF with physical scanned page splitter QR Code
home.sanitizePdf.title=Sanitize
home.sanitizePdf.desc=Remove scripts and other elements from PDF files
###########################
# #
# WEB PAGES #
# #
###########################
#sanitizePDF
sanitizePDF.title=Sanitize PDF
sanitizePDF.header=Sanitize a PDF file
sanitizePDF.selectText.1=Remove JavaScript actions
sanitizePDF.selectText.2=Remove embedded files
sanitizePDF.selectText.3=Remove metadata
sanitizePDF.selectText.4=Remove links
sanitizePDF.selectText.5=Remove fonts
sanitizePDF.submit=Sanitize PDF
#addPageNumbers
addPageNumbers.title=Add Page Numbers
addPageNumbers.header=Add Page Numbers
addPageNumbers.selectText.1=Select PDF file:
addPageNumbers.selectText.2=Margin Size
addPageNumbers.selectText.3=Position
addPageNumbers.selectText.4=Starting Number
addPageNumbers.selectText.5=Pages to Number
addPageNumbers.selectText.6=Custom Text
addPageNumbers.submit=Add Page Numbers
#auto-rename
auto-rename.title=Auto Rename
auto-rename.header=Auto Rename PDF
auto-rename.submit=Auto Rename
#adjustContrast
adjustContrast.title=Adjust Contrast
adjustContrast.header=Adjust Contrast
adjustContrast.contrast=Contrast:
adjustContrast.brightness=Brightness:
adjustContrast.saturation=Saturation:
adjustContrast.download=Download
#crop
crop.title=Crop
crop.header=Crop Image
crop.submit=Submit
#autoSplitPDF
autoSplitPDF.title=Auto Split PDF
autoSplitPDF.header=Auto Split PDF
autoSplitPDF.description=Print, Insert, Scan, upload, and let us auto-separate your documents. No manual work sorting needed.
autoSplitPDF.selectText.1=Print out some divider sheets from below (Black and white is fine).
autoSplitPDF.selectText.2=Scan all your documents at once by inserting the divider sheet between them.
autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirling PDF handle the rest.
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
autoSplitPDF.submit=Submit
#pipeline
pipeline.title=Pipeline
#pageLayout
pageLayout.title=Multi Page Layout
pageLayout.header=Multi Page Layout
pageLayout.pagesPerSheet=Pages per sheet:
pageLayout.submit=Submit
#scalePages
scalePages.title=Adjust page-scale
scalePages.header=Adjust page-scale
scalePages.pageSize=Size of a page of the document.
scalePages.scaleFactor=Zoom level (crop) of a page.
scalePages.submit=Submit
#certSign
certSign.title=Significació del certificat
certSign.header=Firmar un PDF amb el vostre certificat (Treball en curs)
certSign.selectPDF=Seleccioneu un fitxer PDF per signar:
@ -168,6 +295,8 @@ certSign.location=Ubicació
certSign.name=Nom
certSign.submit=Firma PDF
#removeBlanks
removeBlanks.title=Elimina els espais en blanc
removeBlanks.header=Elimina les pàgines en blanc
removeBlanks.threshold=Llindar:
@ -176,12 +305,16 @@ removeBlanks.whitePercent=Percentatge blanc (%):
removeBlanks.whitePercentDesc=Percentatge de pàgina que ha de ser blanca per eliminar-la
removeBlanks.submit=Elimina els espais en blanc
#compare
compare.title=Comparar
compare.header=Compara PDF
compare.document.1=Document 1
compare.document.2=Document 2
compare.submit=Comparar
#sign
sign.title=Sign
sign.header=Firma els PDF
sign.upload=Penja la imatge
@ -190,14 +323,20 @@ sign.text=Entrada de text
sign.clear=Esborrar
sign.add=Afegeix
#repair
repair.title=Reparar
repair.header=Repara els PDF
repair.submit=Reparar
#flatten
flatten.title=Aplanar
flatten.header=Aplana els PDF
flatten.submit=Aplanar
#ScannerImageSplit
ScannerImageSplit.selectText.1=Llindar d'angle:
ScannerImageSplit.selectText.2=Estableix l'angle absolut mínim necessari perquè la imatge es giri (per defecte: 10).
ScannerImageSplit.selectText.3=Tolerància:
@ -209,19 +348,6 @@ ScannerImageSplit.selectText.8=Estableix el llindar mínim de l'àrea de contorn
ScannerImageSplit.selectText.9=Mida Vora:
ScannerImageSplit.selectText.10=Estableix la mida de la vora afegida i eliminada per evitar vores blanques a la sortida (per defecte: 1).
navbar.settings=Opcions
settings.title=Opcions
settings.update=Actualització Disponible
settings.appVersion=Versió App:
settings.downloadOption.title=Trieu l'opció de descàrrega (per a descàrregues d'un sol fitxer no zip):
settings.downloadOption.1=Obre mateixa finestra
settings.downloadOption.2=Obre mateixa finestra
settings.downloadOption.3=Descarrega Arxiu
settings.zipThreshold=Comprimiu els fitxers quan el nombre de fitxers baixats superi
#OCR
ocr.title=OCR / Neteja escaneig
@ -243,7 +369,7 @@ ocr.credit=Aquest servei empra OCRmyPDF i Tesseract per OCR.
ocr.submit=Processa PDF amb OCR
#extractImages
extractImages.title=Extreu Imatges
extractImages.header=Extreu Imatges
extractImages.selectText=Selecciona el format d'imatge al qual convertir les imatges extretes
@ -269,6 +395,7 @@ compress.selectText.4=Mode automàtic: ajusta automàticament la qualitat per ta
compress.selectText.5=Mida esperada del PDF (p. ex. 25 MB, 10,8 MB, 25 KB)
compress.submit=Comprimir
#Add image
addImage.title=Afegir Imatge
addImage.header=Afegir Imatge a PDF (en construcció)
@ -282,11 +409,13 @@ merge.title=Fusiona
merge.header=Fusiona múltiples PDFs (2+)
merge.submit=Fusiona
#pdfOrganiser
pdfOrganiser.title=Organitzador de pàgines
pdfOrganiser.header=Organitzador de pàgines PDF
pdfOrganiser.submit=Reorganitza Pàgines
#multiTool
multiTool.title=PDF Multi Tool
multiTool.header=PDF Multi Tool
@ -298,6 +427,7 @@ pageRemover.header=Eliminació Pàgines PDF
pageRemover.pagesToDelete=Pàgines a esborrar (Números de pàgina) :
pageRemover.submit=Esborra Pàgines
#rotate
rotate.title=Rota PDF
rotate.header=Rota PDF
@ -305,8 +435,6 @@ rotate.selectAngle=Selecciona l'angle de gir (en múltiples de 90 graus):
rotate.submit=Rota
#merge
split.title=Divideix PDF
split.header=Divideix PDF
@ -332,6 +460,7 @@ imageToPDF.selectText.3=Lògica de diversos fitxers (només està activada si es
imageToPDF.selectText.4=Combina en un únic PDF
imageToPDF.selectText.5=Converteix per separar PDFs
#pdfToImage
pdfToImage.title=PDF a Imatge
pdfToImage.header=PDF a Imatge
@ -345,6 +474,7 @@ pdfToImage.grey=Escala de Grisos
pdfToImage.blackwhite=Blanc i Negre (Pot perdre dades!)
pdfToImage.submit=Converteix
#addPassword
addPassword.title=Afegir Password
addPassword.header=Afegir password (Encriptat)
@ -366,6 +496,7 @@ addPassword.selectText.15=Restricts what can be done with the document once it i
addPassword.selectText.16=Restricts the opening of the document itself
addPassword.submit=Encripta
#watermark
watermark.title=Afegir Marca d'Aigua
watermark.header=Afegir Marca d'Aigua
@ -378,6 +509,7 @@ watermark.selectText.6=separació d'alçada (Espai vertical entre cada Marca d'A
watermark.selectText.7=Opacitat (0% - 100%):
watermark.submit=Afegir Marca d'Aigua
#remove-watermark
remove-watermark.title=Elimina Marca d'Aigua
remove-watermark.header=Elimina Marca d'Aigua
@ -385,6 +517,7 @@ remove-watermark.selectText.1=Seleciona PDF per eliminar Marca d'Aigua:
remove-watermark.selectText.2=Text de la Marca d'Aigua:
remove-watermark.submit=Elimina Marca d'Aigua
#Change permissions
permissions.title=Canviar Permissos
permissions.header=Canviar Permissos
@ -401,6 +534,7 @@ permissions.selectText.9=Evita impressió
permissions.selectText.10=Evita impressió de diferents formats
permissions.submit=Canviar Permissos
#remove password
removePassword.title=Treure Password
removePassword.header=Treure Password (Decriptar)
@ -408,7 +542,9 @@ removePassword.selectText.1=Selecciona PDF a Decriptar
removePassword.selectText.2=Password
removePassword.submit=Treu Password
changeMetadata.title=Canvia Metadades
#changeMetadata
changeMetadata.title=Títol:
changeMetadata.header=Canvia Metadades
changeMetadata.selectText.1=Edit les variables a canviar
changeMetadata.selectText.2=Neteja totes les matadades
@ -426,27 +562,30 @@ changeMetadata.selectText.4=Altres Metadades:
changeMetadata.selectText.5=Afegir entrada personalizada
changeMetadata.submit=Canvia
#xlsToPdf
xlsToPdf.title=Excel a PDF
xlsToPdf.header=Excel a PDF
xlsToPdf.selectText.1=Selecciona arxiu XLS o XLSX a convertir
xlsToPdf.convert=Converteix
#pdfToPDFA
pdfToPDFA.title=PDF a PDF/A
pdfToPDFA.header=PDF a PDF/A
pdfToPDFA.credit=Utilitza OCRmyPDF per la conversió a PDF/A
pdfToPDFA.submit=Converteix
#PDFToWord
PDFToWord.title=PDF a Word
PDFToWord.header=PDF a Word
PDFToWord.selectText.1=Format d'Arxiu de Sortida
PDFToWord.credit=Utilitza LibreOffice per a la conversió d'Arxius.
PDFToWord.submit=Converteix
#PDFToPresentation
PDFToPresentation.title=PDF a Presentació
PDFToPresentation.header=PDF a Presentació
PDFToPresentation.selectText.1=Format d'Arxiu de Sortida
@ -454,6 +593,7 @@ PDFToPresentation.credit=Utilitza LibreOffice per a la conversió d'Arxius.
PDFToPresentation.submit=Converteix
#PDFToText
PDFToText.title=PDF a Text/RTF
PDFToText.header=PDF a Text/RTF
PDFToText.selectText.1=Format d'Arxiu de Sortida
@ -461,24 +601,15 @@ PDFToText.credit=Utilitza LibreOffice per a la conversió d'Arxius.
PDFToText.submit=Converteix
#PDFToHTML
PDFToHTML.title=PDF a HTML
PDFToHTML.header=PDF a HTML
PDFToHTML.credit=Utilitza LibreOffice per a la conversió d'Arxius.
PDFToHTML.submit=Converteix
#PDFToXML
PDFToXML.title=PDF a XML
PDFToXML.header=PDF a XML
PDFToXML.credit=Utilitza LibreOffice per a la conversió d'Arxius.
PDFToXML.submit=Converteix

View file

@ -1,7 +1,7 @@
###########
# Generic #
###########
# the direction that the language is written (ltr=left to right, rtl=right to left)
# the direction that the language is written (ltr = left to right, rtl = right to left)
language.direction=ltr
pdfPrompt=PDF auswählen
@ -21,22 +21,62 @@ filesSelected=Dateien ausgewählt
noFavourites=Keine Favoriten hinzugefügt
bored=Gelangweiltes Warten?
alphabet=Alphabet
#############
# HOME-PAGE #
#############
home.desc=Ihr lokal gehosteter One-Stop-Shop für alle Ihre PDF-Anforderungen.
downloadPdf=PDF herunterladen
text=Text
font=Schriftart
selectFillter=-- Auswählen --
pageNum=Seitenzahl
##########################
### TODO: Translate ###
##########################
sizes.small=Small
sizes.medium=Medium
sizes.large=Large
sizes.x-large=X-Large
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
#############
# NAVBAR #
#############
navbar.convert=Konvertieren
navbar.security=Sicherheit
navbar.other=Anderes
navbar.darkmode=Dark Mode
navbar.pageOps=Seitenoperationen
navbar.settings=Einstellungen
#############
# SETTINGS #
#############
settings.title=Einstellungen
settings.update=Update verfügbar
settings.appVersion=App-Version:
settings.downloadOption.title=Download-Option wählen (für einzelne Dateien, die keine Zip-Downloads sind):
settings.downloadOption.1=Im selben Fenster öffnen
settings.downloadOption.2=In neuem Fenster öffnen
settings.downloadOption.3=Datei herunterladen
settings.zipThreshold=Dateien komprimieren, wenn die Anzahl der heruntergeladenen Dateien überschritten wird
#############
# HOME-PAGE #
#############
home.desc=Ihr lokal gehosteter One-Stop-Shop für alle Ihre PDF-Anforderungen.
home.multiTool.title=PDF-Multitool
home.multiTool.desc=Seiten zusammenführen, drehen, neu anordnen und entfernen
##########################
### TODO: Translate ###
##########################
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
home.merge.title=Zusammenführen
home.merge.desc=Mehrere PDF-Dateien zu einer einzigen zusammenführen.
##########################
### TODO: Translate ###
##########################
merge.tags=merge,Page operations,Back end,server side
home.split.title=Aufteilen
home.split.desc=PDFs in mehrere Dokumente aufteilen.
@ -59,9 +99,6 @@ home.addImage.desc=Fügt ein Bild an eine bestimmte Stelle im PDF ein (Work in p
home.watermark.title=Wasserzeichen hinzufügen
home.watermark.desc=Fügen Sie ein eigenes Wasserzeichen zu Ihrem PDF hinzu.
home.remove-watermark.title=Wasserzeichen entfernen
home.remove-watermark.desc=Wasserzeichen aus Ihrem PDF-Dokument entfernen.
home.permissions.title=Berechtigungen ändern
home.permissions.desc=Die Berechtigungen für Ihr PDF-Dokument verändern.
@ -122,37 +159,128 @@ home.repair.desc=Versucht, ein beschädigtes/kaputtes PDF zu reparieren
home.removeBlanks.title=Leere Seiten entfernen
home.removeBlanks.desc=Erkennt und entfernt leere Seiten aus einem Dokument
home.certSign.title=Sign with Certificate
home.certSign.desc=Signs a PDF with a Certificate/Key (PEM/P12)
home.compare.title=Vergleichen
home.compare.desc=Vergleicht und zeigt die Unterschiede zwischen zwei PDF-Dokumenten an
home.certSign.title=Sign with Certificate
home.certSign.desc=Signs a PDF with a Certificate/Key (PEM/P12)
home.pageLayout.title=Multi-Page Layout
home.pageLayout.desc=Merge multiple pages of a PDF document into a single page
home.scalePages.title=Adjust page size/scale
home.scalePages.desc=Change the size/scale of page and/or its contents.
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
##########################
### TODO: Translate ###
##########################
home.pipeline.title=Pipeline (Advanced)
home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts
downloadPdf=PDF herunterladen
text=Text
font=Schriftart
selectFillter=-- Auswählen --
pageNum=Seitenzahl
home.add-page-numbers.title=Add Page Numbers
home.add-page-numbers.desc=Add Page numbers throughout a document in a set location
home.auto-rename.title=Auto Rename PDF File
home.auto-rename.desc=Auto renames a PDF file based on its detected header
home.adjust-contrast.title=Adjust Colors/Contrast
home.adjust-contrast.desc=Adjust Contrast, Saturation and Brightness of a PDF
home.crop.title=Crop PDF
home.crop.desc=Crop a PDF to reduce its size (maintains text!)
home.autoSplitPDF.title=Auto Split Pages
home.autoSplitPDF.desc=Auto Split Scanned PDF with physical scanned page splitter QR Code
home.sanitizePdf.title=Sanitize
home.sanitizePdf.desc=Remove scripts and other elements from PDF files
###########################
# #
# WEB PAGES #
# #
###########################
#sanitizePDF
sanitizePDF.title=Sanitize PDF
sanitizePDF.header=Sanitize a PDF file
sanitizePDF.selectText.1=Remove JavaScript actions
sanitizePDF.selectText.2=Remove embedded files
sanitizePDF.selectText.3=Remove metadata
sanitizePDF.selectText.4=Remove links
sanitizePDF.selectText.5=Remove fonts
sanitizePDF.submit=Sanitize PDF
#addPageNumbers
addPageNumbers.title=Add Page Numbers
addPageNumbers.header=Add Page Numbers
addPageNumbers.selectText.1=Select PDF file:
addPageNumbers.selectText.2=Margin Size
addPageNumbers.selectText.3=Position
addPageNumbers.selectText.4=Starting Number
addPageNumbers.selectText.5=Pages to Number
addPageNumbers.selectText.6=Custom Text
addPageNumbers.submit=Add Page Numbers
#auto-rename
auto-rename.title=Auto Rename
auto-rename.header=Auto Rename PDF
auto-rename.submit=Auto Rename
#adjustContrast
adjustContrast.title=Adjust Contrast
adjustContrast.header=Adjust Contrast
adjustContrast.contrast=Contrast:
adjustContrast.brightness=Brightness:
adjustContrast.saturation=Saturation:
adjustContrast.download=Download
#crop
crop.title=Crop
crop.header=Crop Image
crop.submit=Submit
#autoSplitPDF
autoSplitPDF.title=Auto Split PDF
autoSplitPDF.header=Auto Split PDF
autoSplitPDF.description=Print, Insert, Scan, upload, and let us auto-separate your documents. No manual work sorting needed.
autoSplitPDF.selectText.1=Print out some divider sheets from below (Black and white is fine).
autoSplitPDF.selectText.2=Scan all your documents at once by inserting the divider sheet between them.
autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirling PDF handle the rest.
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
autoSplitPDF.submit=Submit
#pipeline
pipeline.title=Pipeline
#pageLayout
pageLayout.title=Multi Page Layout
pageLayout.header=Multi Page Layout
pageLayout.pagesPerSheet=Pages per sheet:
pageLayout.submit=Submit
#scalePages
scalePages.title=Adjust page-scale
scalePages.header=Adjust page-scale
scalePages.pageSize=Size of a page of the document.
scalePages.scaleFactor=Zoom level (crop) of a page.
scalePages.submit=Submit
#certSign
certSign.title=Zertifikatsignierung
certSign.header=Signieren Sie ein PDF mit Ihrem Zertifikat (in Arbeit)
certSign.selectPDF=Wählen Sie eine PDF-Datei zum Signieren aus:
@ -167,6 +295,8 @@ certSign.location=Standort
certSign.name=Name
certSign.submit=PDF signieren
#removeBlanks
removeBlanks.title=Leerzeichen entfernen
removeBlanks.header=Leere Seiten entfernen
removeBlanks.threshold=Schwellenwert:
@ -175,12 +305,16 @@ removeBlanks.whitePercent=Weißprozentsatz (%):
removeBlanks.whitePercentDesc=Prozentsatz der Seite, die weiß sein muss, um entfernt zu werden
removeBlanks.submit=Leerzeichen entfernen
#compare
compare.title=Vergleichen
compare.header=PDFs vergleichen
compare.document.1=Dokument 1
compare.document.2=Dokument 2
compare.submit=Vergleichen
#sign
sign.title=Signieren
sign.header=PDFs signieren
sign.upload=Bild hochladen
@ -189,14 +323,23 @@ sign.text=Texteingabe
sign.clear=Klar
sign.add=Hinzufügen
#repair
repair.title=Reparieren
Repair.header=PDFs reparieren
##########################
### TODO: Translate ###
##########################
repair.header=Repair PDFs
repair.submit=Reparieren
#flatten
flatten.title=Abflachen
flatten.header=PDFs reduzieren
flatten.submit=Abflachen
#ScannerImageSplit
ScannerImageSplit.selectText.1=Winkelschwelle:
ScannerImageSplit.selectText.2=Legt den minimalen absoluten Winkel fest, der erforderlich ist, damit das Bild gedreht werden kann (Standard: 10).
ScannerImageSplit.selectText.3=Toleranz:
@ -209,16 +352,6 @@ ScannerImageSplit.selectText.9=Randgröße:
ScannerImageSplit.selectText.10=Legt die Größe des hinzugefügten und entfernten Randes fest, um weiße Ränder in der Ausgabe zu verhindern (Standard: 1).
navbar.settings=Einstellungen
settings.title=Einstellungen
settings.update=Update verfügbar
settings.appVersion=App-Version:
settings.downloadOption.title=Download-Option wählen (für einzelne Dateien, die keine Zip-Downloads sind):
settings.downloadOption.1=Im selben Fenster öffnen
settings.downloadOption.2=In neuem Fenster öffnen
settings.downloadOption.3=Datei herunterladen
settings.zipThreshold=Dateien komprimieren, wenn die Anzahl der heruntergeladenen Dateien überschritten wird
#OCR
ocr.title=OCR / Scan-Bereinigung
ocr.header=Scans bereinigen / OCR (Optical Character Recognition)
@ -239,6 +372,7 @@ ocr.credit=Dieser Dienst verwendet OCRmyPDF und Tesseract für OCR.
ocr.submit=PDF mit OCR verarbeiten
#extractImages
extractImages.title=Bilder extrahieren
extractImages.header=Bilder extrahieren
extractImages.selectText=Wählen Sie das Bildformat aus, in das extrahierte Bilder konvertiert werden sollen
@ -253,16 +387,6 @@ fileToPDF.supportedFileTypes=Unterstützte Dateitypen sollten die folgenden enth
fileToPDF.submit=In PDF konvertieren
#Add image
addImage.title=Bild hinzufügen
addImage.header=Ein Bild einfügen
addImage.everyPage=Jede Seite?
addImage.upload=Bild hinzufügen
addImage.submit=Bild hinzufügen
#compress
compress.title=Komprimieren
compress.header=PDF komprimieren
@ -275,26 +399,38 @@ compress.selectText.5=Erwartete PDF-Größe (z. B. 25 MB, 10,8 MB, 25 KB)
compress.submit=Komprimieren
#Add image
addImage.title=Bild hinzufügen
addImage.header=Ein Bild einfügen
addImage.everyPage=Jede Seite?
addImage.upload=Bild hinzufügen
addImage.submit=Bild hinzufügen
#merge
merge.title=Zusammenführen
merge.header=Mehrere PDFs zusammenführen (2+)
merge.submit=Zusammenführen
#pdfOrganiser
pdfOrganiser.title=Seiten anordnen
pdfOrganiser.header=PDF Seitenorganisation
pdfOrganiser.submit=Seiten anordnen
#Mehrfachwerkzeug
#multiTool
multiTool.title=PDF-Multitool
multiTool.header=PDF-Multitool
#pageRemover
pageRemover.title=Seiten entfernen
pageRemover.header=PDF Seiten entfernen
pageRemover.pagesToDelete=Seiten zu entfernen (geben Sie eine Kommagetrennte Liste der Seitenzahlen an):
pageRemover.submit=Seiten löschen
#rotate
rotate.title=PDF drehen
rotate.header=PDF drehen
@ -302,8 +438,6 @@ rotate.selectAngle=Wählen Sie den Winkel (in Vielfachen von 90 Grad):
rotate.submit=Drehen
#merge
split.title=PDF aufteilen
split.header=PDF aufteilen
@ -329,6 +463,7 @@ imageToPDF.selectText.3=Mehrere Dateien verarbeiten (nur aktiv, wenn Sie mit meh
imageToPDF.selectText.4=In ein einziges PDF zusammenführen
imageToPDF.selectText.5=In separate PDFs konvertieren
#pdfToImage
pdfToImage.title=PDF zu Bild
pdfToImage.header=PDF zu Bild
@ -342,6 +477,7 @@ pdfToImage.grey=Graustufen
pdfToImage.blackwhite=Schwarzweiß (Datenverlust möglich!)
pdfToImage.submit=Umwandeln
#addPassword
addPassword.title=Passwort hinzufügen
addPassword.header=Passwort hinzufügen (Verschlüsseln)
@ -363,6 +499,7 @@ addPassword.selectText.15=Restricts what can be done with the document once it i
addPassword.selectText.16=Restricts the opening of the document itself
addPassword.submit=Verschlüsseln
#watermark
watermark.title=Wasserzeichen hinzufügen
watermark.header=Wasserzeichen hinzufügen
@ -375,6 +512,7 @@ watermark.selectText.6=höheSpacer (vertikaler Abstand zwischen den einzelnen Wa
watermark.selectText.7=Deckkraft (0% - 100 %):
watermark.submit=Wasserzeichen hinzufügen
#remove-watermark
remove-watermark.title=Wasserzeichen entfernen
remove-watermark.header=Wasserzeichen entfernen
@ -382,6 +520,7 @@ remove-watermark.selectText.1=PDF auswählen, um Wasserzeichen zu entfernen von:
remove-watermark.selectText.2=Wasserzeichentext:
remove-watermark.submit=Wasserzeichen entfernen
#Change permissions
permissions.title=Berechtigungen ändern
permissions.header=Berechtigungen ändern
@ -398,6 +537,7 @@ permissions.selectText.9=Drucken verhindern
permissions.selectText.10=Drucken verschiedener Formate verhindern
permissions.submit=Ändern
#remove password
removePassword.title=Passwort entfernen
removePassword.header=Passwort entfernen (Entschlüsseln)
@ -406,7 +546,8 @@ removePassword.selectText.2=Passwort
removePassword.submit=Entfernen
changeMetadata.title=Metadaten ändern
#changeMetadata
changeMetadata.title=Titel:
changeMetadata.header=Metadaten ändern
changeMetadata.selectText.1=Bitte bearbeiten Sie die Variablen, die Sie ändern möchten
changeMetadata.selectText.2=Alle Metadaten löschen
@ -425,28 +566,29 @@ changeMetadata.selectText.5=Benutzerdefinierten Metadateneintrag hinzufügen
changeMetadata.submit=Ändern
#xlsToPdf
xlsToPdf.title=Excel in PDF
xlsToPdf.header=Excel in PDF
xlsToPdf.selectText.1=XLS- oder XLSX-Excel-Tabelle zum Konvertieren auswählen
xlsToPdf.convert=konvertieren
#pdfToPDFA
pdfToPDFA.title=PDF zu PDF/A
pdfToPDFA.header=PDF zu PDF/A
pdfToPDFA.credit=Dieser Dienst verwendet OCRmyPDF für die PDF/A-Konvertierung
pdfToPDFA.submit=Konvertieren
#PDFToWord
PDFToWord.title=PDF zu Word
PDFToWord.header=PDF zu Word
PDFToWord.selectText.1=Ausgabedateiformat
PDFToWord.credit=Dieser Dienst verwendet LibreOffice für die Dateikonvertierung.
PDFToWord.submit=Konvertieren
#PDFToPresentation
PDFToPresentation.title=PDF zu Präsentation
PDFToPresentation.header=PDF zu Präsentation
PDFToPresentation.selectText.1=Ausgabedateiformat
@ -454,6 +596,7 @@ PDFToPresentation.credit=Dieser Dienst verwendet LibreOffice für die Dateikonve
PDFToPresentation.submit=Konvertieren
#PDFToText
PDFToText.title=PDF in Text/RTF
PDFToText.header=PDF in Text/RTF
PDFToText.selectText.1=Ausgabedateiformat
@ -461,27 +604,15 @@ PDFToText.credit=Dieser Dienst verwendet LibreOffice für die Dateikonvertierung
PDFToText.submit=Konvertieren
#PDFToHTML
PDFToHTML.title=PDF in HTML
PDFToHTML.header=PDF in HTML
PDFToHTML.credit=Dieser Dienst verwendet LibreOffice für die Dateikonvertierung.
PDFToHTML.submit=Konvertieren
#PDFToXML
PDFToXML.title=PDF in XML
PDFToXML.header=PDF in XML
PDFToXML.credit=Dieser Dienst verwendet LibreOffice für die Dateikonvertierung.
PDFToXML.submit=Konvertieren

View file

@ -21,23 +21,53 @@ filesSelected=files selected
noFavourites=No favourites added
bored=Bored Waiting?
alphabet=Alphabet
downloadPdf=Download PDF
text=Text
font=Font
selectFillter=-- Select --
pageNum=Page Number
sizes.small=Small
sizes.medium=Medium
sizes.large=Large
sizes.x-large=X-Large
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
#############
# NAVBAR #
#############
navbar.convert=Convert
navbar.security=Security
navbar.other=Other
navbar.darkmode=Dark Mode
navbar.pageOps=Page Operations
navbar.settings=Settings
#############
# SETTINGS #
#############
settings.title=Settings
settings.update=Update available
settings.appVersion=App Version:
settings.downloadOption.title=Choose download option (For single file non zip downloads):
settings.downloadOption.1=Open in same window
settings.downloadOption.2=Open in new window
settings.downloadOption.3=Download file
settings.zipThreshold=Zip files when the number of downloaded files exceeds
#############
# HOME-PAGE #
#############
home.desc=Your locally hosted one-stop-shop for all your PDF needs.
navbar.convert=Convert
navbar.security=Security
navbar.other=Other
navbar.darkmode=Dark Mode
navbar.pageOps=Page Operations
home.multiTool.title=PDF Multi Tool
home.multiTool.desc=Merge, Rotate, Rearrange, and Remove pages
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
home.merge.title=Merge
home.merge.desc=Easily merge multiple PDFs into one.
merge.tags=merge,Page operations,Back end,server side
home.split.title=Split
home.split.desc=Split PDFs into multiple documents
@ -132,30 +162,113 @@ home.pageLayout.desc=Merge multiple pages of a PDF document into a single page
home.scalePages.title=Adjust page size/scale
home.scalePages.desc=Change the size/scale of a page and/or its contents.
home.pipeline.title=Pipeline
home.pipeline.desc=Pipeline desc.
home.pipeline.title=Pipeline (Advanced)
home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
home.add-page-numbers.title=Add Page Numbers
home.add-page-numbers.desc=Add Page numbers throughout a document in a set location
downloadPdf=Download PDF
text=Text
font=Font
selectFillter=-- Select --
pageNum=Page Number
home.auto-rename.title=Auto Rename PDF File
home.auto-rename.desc=Auto renames a PDF file based on its detected header
home.adjust-contrast.title=Adjust Colors/Contrast
home.adjust-contrast.desc=Adjust Contrast, Saturation and Brightness of a PDF
home.crop.title=Crop PDF
home.crop.desc=Crop a PDF to reduce its size (maintains text!)
home.autoSplitPDF.title=Auto Split Pages
home.autoSplitPDF.desc=Auto Split Scanned PDF with physical scanned page splitter QR Code
home.sanitizePdf.title=Sanitize
home.sanitizePdf.desc=Remove scripts and other elements from PDF files
###########################
# #
# WEB PAGES #
# #
###########################
#sanitizePDF
sanitizePDF.title=Sanitize PDF
sanitizePDF.header=Sanitize a PDF file
sanitizePDF.selectText.1=Remove JavaScript actions
sanitizePDF.selectText.2=Remove embedded files
sanitizePDF.selectText.3=Remove metadata
sanitizePDF.selectText.4=Remove links
sanitizePDF.selectText.5=Remove fonts
sanitizePDF.submit=Sanitize PDF
#addPageNumbers
addPageNumbers.title=Add Page Numbers
addPageNumbers.header=Add Page Numbers
addPageNumbers.selectText.1=Select PDF file:
addPageNumbers.selectText.2=Margin Size
addPageNumbers.selectText.3=Position
addPageNumbers.selectText.4=Starting Number
addPageNumbers.selectText.5=Pages to Number
addPageNumbers.selectText.6=Custom Text
addPageNumbers.submit=Add Page Numbers
#auto-rename
auto-rename.title=Auto Rename
auto-rename.header=Auto Rename PDF
auto-rename.submit=Auto Rename
#adjustContrast
adjustContrast.title=Adjust Contrast
adjustContrast.header=Adjust Contrast
adjustContrast.contrast=Contrast:
adjustContrast.brightness=Brightness:
adjustContrast.saturation=Saturation:
adjustContrast.download=Download
#crop
crop.title=Crop
crop.header=Crop Image
crop.submit=Submit
#autoSplitPDF
autoSplitPDF.title=Auto Split PDF
autoSplitPDF.header=Auto Split PDF
autoSplitPDF.description=Print, Insert, Scan, upload, and let us auto-separate your documents. No manual work sorting needed.
autoSplitPDF.selectText.1=Print out some divider sheets from below (Black and white is fine).
autoSplitPDF.selectText.2=Scan all your documents at once by inserting the divider sheet between them.
autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirling PDF handle the rest.
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
autoSplitPDF.submit=Submit
#pipeline
pipeline.title=Pipeline
#pageLayout
pageLayout.title=Multi Page Layout
pageLayout.header=Multi Page Layout
pageLayout.pagesPerSheet=Pages per sheet:
pageLayout.submit=Submit
#scalePages
scalePages.title=Adjust page-scale
scalePages.header=Adjust page-scale
scalePages.pageSize=Size of a page of the document.
scalePages.scaleFactor=Zoom level (crop) of a page.
scalePages.submit=Submit
#certSign
certSign.title=Certificate Signing
certSign.header=Sign a PDF with your certificate (Work in progress)
certSign.selectPDF=Select a PDF File for Signing:
@ -168,11 +281,10 @@ certSign.showSig=Show Signature
certSign.reason=Reason
certSign.location=Location
certSign.name=Name
certSign.submit=Sign PDF
#removeBlanks
removeBlanks.title=Remove Blanks
removeBlanks.header=Remove Blank Pages
removeBlanks.threshold=Threshold:
@ -181,12 +293,16 @@ removeBlanks.whitePercent=White Percent (%):
removeBlanks.whitePercentDesc=Percent of page that must be white to be removed
removeBlanks.submit=Remove Blanks
#compare
compare.title=Compare
compare.header=Compare PDFs
compare.document.1=Document 1
compare.document.2=Document 2
compare.submit=Compare
#sign
sign.title=Sign
sign.header=Sign PDFs
sign.upload=Upload Image
@ -195,14 +311,20 @@ sign.text=Text Input
sign.clear=Clear
sign.add=Add
#repair
repair.title=Repair
repair.header=Repair PDFs
repair.submit=Repair
#flatten
flatten.title=Flatten
flatten.header=Flatten PDFs
flatten.submit=Flatten
#ScannerImageSplit
ScannerImageSplit.selectText.1=Angle Threshold:
ScannerImageSplit.selectText.2=Sets the minimum absolute angle required for the image to be rotated (default: 10).
ScannerImageSplit.selectText.3=Tolerance:
@ -214,19 +336,6 @@ ScannerImageSplit.selectText.8=Sets the minimum contour area threshold for a pho
ScannerImageSplit.selectText.9=Border Size:
ScannerImageSplit.selectText.10=Sets the size of the border added and removed to prevent white borders in the output (default: 1).
navbar.settings=Settings
settings.title=Settings
settings.update=Update available
settings.appVersion=App Version:
settings.downloadOption.title=Choose download option (For single file non zip downloads):
settings.downloadOption.1=Open in same window
settings.downloadOption.2=Open in new window
settings.downloadOption.3=Download file
settings.zipThreshold=Zip files when the number of downloaded files exceeds
#OCR
ocr.title=OCR / Scan Cleanup
@ -248,7 +357,7 @@ ocr.credit=This service uses OCRmyPDF and Tesseract for OCR.
ocr.submit=Process PDF with OCR
#extractImages
extractImages.title=Extract Images
extractImages.header=Extract Images
extractImages.selectText=Select image format to convert extracted images to
@ -288,11 +397,13 @@ merge.title=Merge
merge.header=Merge multiple PDFs (2+)
merge.submit=Merge
#pdfOrganiser
pdfOrganiser.title=Page Organiser
pdfOrganiser.header=PDF Page Organiser
pdfOrganiser.submit=Rearrange Pages
#multiTool
multiTool.title=PDF Multi Tool
multiTool.header=PDF Multi Tool
@ -304,6 +415,7 @@ pageRemover.header=PDF Page remover
pageRemover.pagesToDelete=Pages to delete (Enter a comma-separated list of page numbers) :
pageRemover.submit=Delete Pages
#rotate
rotate.title=Rotate PDF
rotate.header=Rotate PDF
@ -311,8 +423,6 @@ rotate.selectAngle=Select rotation angle (in multiples of 90 degrees):
rotate.submit=Rotate
#merge
split.title=Split PDF
split.header=Split PDF
@ -338,6 +448,7 @@ imageToPDF.selectText.3=Multi file logic (Only enabled if working with multiple
imageToPDF.selectText.4=Merge into single PDF
imageToPDF.selectText.5=Convert to separate PDFs
#pdfToImage
pdfToImage.title=PDF to Image
pdfToImage.header=PDF to Image
@ -351,6 +462,7 @@ pdfToImage.grey=Greyscale
pdfToImage.blackwhite=Black and White (May lose data!)
pdfToImage.submit=Convert
#addPassword
addPassword.title=Add Password
addPassword.header=Add password (Encrypt)
@ -372,6 +484,7 @@ addPassword.selectText.15=Restricts what can be done with the document once it i
addPassword.selectText.16=Restricts the opening of the document itself
addPassword.submit=Encrypt
#watermark
watermark.title=Add Watermark
watermark.header=Add Watermark
@ -384,6 +497,7 @@ watermark.selectText.6=heightSpacer (Space between each watermark vertically):
watermark.selectText.7=Opacity (0% - 100%):
watermark.submit=Add Watermark
#remove-watermark
remove-watermark.title=Remove Watermark
remove-watermark.header=Remove Watermark
@ -391,6 +505,7 @@ remove-watermark.selectText.1=Select PDF to remove watermark from:
remove-watermark.selectText.2=Watermark Text:
remove-watermark.submit=Remove Watermark
#Change permissions
permissions.title=Change Permissions
permissions.header=Change Permissions
@ -407,6 +522,7 @@ permissions.selectText.9=Prevent printing
permissions.selectText.10=Prevent printing different formats
permissions.submit=Change
#remove password
removePassword.title=Remove password
removePassword.header=Remove password (Decrypt)
@ -414,6 +530,8 @@ removePassword.selectText.1=Select PDF to Decrypt
removePassword.selectText.2=Password
removePassword.submit=Remove
#changeMetadata
changeMetadata.title=Change Metadata
changeMetadata.header=Change Metadata
changeMetadata.selectText.1=Please edit the variables you wish to change
@ -432,27 +550,30 @@ changeMetadata.selectText.4=Other Metadata:
changeMetadata.selectText.5=Add Custom Metadata Entry
changeMetadata.submit=Change
#xlsToPdf
xlsToPdf.title=Excel to PDF
xlsToPdf.header=Excel to PDF
xlsToPdf.selectText.1=Select XLS or XLSX Excel sheet to convert
xlsToPdf.convert=convert
#pdfToPDFA
pdfToPDFA.title=PDF To PDF/A
pdfToPDFA.header=PDF To PDF/A
pdfToPDFA.credit=This service uses OCRmyPDF for PDF/A conversion
pdfToPDFA.submit=Convert
#PDFToWord
PDFToWord.title=PDF to Word
PDFToWord.header=PDF to Word
PDFToWord.selectText.1=Output file format
PDFToWord.credit=This service uses LibreOffice for file conversion.
PDFToWord.submit=Convert
#PDFToPresentation
PDFToPresentation.title=PDF to Presentation
PDFToPresentation.header=PDF to Presentation
PDFToPresentation.selectText.1=Output file format
@ -460,6 +581,7 @@ PDFToPresentation.credit=This service uses LibreOffice for file conversion.
PDFToPresentation.submit=Convert
#PDFToText
PDFToText.title=PDF to Text/RTF
PDFToText.header=PDF to Text/RTF
PDFToText.selectText.1=Output file format
@ -467,24 +589,15 @@ PDFToText.credit=This service uses LibreOffice for file conversion.
PDFToText.submit=Convert
#PDFToHTML
PDFToHTML.title=PDF to HTML
PDFToHTML.header=PDF to HTML
PDFToHTML.credit=This service uses LibreOffice for file conversion.
PDFToHTML.submit=Convert
#PDFToXML
PDFToXML.title=PDF to XML
PDFToXML.header=PDF to XML
PDFToXML.credit=This service uses LibreOffice for file conversion.
PDFToXML.submit=Convert

View file

@ -21,22 +21,65 @@ filesSelected=archivos seleccionados
noFavourites=No se agregaron favoritos
bored=¿Aburrido de esperar?
alphabet=Alfabeto
#############
# HOME-PAGE #
#############
home.desc=Tu ventanilla única autohospedada para todas tus necesidades PDF
downloadPdf=Descargar PDF
text=Texto
font=Fuente
##########################
### TODO: Translate ###
##########################
selectFillter=-- Select --
pageNum=Número de página
##########################
### TODO: Translate ###
##########################
sizes.small=Small
sizes.medium=Medium
sizes.large=Large
sizes.x-large=X-Large
error.pdfPassword=El documento PDF está protegido con contraseña y no se ha proporcionado o es incorrecta
#############
# NAVBAR #
#############
navbar.convert=Convertir
navbar.security=Seguridad
navbar.other=Otro
navbar.darkmode=Modo oscuro
navbar.pageOps=Operaciones de página
navbar.settings=Ajustes
#############
# SETTINGS #
#############
settings.title=Ajustes
settings.update=Actualización disponible
settings.appVersion=Versión de la aplicación:
settings.downloadOption.title=Elegir la opción de descarga (para descargas de un solo archivo sin ZIP):
settings.downloadOption.1=Abrir en la misma ventana
settings.downloadOption.2=Abrir en una nueva ventana
settings.downloadOption.3=Descargar el fichero
settings.zipThreshold=Ficheros ZIP cuando excede el número de ficheros descargados
#############
# HOME-PAGE #
#############
home.desc=Tu ventanilla única autohospedada para todas tus necesidades PDF
home.multiTool.title=Multi-herramienta PDF
home.multiTool.desc=Combinar, rotar, reorganizar y eliminar páginas
##########################
### TODO: Translate ###
##########################
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
home.merge.title=Unir
home.merge.desc=Unir fácilmente múltiples PDFs en uno
##########################
### TODO: Translate ###
##########################
merge.tags=merge,Page operations,Back end,server side
home.split.title=Dividir
home.split.desc=Dividir PDFs en múltiples documentos
@ -59,9 +102,6 @@ home.addImage.desc=Agregar una imagen en una ubicación establecida en el PDF (t
home.watermark.title=Añadir marca de agua
home.watermark.desc=Añadir una marca de agua predefinida al documento PDF
home.remove-watermark.title=Eliminar marca de agua
home.remove-watermark.desc=Eliminar marca de agua de tu documento PDF
home.permissions.title=Cambiar permisos
home.permissions.desc=Cambiar los permisos del documento PDF
@ -122,37 +162,128 @@ home.repair.desc=Intentar reparar un PDF corrupto/roto
home.removeBlanks.title=Eliminar páginas en blanco
home.removeBlanks.desc=Detectar y eliminar páginas en blanco de un documento
home.certSign.title=Firmar con certificado
home.certSign.desc=Firmar un PDF con un Certificado/Clave (PEM/P12)
home.compare.title=Comparar
home.compare.desc=Comparar y mostrar las diferencias entre 2 documentos PDF
home.certSign.title=Firmar con certificado
home.certSign.desc=Firmar un PDF con un Certificado/Clave (PEM/P12)
home.pageLayout.title=Diseño de varias páginas
home.pageLayout.desc=Unir varias páginas de un documento PDF en una sola página
home.scalePages.title=Escalar/ajustar tamaño de página
home.scalePages.desc=Escalar/cambiar el tamaño de una pagina y/o su contenido
error.pdfPassword=El documento PDF está protegido con contraseña y no se ha proporcionado o es incorrecta
##########################
### TODO: Translate ###
##########################
home.pipeline.title=Pipeline (Advanced)
home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts
downloadPdf=Descargar PDF
text=Texto
font=Fuente
selectFilter=-- Seleccionar --
pageNum=Número de página
home.add-page-numbers.title=Add Page Numbers
home.add-page-numbers.desc=Add Page numbers throughout a document in a set location
home.auto-rename.title=Auto Rename PDF File
home.auto-rename.desc=Auto renames a PDF file based on its detected header
home.adjust-contrast.title=Adjust Colors/Contrast
home.adjust-contrast.desc=Adjust Contrast, Saturation and Brightness of a PDF
home.crop.title=Crop PDF
home.crop.desc=Crop a PDF to reduce its size (maintains text!)
home.autoSplitPDF.title=Auto Split Pages
home.autoSplitPDF.desc=Auto Split Scanned PDF with physical scanned page splitter QR Code
home.sanitizePdf.title=Sanitize
home.sanitizePdf.desc=Remove scripts and other elements from PDF files
###########################
# #
# WEB PAGES #
# #
###########################
#sanitizePDF
sanitizePDF.title=Sanitize PDF
sanitizePDF.header=Sanitize a PDF file
sanitizePDF.selectText.1=Remove JavaScript actions
sanitizePDF.selectText.2=Remove embedded files
sanitizePDF.selectText.3=Remove metadata
sanitizePDF.selectText.4=Remove links
sanitizePDF.selectText.5=Remove fonts
sanitizePDF.submit=Sanitize PDF
#addPageNumbers
addPageNumbers.title=Add Page Numbers
addPageNumbers.header=Add Page Numbers
addPageNumbers.selectText.1=Select PDF file:
addPageNumbers.selectText.2=Margin Size
addPageNumbers.selectText.3=Position
addPageNumbers.selectText.4=Starting Number
addPageNumbers.selectText.5=Pages to Number
addPageNumbers.selectText.6=Custom Text
addPageNumbers.submit=Add Page Numbers
#auto-rename
auto-rename.title=Auto Rename
auto-rename.header=Auto Rename PDF
auto-rename.submit=Auto Rename
#adjustContrast
adjustContrast.title=Adjust Contrast
adjustContrast.header=Adjust Contrast
adjustContrast.contrast=Contrast:
adjustContrast.brightness=Brightness:
adjustContrast.saturation=Saturation:
adjustContrast.download=Download
#crop
crop.title=Crop
crop.header=Crop Image
crop.submit=Submit
#autoSplitPDF
autoSplitPDF.title=Auto Split PDF
autoSplitPDF.header=Auto Split PDF
autoSplitPDF.description=Print, Insert, Scan, upload, and let us auto-separate your documents. No manual work sorting needed.
autoSplitPDF.selectText.1=Print out some divider sheets from below (Black and white is fine).
autoSplitPDF.selectText.2=Scan all your documents at once by inserting the divider sheet between them.
autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirling PDF handle the rest.
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
autoSplitPDF.submit=Submit
#pipeline
pipeline.title=Pipeline
#pageLayout
pageLayout.title=Diseño de varias páginas
pageLayout.header=Diseño de varias páginas
pageLayout.pagesPerSheet=Páginas por hoja:
pageLayout.submit=Entregar
#scalePages
scalePages.title=Ajustar escala de la página
scalePages.header=Adjustar escala de la página
scalePages.pageSize=Tamaño de la página del documento
scalePages.scaleFactor=Nivel de zoom (recorte) de la página
scalePages.submit=Entregar
#certSign
certSign.title=Firma de certificado
certSign.header=Firmar un PDF con su certificado (Trabajo en progreso)
certSign.selectPDF=Seleccione un archivo PDF para firmar:
@ -167,6 +298,8 @@ certSign.location=Ubicación
certSign.name=Nombre
certSign.submit=Firmar PDF
#removeBlanks
removeBlanks.title=Eliminar espacios en blanco
removeBlanks.header=Eliminar páginas en blanco
removeBlanks.threshold=Umbral:
@ -175,12 +308,16 @@ removeBlanks.whitePercent=Porcentaje de blanco (%):
removeBlanks.whitePercentDesc=Porcentaje de página que debe ser blanca para ser eliminada
removeBlanks.submit=Eliminar espacios en blanco
#compare
compare.title=Comparar
compare.header=Comparar archivos PDF
compare.document.1=Documento 1
compare.document.2=Documento 2
compare.submit=Comparar
#sign
sign.title=Firmar
sign.header=Firmar archivos PDF
sign.upload=Subir imagen
@ -189,14 +326,20 @@ sign.text=Entrada de texto
sign.clear=Borrar
sign.add=Agregar
#repair
repair.title=Reparar
repair.header=Reparar archivos PDF
repair.submit=Reparar
#flatten
flatten.title=Aplanar
flatten.header=Acoplar archivos PDF
flatten.submit=Aplanar
#ScannerImageSplit
ScannerImageSplit.selectText.1=Umbral de ángulo:
ScannerImageSplit.selectText.2=Establecer el ángulo absoluto mínimo requerido para rotar la imagen (predeterminado: 10).
ScannerImageSplit.selectText.3=Tolerancia:
@ -208,18 +351,6 @@ ScannerImageSplit.selectText.8=Establecer el umbral mínimo del área de contorn
ScannerImageSplit.selectText.9=Tamaño del borde:
ScannerImageSplit.selectText.10=Establece el tamaño del borde agregado y eliminado para evitar bordes blancos en la salida (predeterminado: 1).
navbar.settings=Ajustes
settings.title=Ajustes
settings.update=Actualización disponible
settings.appVersion=Versión de la aplicación:
settings.downloadOption.title=Elegir la opción de descarga (para descargas de un solo archivo sin ZIP):
settings.downloadOption.1=Abrir en la misma ventana
settings.downloadOption.2=Abrir en una nueva ventana
settings.downloadOption.3=Descargar el fichero
settings.zipThreshold=Ficheros ZIP cuando excede el número de ficheros descargados
#OCR
ocr.title=OCR / Escaneo de limpieza
@ -241,7 +372,7 @@ ocr.credit=Este servicio utiliza OCRmyPDF y Tesseract para OCR
ocr.submit=Procesar PDF con OCR
#extractImages
extractImages.title=Extraer imágenes
extractImages.header=Extraer imágenes
extractImages.selectText=Seleccionar el formato de imagen para convertir las imágenes extraídas
@ -281,30 +412,35 @@ merge.title=Unir
merge.header=Unir múltiples PDFs (2+)
merge.submit=Unir
#pdfOrganiser
pdfOrganiser.title=Organizador de páginas
pdfOrganiser.header=Organizador de páginas PDF
pdfOrganiser.submit=Organizar páginas
#herramienta multiple
#multiTool
multiTool.title=Multi-herramienta PDF
multiTool.header=Multi-herramienta PDF
#pageRemover
pageRemover.title=Eliminador de páginas
pageRemover.header=Eliminador de páginas PDF
pageRemover.pagesToDelete=Páginas a eliminar (introducir una lista de números de página separados por coma):
pageRemover.submit=Eliminar Páginas
#rotate
rotate.title=Rotar PDF
rotate.header=Rotar PDF
rotate.SeleccionaAngle=Seleccionar ángulo de rotación (múltiplo de 90 grados):
##########################
### TODO: Translate ###
##########################
rotate.selectAngle=Select rotation angle (in multiples of 90 degrees):
rotate.submit=Rotar
#merge
split.title=Dividir PDF
split.header=Dividir PDF
@ -330,6 +466,7 @@ imageToPDF.selectText.3=Lógica de archivos múltiples (únicamente activado si
imageToPDF.selectText.4=Unir en un único archivo PDF
imageToPDF.selectText.5=Convertir a PDFs separados
#pdfToImage
pdfToImage.title=PDF a Imagen
pdfToImage.header=PDF a Imagen
@ -343,6 +480,7 @@ pdfToImage.grey=Escala de grises
pdfToImage.blackwhite=Blanco y Negro (¡Puede perder datos!)
pdfToImage.submit=Convertir
#addPassword
addPassword.title=Añadir contraseña
addPassword.header=Añadir contraseña (encriptar)
@ -364,6 +502,7 @@ addPassword.selectText.15=Restringe qué se puede hacer con el documento una vez
addPassword.selectText.16=Restringe la apertura del propio documento
addPassword.submit=Encriptar
#watermark
watermark.title=Añadir marca de agua
watermark.header=Añadir marca de agua
@ -376,6 +515,7 @@ watermark.selectText.6=Alto (Espacio entre cada marca de agua verticalmente):
watermark.selectText.7=Opacidad (0% - 100%):
watermark.submit=Añadir marca de agua
#remove-watermark
remove-watermark.title=Eliminar marca de agua
remove-watermark.header=Eliminar marca de agua
@ -383,6 +523,7 @@ remove-watermark.selectText.1=Seleccionar PDF para eliminar la marca de agua:
remove-watermark.selectText.2=Texto de la marca de agua:
remove-watermark.submit=Eliminar marca de agua
#Change permissions
permissions.title=Cambiar permisos
permissions.header=Cambiar permisos
@ -399,6 +540,7 @@ permissions.selectText.9=Impedir imprimir
permissions.selectText.10=Impedir imprimir diferentes formatos
permissions.submit=Cambiar
#remove password
removePassword.title=Eliminar contraseña
removePassword.header=Eliminar contraseña (desencriptar)
@ -406,7 +548,9 @@ removePassword.selectText.1=Seleccionar PDF para desencriptar
removePassword.selectText.2=Contraseña
removePassword.submit=Eliminar
changeMetadata.title=Cambiar metadatos
#changeMetadata
changeMetadata.title=Título:
changeMetadata.header=Cambiar metadatos
changeMetadata.selectText.1=Editar las variables que desea cambiar
changeMetadata.selectText.2=Eliminar todos los metadatos
@ -424,27 +568,30 @@ changeMetadata.selectText.4=Otros Metadatos:
changeMetadata.selectText.5=Agregar entrada de metadatos personalizados
changeMetadata.submit=Cambiar
#xlsToPdf
xlsToPdf.title=Excel a PDF
xlsToPdf.header=Excel a PDF
xlsToPdf.selectText.1=Seleccionar hoja de cálculo de Excel XLS o XLSX para convertir
xlsToPdf.convert=Convertir
#pdfToPDFA
pdfToPDFA.title=PDF a PDF/A
pdfToPDFA.header=PDF a PDF/A
pdfToPDFA.credit=Este servicio usa OCRmyPDF para la conversión a PDF/A
pdfToPDFA.submit=Convertir
#PDFToWord
PDFToWord.title=PDF a Word
PDFToWord.header=PDF a Word
PDFToWord.selectText.1=Formato de archivo de salida
PDFToWord.credit=Este servicio utiliza LibreOffice para la conversión de archivos
PDFToWord.submit=Convertir
#PDFToPresentation
PDFToPresentation.title=PDF a presentación
PDFToPresentation.header=PDF a presentación
PDFToPresentation.selectText.1=Formato de archivo de salida
@ -452,6 +599,7 @@ PDFToPresentation.credit=Este servicio utiliza LibreOffice para la conversión d
PDFToPresentation.submit=Convertir
#PDFToText
PDFToText.title=PDF a TXT/RTF
PDFToText.header=PDF a TXT/RTF
PDFToText.selectText.1=Formato de archivo de salida
@ -459,11 +607,14 @@ PDFToText.credit=Este servicio utiliza LibreOffice para la conversión de archiv
PDFToText.submit=Convertir
#PDFToHTML
PDFToHTML.title=PDF a HTML
PDFToHTML.header=PDF a HTML
PDFToHTML.credit=Este servicio utiliza LibreOffice para la conversión de archivos
PDFToHTML.submit=Convertir
#PDFToXML
PDFToXML.title=PDF a XML
PDFToXML.header=PDF a XML
PDFToXML.credit=Este servicio utiliza LibreOffice para la conversión de archivos

View file

@ -21,22 +21,65 @@ filesSelected=Hautatutako fitxategiak
noFavourites=Ez dira gogokoak gehitu
bored=Itxaroten aspertuta?
alphabet=Alfabetoa
#############
# HOME-PAGE #
#############
home.desc=Zure leihatila bakarra autoostatatua zure PDF behar guztietarako
downloadPdf=PDFa deskargatu
text=Testua
font=Letra-tipoa
##########################
### TODO: Translate ###
##########################
selectFillter=-- Select --
pageNum=Orrialde-zenbakia
##########################
### TODO: Translate ###
##########################
sizes.small=Small
sizes.medium=Medium
sizes.large=Large
sizes.x-large=X-Large
error.pdfPassword=PDF dokumentua pasahitzarekin babestuta dago eta pasahitza ez da sartu edo akastuna da
#############
# NAVBAR #
#############
navbar.convert=Bihurtu
navbar.security=Segurtasuna
navbar.other=Beste bat
navbar.darkmode=Modu iluna
navbar.pageOps=Orrialde-eragiketak
navbar.settings=Ezarpenak
#############
# SETTINGS #
#############
settings.title=Ezarpenak
settings.update=Eguneratze eskuragarria
settings.appVersion=Aplikazioaren bertsioa:
settings.downloadOption.title=Hautatu deskargatzeko aukera (fitxategi bakarra deskargatzeko ZIP gabe):
settings.downloadOption.1=Ireki leiho berean
settings.downloadOption.2=Ireki leiho berrian
settings.downloadOption.3=Deskargatu fitxategia
settings.zipThreshold=ZIP fitxategiak deskargatutako fitxategi kopurua gainditzen denean
#############
# HOME-PAGE #
#############
home.desc=Zure leihatila bakarra autoostatatua zure PDF behar guztietarako
home.multiTool.title=Erabilera anitzeko tresna PDF
home.multiTool.desc= Orriak konbinatu, biratu, berrantolatu eta ezabatu
home.multiTool.desc=Orriak konbinatu, biratu, berrantolatu eta ezabatu
##########################
### TODO: Translate ###
##########################
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
home.merge.title=Elkartu
home.merge.desc=Elkartu zenbait PDF dokumentu bakar batean modu errazean
##########################
### TODO: Translate ###
##########################
merge.tags=merge,Page operations,Back end,server side
home.split.title=Zatitu
home.split.desc=Zatitu PDFak zenbait dokumentutan
@ -59,9 +102,6 @@ home.addImage.desc=Gehitu irudi bat PDFan ezarritako kokaleku batean (lanean)
home.watermark.title=Gehitu ur-marka
home.watermark.desc=Gehitu aurrez zehaztutako ur-marka bat PFD dokumentuari
home.remove-watermark.title= Ezabatu ur-marka
home.remove-watermark.desc= Ezabatu ur-marka PDF dokumentutik
home.permissions.title=Aldatu baimenak
home.permissions.desc=Aldatu PDF dokumentuaren baimenak
@ -122,37 +162,128 @@ home.repair.desc=Saiatu PDF hondatu/kaltetu bat konpontzen
home.removeBlanks.title=Ezabatu orrialde zuriak
home.removeBlanks.desc=Detektatu orrialde zuriak eta dokumentutik ezabatu
home.certSign.title=Sinatu ziurtagiriarekin
home.certSign.desc=Sinatu PDF bat Ziurtagiri/Gako batekin (PEM/P12)
home.compare.title=Konparatu
home.compare.desc=Konparatu eta erakutsi 2 PDF dokumenturen aldeak
home.certSign.title=Sinatu ziurtagiriarekin
home.certSign.desc=Sinatu PDF bat Ziurtagiri/Gako batekin (PEM/P12)
home.pageLayout.title=Zenbait orrialderen diseinua
home.pageLayout.desc=Elkartu orri bakar batean PDF dokumentu baten zenbait orrialde
home.scalePages.title=Eskalatu/Doitu orrialdearen tamaina
home.scalePages.desc=Eskalatu/Aldatu orrialde baten tamaina eta/edo edukia
error.pdfPassword=PDF dokumentua pasahitzarekin babestuta dago eta pasahitza ez da sartu edo akastuna da
##########################
### TODO: Translate ###
##########################
home.pipeline.title=Pipeline (Advanced)
home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts
downloadPdf=PDFa deskargatu
text=Testua
font=Letra-tipoa
selectFilter=-- Hautatu --
pageNum=Orrialde-zenbakia
home.add-page-numbers.title=Add Page Numbers
home.add-page-numbers.desc=Add Page numbers throughout a document in a set location
home.auto-rename.title=Auto Rename PDF File
home.auto-rename.desc=Auto renames a PDF file based on its detected header
home.adjust-contrast.title=Adjust Colors/Contrast
home.adjust-contrast.desc=Adjust Contrast, Saturation and Brightness of a PDF
home.crop.title=Crop PDF
home.crop.desc=Crop a PDF to reduce its size (maintains text!)
home.autoSplitPDF.title=Auto Split Pages
home.autoSplitPDF.desc=Auto Split Scanned PDF with physical scanned page splitter QR Code
home.sanitizePdf.title=Sanitize
home.sanitizePdf.desc=Remove scripts and other elements from PDF files
###########################
# #
# WEB PAGES #
# #
###########################
#sanitizePDF
sanitizePDF.title=Sanitize PDF
sanitizePDF.header=Sanitize a PDF file
sanitizePDF.selectText.1=Remove JavaScript actions
sanitizePDF.selectText.2=Remove embedded files
sanitizePDF.selectText.3=Remove metadata
sanitizePDF.selectText.4=Remove links
sanitizePDF.selectText.5=Remove fonts
sanitizePDF.submit=Sanitize PDF
#addPageNumbers
addPageNumbers.title=Add Page Numbers
addPageNumbers.header=Add Page Numbers
addPageNumbers.selectText.1=Select PDF file:
addPageNumbers.selectText.2=Margin Size
addPageNumbers.selectText.3=Position
addPageNumbers.selectText.4=Starting Number
addPageNumbers.selectText.5=Pages to Number
addPageNumbers.selectText.6=Custom Text
addPageNumbers.submit=Add Page Numbers
#auto-rename
auto-rename.title=Auto Rename
auto-rename.header=Auto Rename PDF
auto-rename.submit=Auto Rename
#adjustContrast
adjustContrast.title=Adjust Contrast
adjustContrast.header=Adjust Contrast
adjustContrast.contrast=Contrast:
adjustContrast.brightness=Brightness:
adjustContrast.saturation=Saturation:
adjustContrast.download=Download
#crop
crop.title=Crop
crop.header=Crop Image
crop.submit=Submit
#autoSplitPDF
autoSplitPDF.title=Auto Split PDF
autoSplitPDF.header=Auto Split PDF
autoSplitPDF.description=Print, Insert, Scan, upload, and let us auto-separate your documents. No manual work sorting needed.
autoSplitPDF.selectText.1=Print out some divider sheets from below (Black and white is fine).
autoSplitPDF.selectText.2=Scan all your documents at once by inserting the divider sheet between them.
autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirling PDF handle the rest.
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
autoSplitPDF.submit=Submit
#pipeline
pipeline.title=Pipeline
#pageLayout
pageLayout.title=Hainbat orrialderen diseinua
pageLayout.header=Hainbat orrialderen diseinua
pageLayout.pagesPerSheet=Orrialdeak orriko:
pageLayout.submit=Entregatu
#scalePages
scalePages.title=Doitu orrialdearen eskala
scalePages.header=Doitu orrialdearen eskala
scalePages.pageSize=Dokumentuaren orrialdearen tamaina
scalePages.scaleFactor=Orriaren zoom maila (moztea)
scalePages.submit=Entregatu
#certSign
certSign.title=Ziurtagiriaren sinadura
certSign.header=Sinatu PDF bat haren ziurtagiriarekin (lanean)
certSign.selectPDF=Hautatu PDF fitxategi bat sinatzeko:
@ -167,6 +298,8 @@ certSign.location=Kokalekua
certSign.name=Izena
certSign.submit=Sinatu PDFa
#removeBlanks
removeBlanks.title=Ezabatu zuriuneak
removeBlanks.header=Ezabatu orrialde zuriak
removeBlanks.threshold=Gutxieneko balioa:
@ -175,12 +308,16 @@ removeBlanks.whitePercent=Zuriaren protzentajea (%):
removeBlanks.whitePercentDesc=Zuria izan behar den orriaren ehunekoa ezabatua izan dadin
removeBlanks.submit=Ezabatu zuriuneak
#compare
compare.title=Konparatu
compare.header=Konparatu PDF fitxategiak
compare.document.1=1. dokumentua
compare.document.2=2. dokumentua
compare.submit=Konparatu
#sign
sign.title=Sinatu
sign.header=Sinatu PDF fitxategiak
sign.upload=Igo irudia
@ -189,14 +326,20 @@ sign.text=Testua sartzea
sign.clear=Garbitu
sign.add=Gehitu
#repair
repair.title=Konpondu
repair.header=Konpondu PDF fitxategiak
repair.submit=Konpondu
#flatten
flatten.title=Lautu
flatten.header=Akoplatu PDF fitxategiak
flatten.submit=Lautu
#ScannerImageSplit
ScannerImageSplit.selectText.1=Angeluaren gutxieneko balioa:
ScannerImageSplit.selectText.2=Ezarri eskatutako gutxieneko angelu absolutua irudia biratzeko (lehenetsia: 10).
ScannerImageSplit.selectText.3=Tolerantzia:
@ -208,18 +351,6 @@ ScannerImageSplit.selectText.8=Ezarri inguruko arearen gutxieneko balioa argazki
ScannerImageSplit.selectText.9=Ertzaren tamaina:
ScannerImageSplit.selectText.10=Ezarri gehitutako eta ezabatutako ertzaren tamaina irteeran ertz zuriak saihesteko (lehenetsia: 1).
navbar.settings=Ezarpenak
settings.title=Ezarpenak
settings.update=Eguneratze eskuragarria
settings.appVersion=Aplikazioaren bertsioa:
settings.downloadOption.title=Hautatu deskargatzeko aukera (fitxategi bakarra deskargatzeko ZIP gabe):
settings.downloadOption.1=Ireki leiho berean
settings.downloadOption.2=Ireki leiho berrian
settings.downloadOption.3=Deskargatu fitxategia
settings.zipThreshold=ZIP fitxategiak deskargatutako fitxategi kopurua gainditzen denean
#OCR
ocr.title=OCR / Garbiketa-eskaneatzea
@ -241,7 +372,7 @@ ocr.credit=Zerbitzu honek OCRmyPDF eta OCR-rako Tesseract erabiltzen ditu
ocr.submit=PDF prozesatu OCR-rekin
#extractImages
extractImages.title=Atera irudiak
extractImages.header=Atera irudiak
extractImages.selectText=Hautatu irudi-formatua ateratako irudiak bihurtzeko
@ -281,30 +412,35 @@ merge.title=Elkartu
merge.header=Elkartu zenbait PDF (2+)
merge.submit=Elkartu
#pdfOrganiser
pdfOrganiser.title=Orrialdeen antolatzailea
pdfOrganiser.header=PDF orrialdeen antolatzailea
pdfOrganiser.submit=Antolatu orrialdeak
#herramienta multiple
multiTool.title= PDF erabilera anitzeko tresna
#multiTool
multiTool.title=PDF erabilera anitzeko tresna
multiTool.header=PDF erabilera anitzeko tresna
#pageRemover
pageRemover.title=Orrialdeen ezabatzailea
pageRemover.header=PDF orrialdeen ezabatzailea
pageRemover.pagesToDelete=Ezabatu beharreko orrialdeak (sartu komaz bereizitako orrialde-zenbakien zerrenda):
pageRemover.submit=Ezabatu orrialdeak
#rotate
rotate.title=Biratu PDFa
rotate.header=Biratu PDFa
rotate.SeleccionaAngle=Hautatu errotazio-angelua (90 graduren multiploa):
##########################
### TODO: Translate ###
##########################
rotate.selectAngle=Select rotation angle (in multiples of 90 degrees):
rotate.submit=Biratu
#merge
split.title=Zatitu PDFa
split.header=Zatitu PDFa
@ -330,6 +466,7 @@ imageToPDF.selectText.3=Fitxategi askoren logika (gaituta bakarrik zenbait irudi
imageToPDF.selectText.4=Elkartu PDF bakar batean
imageToPDF.selectText.5=Bihurtu eta PDF bereizituak sortu
#pdfToImage
pdfToImage.title=PDFa irudi bihurtu
pdfToImage.header=PDFa irudi bihurtu
@ -343,6 +480,7 @@ pdfToImage.grey=Gris-eskala
pdfToImage.blackwhite=Zuria eta Beltza (Datuak galdu ditzake!)
pdfToImage.submit=Bihurtu
#addPassword
addPassword.title=Gehitu pasahitza
addPassword.header=Gehitu pasahitza (enkriptatu)
@ -364,6 +502,7 @@ addPassword.selectText.15=Mugatu zer egin daitekeen dokumentuarekin behin zabald
addPassword.selectText.16=Mugatu dokumentu bera zabaltzeko aukera
addPassword.submit=Enkriptatu
#watermark
watermark.title=Gehitu ur-marka
watermark.header=Gehitu ur-marka
@ -376,6 +515,7 @@ watermark.selectText.6=Altuera (ur-marka bakoitzaren arteko espazioa bertikalean
watermark.selectText.7=Opakutasuna (0% - 100%):
watermark.submit=Gehitu ur-marka
#remove-watermark
remove-watermark.title=Ezabatu ur-marka
remove-watermark.header=Ezabatu ur-marka
@ -383,6 +523,7 @@ remove-watermark.selectText.1=Hautatu PDFa ur-marka ezabatzeko:
remove-watermark.selectText.2=Ur-markaren testua:
remove-watermark.submit=Ezabatu ur-marka
#Change permissions
permissions.title=Aldatu baimenak
permissions.header=Aldatu baimenak
@ -399,6 +540,7 @@ permissions.selectText.9=Galarazi inprimatzea
permissions.selectText.10=Galarazi zenbait formatu inprimatzea
permissions.submit=Aldatu
#remove password
removePassword.title=Ezabatu pasahitza
removePassword.header=Ezabatu pasahitza (desenkriptatu)
@ -406,7 +548,9 @@ removePassword.selectText.1=Hautatu PDFa desenkriptatzeko
removePassword.selectText.2=Pasahitza
removePassword.submit=Ezabatu
changeMetadata.title=Aldatu metadatuak
#changeMetadata
changeMetadata.title=Izenburua:
changeMetadata.header=Aldatu metadatuak
changeMetadata.selectText.1=Editatu aldatu nahi dituzun aldagaiak
changeMetadata.selectText.2=Ezabatu metadatu guztiak
@ -424,27 +568,30 @@ changeMetadata.selectText.4=Beste metadatu batzuk:
changeMetadata.selectText.5=Gehitu metadatu pertsonalizatuen sarrera
changeMetadata.submit=Aldatu
#xlsToPdf
xlsToPdf.title=Excela PDF bihurtu
xlsToPdf.header=Excela PDF bihurtu
xlsToPdf.selectText.1=Hautatu Excel XLSren edo XLSXren kalkulu-orria bihurtzeko
xlsToPdf.convert=Bikurtu
#pdfToPDFA
pdfToPDFA.title=PDFa PDF/A bihurtu
pdfToPDFA.header=PDFa PDF/A bihurtu
pdfToPDFA.credit=Zerbitzu honek OCRmyPDF erabiltzen du PDFak PDF/A bihurtzeko
pdfToPDFA.submit=Bihurtu
#PDFToWord
PDFToWord.title=PDFa Word bihurtu
PDFToWord.header=PDFa Word bihurtu
PDFToWord.selectText.1=Irteerako fitxategiaren formatua
PDFToWord.credit=Zerbitzu honek LibreOffice erabiltzen du fitxategiak bihurtzeko
PDFToWord.submit=Bihurtu
#PDFToPresentation
PDFToPresentation.title=PDFa aurkezpen bihurtu
PDFToPresentation.header=PDFa aurkezpen bihurtu
PDFToPresentation.selectText.1=Irteerako fitxategiaren formatua
@ -452,6 +599,7 @@ PDFToPresentation.credit=Zerbitzu honek LibreOffice erabiltzen du fitxategiak bi
PDFToPresentation.submit=Bihurtu
#PDFToText
PDFToText.title=PDFa TXT/RTF bihurtu
PDFToText.header=PDFa TXT/RTF bihurtu
PDFToText.selectText.1=Irteerako fitxategiaren formatua
@ -459,11 +607,14 @@ PDFToText.credit=Zerbitzu honek LibreOffice erabiltzen du fitxategiak bihurtzeko
PDFToText.submit=Bihurtu
#PDFToHTML
PDFToHTML.title=PDFa HTML bihurtu
PDFToHTML.header=PDFa HTML bihurtu
PDFToHTML.credit=Zerbitzu honek LibreOffice erabiltzen du fitxategiak bihurtzeko
PDFToHTML.submit=Bihurtu
#PDFToXML
PDFToXML.title=PDFa XML bihurtu
PDFToXML.header=PDFa XML bihurtu
PDFToXML.credit=Zerbitzu honek LibreOffice erabiltzen du fitxategiak bihurtzeko

View file

@ -1,11 +1,7 @@
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#
# Translated by Google Translate #
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#
###########
# Generic #
###########
# the direction that the language is written (ltr=left to right, rtl=right to left)
# the direction that the language is written (ltr = left to right, rtl = right to left)
language.direction=ltr
pdfPrompt=Choisir PDF
@ -25,22 +21,65 @@ filesSelected=fichiers sélectionnés
noFavourites=Aucun favori ajouté
bored=Ennuyé d'attendre ?
alphabet=Alphabet
#############
# HOME-PAGE #
#############
home.desc=Votre guichet unique hébergé localement pour tous vos besoins PDF.
downloadPdf=Télécharger le PDF
text=Texte
font=Police
##########################
### TODO: Translate ###
##########################
selectFillter=-- Select --
pageNum=numéro de page
##########################
### TODO: Translate ###
##########################
sizes.small=Small
sizes.medium=Medium
sizes.large=Large
sizes.x-large=X-Large
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
#############
# NAVBAR #
#############
navbar.convert=Convertir
navbar.security=Sécurité
navbar.other=Autre
navbar.darkmode=Mode sombre
navbar.pageOps=Opérations de page
navbar.settings=Paramètres
#############
# SETTINGS #
#############
settings.title=Paramètres
settings.update=Mise à jour disponible
settings.appVersion=Version de l'application :
settings.downloadOption.title=Choisissez l'option de téléchargement (pour les téléchargements sans fichier unique) :
settings.downloadOption.1=Ouvrir dans la même fenêtre
settings.downloadOption.2=Ouvrir dans une nouvelle fenêtre
settings.downloadOption.3=Fichier téléchargé
settings.zipThreshold=Zip les fichiers lorsque le nombre de fichiers téléchargés dépasse
#############
# HOME-PAGE #
#############
home.desc=Votre guichet unique hébergé localement pour tous vos besoins PDF.
home.multiTool.title=Multi-outil PDF
home.multiTool.desc=Fusionner, faire pivoter, réorganiser et supprimer des pages
##########################
### TODO: Translate ###
##########################
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
home.merge.title=Fusionnez
home.merge.desc=Fusionnez facilement plusieurs PDF en un seul.
##########################
### TODO: Translate ###
##########################
merge.tags=merge,Page operations,Back end,server side
home.split.title=Fractionner
home.split.desc=Diviser les PDF en plusieurs documents
@ -63,9 +102,6 @@ home.addImage.desc=Ajoute une image à un emplacement défini sur le PDF (Travai
home.watermark.title=Ajouter un filigrane
home.watermark.desc=Ajoutez un filigrane personnalisé à votre document PDF.
home.remove-watermark.title=Supprimer le filigrane
home.remove-watermark.desc=Supprimez les filigranes de votre document PDF.
home.permissions.title=Modifier les autorisations
home.permissions.desc=Modifier les permissions de votre document PDF
@ -84,7 +120,6 @@ home.compressPdfs.desc=Compressez les PDF pour réduire leur taille de fichier.
home.changeMetadata.title=Modifier les métadonnées
home.changeMetadata.desc=Modifier/Supprimer/Ajouter des métadonnées d'un document PDF
home.fileToPDF.title=Convertir un fichier en PDF
home.fileToPDF.desc=Convertissez presque n\u2019importe quel fichier en PDF (DOCX, PNG, XLS, PPT, TXT et plus)
@ -94,7 +129,6 @@ home.ocr.desc=Le nettoyage analyse et détecte le texte des images dans un PDF e
home.extractImages.title=Extraire les images
home.extractImages.desc=Extrait toutes les images d\u2019un PDF et les enregistre au format zip
home.pdfToPDFA.title=Convertir PDF en PDF/A
home.pdfToPDFA.desc=Convertir un PDF en PDF/A pour un stockage à long terme
@ -128,37 +162,128 @@ home.repair.desc=Essaye de réparer un PDF corrompu/cassé
home.removeBlanks.title=Supprimer les pages vierges
home.removeBlanks.desc=Détecte et supprime les pages vierges d'un document
home.certSign.title=Sign with Certificate
home.certSign.desc=Signs a PDF with a Certificate/Key (PEM/P12)
home.compare.title=Comparer
home.compare.desc=Compare et affiche les différences entre 2 documents PDF
home.certSign.title=Sign with Certificate
home.certSign.desc=Signs a PDF with a Certificate/Key (PEM/P12)
home.pageLayout.title=Multi-Page Layout
home.pageLayout.desc=Merge multiple pages of a PDF document into a single page
home.scalePages.title=Adjust page size/scale
home.scalePages.desc=Change the size/scale of page and/or its contents.
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
##########################
### TODO: Translate ###
##########################
home.pipeline.title=Pipeline (Advanced)
home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts
downloadPdf=Télécharger le PDF
text=Texte
font=Police
selectFilter=-- Sélectionner --
pageNum=numéro de page
home.add-page-numbers.title=Add Page Numbers
home.add-page-numbers.desc=Add Page numbers throughout a document in a set location
home.auto-rename.title=Auto Rename PDF File
home.auto-rename.desc=Auto renames a PDF file based on its detected header
home.adjust-contrast.title=Adjust Colors/Contrast
home.adjust-contrast.desc=Adjust Contrast, Saturation and Brightness of a PDF
home.crop.title=Crop PDF
home.crop.desc=Crop a PDF to reduce its size (maintains text!)
home.autoSplitPDF.title=Auto Split Pages
home.autoSplitPDF.desc=Auto Split Scanned PDF with physical scanned page splitter QR Code
home.sanitizePdf.title=Sanitize
home.sanitizePdf.desc=Remove scripts and other elements from PDF files
###########################
# #
# WEB PAGES #
# #
###########################
#sanitizePDF
sanitizePDF.title=Sanitize PDF
sanitizePDF.header=Sanitize a PDF file
sanitizePDF.selectText.1=Remove JavaScript actions
sanitizePDF.selectText.2=Remove embedded files
sanitizePDF.selectText.3=Remove metadata
sanitizePDF.selectText.4=Remove links
sanitizePDF.selectText.5=Remove fonts
sanitizePDF.submit=Sanitize PDF
#addPageNumbers
addPageNumbers.title=Add Page Numbers
addPageNumbers.header=Add Page Numbers
addPageNumbers.selectText.1=Select PDF file:
addPageNumbers.selectText.2=Margin Size
addPageNumbers.selectText.3=Position
addPageNumbers.selectText.4=Starting Number
addPageNumbers.selectText.5=Pages to Number
addPageNumbers.selectText.6=Custom Text
addPageNumbers.submit=Add Page Numbers
#auto-rename
auto-rename.title=Auto Rename
auto-rename.header=Auto Rename PDF
auto-rename.submit=Auto Rename
#adjustContrast
adjustContrast.title=Adjust Contrast
adjustContrast.header=Adjust Contrast
adjustContrast.contrast=Contrast:
adjustContrast.brightness=Brightness:
adjustContrast.saturation=Saturation:
adjustContrast.download=Download
#crop
crop.title=Crop
crop.header=Crop Image
crop.submit=Submit
#autoSplitPDF
autoSplitPDF.title=Auto Split PDF
autoSplitPDF.header=Auto Split PDF
autoSplitPDF.description=Print, Insert, Scan, upload, and let us auto-separate your documents. No manual work sorting needed.
autoSplitPDF.selectText.1=Print out some divider sheets from below (Black and white is fine).
autoSplitPDF.selectText.2=Scan all your documents at once by inserting the divider sheet between them.
autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirling PDF handle the rest.
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
autoSplitPDF.submit=Submit
#pipeline
pipeline.title=Pipeline
#pageLayout
pageLayout.title=Multi Page Layout
pageLayout.header=Multi Page Layout
pageLayout.pagesPerSheet=Pages per sheet:
pageLayout.submit=Submit
#scalePages
scalePages.title=Adjust page-scale
scalePages.header=Adjust page-scale
scalePages.pageSize=Size of a page of the document.
scalePages.scaleFactor=Zoom level (crop) of a page.
scalePages.submit=Submit
#certSign
certSign.title=Signature du certificat
certSign.header=Signer un PDF avec votre certificat (Travail en cours)
certSign.selectPDF=Sélectionnez un fichier PDF à signer :
@ -173,6 +298,8 @@ certSign.location=Emplacement
certSign.name=Nom
certSign.submit=Signer le PDF
#removeBlanks
removeBlanks.title=Supprimer les blancs
removeBlanks.header=Supprimer les pages vierges
removeBlanks.threshold=Seuil :
@ -181,12 +308,16 @@ removeBlanks.whitePercent=Pourcentage blanc (%) :
removeBlanks.whitePercentDesc=Pourcentage de page qui doit être blanche pour être supprimée
removeBlanks.submit=Supprimer les blancs
#compare
compare.title=Comparer
compare.header=Comparer des PDF
compare.document.1=Document 1
compare.document.2=Document 2
compare.submit=Comparer
#sign
sign.title=Signe
sign.header=Signer des PDF
sign.upload=Télécharger l'image
@ -195,14 +326,20 @@ sign.text=Saisie de texte
sign.clear=Effacer
sign.add=Ajouter
#repair
repair.title=Réparer
repair.header=Réparer les PDF
repair.submit=Réparer
#flatten
flatten.title=Aplatir
flatten.header=Aplatir les PDF
flatten.submit=Aplatir
#ScannerImageSplit
ScannerImageSplit.selectText.1=Seuil d'angle :
ScannerImageSplit.selectText.2=Définit l'angle absolu minimum requis pour la rotation de l'image (par défaut : 10).
ScannerImageSplit.selectText.3=Tolérance :
@ -214,16 +351,6 @@ ScannerImageSplit.selectText.8=Définit le seuil de zone de contour minimum pour
ScannerImageSplit.selectText.9=Taille de la bordure :
ScannerImageSplit.selectText.10=Définit la taille de la bordure ajoutée et supprimée pour éviter les bordures blanches dans la sortie (par défaut : 1).
navbar.settings=Paramètres
settings.title=Paramètres
settings.update=Mise à jour disponible
settings.appVersion=Version de l'application :
settings.downloadOption.title=Choisissez l'option de téléchargement (pour les téléchargements sans fichier unique) :
settings.downloadOption.1=Ouvrir dans la même fenêtre
settings.downloadOption.2=Ouvrir dans une nouvelle fenêtre
settings.downloadOption.3=Fichier téléchargé
settings.zipThreshold=Zip les fichiers lorsque le nombre de fichiers téléchargés dépasse
#OCR
ocr.title=OCR / Nettoyage de numérisation
@ -245,11 +372,13 @@ ocr.credit=Ce service utilise OCRmyPDF et Tesseract pour l'OCR.
ocr.submit=Traiter PDF avec OCR
#extractImages
extractImages.title=Extraire les images
extractImages.header=Extraire les images
extractImages.selectText=Sélectionner le format d'image pour convertir les images extraites en
extractImages.submit=Extraire
#File to PDF
fileToPDF.title=Fichier au format PDF
fileToPDF.header=Convertir n'importe quel fichier au format PDF
@ -258,14 +387,6 @@ fileToPDF.supportedFileTypes=Les types de fichiers pris en charge doivent inclur
fileToPDF.submit=Convertir en PDF
#Add image
addImage.title=Ajouter une image
addImage.header=Ajouter une image au PDF
addImage.everyPage=Chaque page?
addImage.upload=Ajouter une image
addImage.submit=Ajouter une image
#compress
compress.title=Compresser
compress.header=Compresser le PDF
@ -278,17 +399,27 @@ compress.selectText.5=Taille PDF attendue (par exemple, 25 Mo, 10,8 Mo, 25 Ko
compress.submit=Compresser
#Add image
addImage.title=Ajouter une image
addImage.header=Ajouter une image au PDF
addImage.everyPage=Chaque page?
addImage.upload=Ajouter une image
addImage.submit=Ajouter une image
#merge
merge.title=Fusionner
merge.header=Fusionner plusieurs PDF (2+)
merge.submit=Fusionner
#pdfOrganiser
pdfOrganiser.title=Organisateur de pages
pdfOrganiser.header=Organisateur de pages PDF
pdfOrganiser.submit=Réorganiser les pages
#Outil Multi-fonction
#multiTool
multiTool.title=Multi-outil PDF
multiTool.header=Outil multiple PDF
@ -299,13 +430,15 @@ pageRemover.header=Outil de suppression de pages PDF
pageRemover.pagesToDelete=Pages à supprimer (Entrez une liste de numéros de page séparés par des virgules):
pageRemover.submit=Supprimer des pages
#rotate
rotate.title=Faire pivoter le PDF
rotate.header=Faire pivoter le PDF
rotate.selectAngle=Sélectionner l'angle de rotation (en multiples de 90 degrés) :
rotate.submit=Rotation
#Split PDF
#merge
split.title=Fractionner le PDF
split.header=Diviser le PDF
split.desc.1=Les numéros que vous sélectionnez sont le numéro de page sur lequel vous souhaitez faire un fractionnement.
@ -319,7 +452,8 @@ split.desc.8=Document #6 : Pages 9 et 10
split.splitPages=Entrez les pages sur lesquelles fractionner :
split.submit=Diviser
#imageToPDF
#merge
imageToPDF.title=Image au format PDF
imageToPDF.header=Image au format PDF
imageToPDF.submit=Convertir
@ -329,7 +463,8 @@ imageToPDF.selectText.3=Logique de fichiers multiples (activé uniquement si vou
imageToPDF.selectText.4=Fusionner en un seul PDF
imageToPDF.selectText.5=Convertir en PDFs distincts
#PDF to Image
#pdfToImage
pdfToImage.title=PDF vers image
pdfToImage.header=PDF vers image
pdfToImage.selectText=Format d'image
@ -342,6 +477,7 @@ pdfToImage.grey=Niveaux de gris
pdfToImage.blackwhite=Noir et Blanc (Peut perdre des données !)
pdfToImage.submit=Convertir
#addPassword
addPassword.title=Ajouter un mot de passe
addPassword.header=Ajouter un mot de passe (chiffrer)
@ -363,6 +499,7 @@ addPassword.selectText.15=Restricts what can be done with the document once it i
addPassword.selectText.16=Restricts the opening of the document itself
addPassword.submit=Crypter
#watermark
watermark.title=Ajouter un filigrane
watermark.header=Ajouter un filigrane
@ -375,6 +512,7 @@ watermark.selectText.6=heightSpacer (Espace entre chaque filigrane verticalement
watermark.selectText.7=Opacité (0 % - 100 %) :
watermark.submit=Ajouter un filigrane
#remove-watermark
remove-watermark.title=Supprimer le filigrane
remove-watermark.header=Supprimer le filigrane
@ -382,7 +520,8 @@ remove-watermark.selectText.1=Sélectionnez le PDF pour supprimer le filigrane :
remove-watermark.selectText.2=Texte du filigrane :
remove-watermark.submit=Supprimer le filigrane
#Change Permissions
#Change permissions
permissions.title=Modifier les autorisations
permissions.header=Modifier les autorisations
permissions.warning=Attention pour que ces permissions soient immuables il est recommandé de les définir avec un mot de passe via la page add-password.
@ -398,15 +537,17 @@ permissions.selectText.9=Employer pour l'impression
permissions.selectText.10=Empêcher l'impression de différents formats
permissions.submit=Modificateur
#supprimer le mot de passe
#remove password
removePassword.title=Supprimer le mot de passe
removePassword.header=Supprimer le mot de passe (Déchiffrer)
removePassword.selectText.1=Sélectionnez le PDF à déchiffrer
removePassword.selectText.2=Mot de passe
removePassword.submit=Supprimer
#Change Metadata
changeMetadata.title=Modifier les métadonnées
#changeMetadata
changeMetadata.title=Titre :
changeMetadata.header=Modifier les métadonnées
changeMetadata.selectText.1=Veuillez modifier les variables que vous souhaitez modifier.
changeMetadata.selectText.2=Supprimer toutes les métadonnées.
@ -424,26 +565,30 @@ changeMetadata.selectText.4=Autres métadonnées :
changeMetadata.selectText.5=Ajouter une entrée de métadonnées personnalisées
changeMetadata.submit=Modifier
#XLS to PDF
#xlsToPdf
xlsToPdf.title=Excel vers PDF
xlsToPdf.header=Excel en PDF
xlsToPdf.selectText.1=Sélectionnez une feuille Excel XLS ou XLSX à convertir.
xlsToPdf.convert=Convertir
#pdfToPDFA
pdfToPDFA.title=PDF vers PDF/A
pdfToPDFA.header=PDF vers PDF/A
pdfToPDFA.credit=Ce service utilise OCRmyPDF pour la conversion PDF/A
pdfToPDFA.submit=Convertir
#PDFToWord
PDFToWord.title=PDF vers Word
PDFToWord.header=PDF vers Word
PDFToWord.selectText.1=Format du fichier de sortie
PDFToWord.credit=Ce service utilise LibreOffice pour la conversion de fichiers.
PDFToWord.submit=Convertir
#PDFToPresentation
PDFToPresentation.title=PDF vers présentation
PDFToPresentation.header=PDF vers présentation
PDFToPresentation.selectText.1=Format du fichier de sortie
@ -451,6 +596,7 @@ PDFToPresentation.credit=Ce service utilise LibreOffice pour la conversion de fi
PDFToPresentation.submit=Convertir
#PDFToText
PDFToText.title=PDF vers Texte/RTF
PDFToText.header=PDF vers texte/RTF
PDFToText.selectText.1=Format du fichier de sortie
@ -458,14 +604,15 @@ PDFToText.credit=Ce service utilise LibreOffice pour la conversion de fichiers.
PDFToText.submit=Convertir
#PDFToHTML
PDFToHTML.title=PDF vers HTML
PDFToHTML.header=PDF vers HTML
PDFToHTML.credit=Ce service utilise LibreOffice pour la conversion de fichiers.
PDFToHTML.submit=Convertir
#PDFToXML
PDFToXML.title=PDF vers XML
PDFToXML.header=PDF vers XML
PDFToXML.credit=Ce service utilise LibreOffice pour la conversion de fichiers.
PDFToXML.submit=Convertir

View file

@ -21,23 +21,62 @@ filesSelected=file selezionati
noFavourites=Nessun preferito
bored=Stanco di aspettare?
alphabet=Alfabeto
downloadPdf=Scarica PDF
text=Testo
font=Font
selectFillter=-- Seleziona --
pageNum=Numero pagina
##########################
### TODO: Translate ###
##########################
sizes.small=Small
sizes.medium=Medium
sizes.large=Large
sizes.x-large=X-Large
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
#############
# NAVBAR #
#############
navbar.convert=Converti
navbar.security=Sicurezza
navbar.other=Altro
navbar.darkmode=Modalità Scura
navbar.pageOps=Modifica pagine
navbar.settings=Impostazioni
#############
# SETTINGS #
#############
settings.title=Impostazioni
settings.update=Aggiornamento disponibile
settings.appVersion=Versione App:
settings.downloadOption.title=Scegli opzione di download (Per file singoli non compressi):
settings.downloadOption.1=Apri in questa finestra
settings.downloadOption.2=Apri in una nuova finestra
settings.downloadOption.3=Scarica file
settings.zipThreshold=Comprimi file in .zip quando il numero di download supera
#############
# HOME-PAGE #
#############
home.desc=La tua pagina self-hostata per gestire qualsiasi PDF.
navbar.convert=Converti
navbar.security=Sicurezza
navbar.other=Altro
navbar.darkmode=Modalità Scura
navbar.pageOps=Modifica pagine
home.multiTool.title=Multifunzione PDF
home.multiTool.desc=Unisci, Ruota, Riordina, e Rimuovi pagine
##########################
### TODO: Translate ###
##########################
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
home.merge.title=Unisci
home.merge.desc=Unisci facilmente più PDF in uno.
##########################
### TODO: Translate ###
##########################
merge.tags=merge,Page operations,Back end,server side
home.split.title=Dividi
home.split.desc=Dividi un singolo PDF in più documenti.
@ -60,9 +99,6 @@ home.addImage.desc=Aggiungi un'immagine in un punto specifico del PDF (Work in p
home.watermark.title=Aggiungi Filigrana
home.watermark.desc=Aggiungi una filigrana al tuo PDF.
home.remove-watermark.title=Rimuovi Filigrana
home.remove-watermark.desc=Rimuovi la filigrana dal tuo PDF.
home.permissions.title=Cambia Permessi
home.permissions.desc=Cambia i permessi del tuo PDF.
@ -123,37 +159,127 @@ home.repair.desc=Prova a riparare un PDF corrotto.
home.removeBlanks.title=Rimuovi pagine vuote
home.removeBlanks.desc=Trova e rimuovi pagine vuote da un PDF.
home.certSign.title=Sign with Certificate
home.certSign.desc=Signs a PDF with a Certificate/Key (PEM/P12)
home.compare.title=Compara
home.compare.desc=Vedi e compara le differenze tra due PDF.
home.certSign.title=Sign with Certificate
home.certSign.desc=Signs a PDF with a Certificate/Key (PEM/P12)
home.pageLayout.title=Multi-Page Layout
home.pageLayout.desc=Merge multiple pages of a PDF document into a single page
home.scalePages.title=Adjust page size/scale
home.scalePages.desc=Change the size/scale of page and/or its contents.
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
##########################
### TODO: Translate ###
##########################
home.pipeline.title=Pipeline (Advanced)
home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts
downloadPdf=Scarica PDF
text=Testo
font=Font
selectFillter=-- Seleziona --
pageNum=Numero pagina
home.add-page-numbers.title=Add Page Numbers
home.add-page-numbers.desc=Add Page numbers throughout a document in a set location
home.auto-rename.title=Auto Rename PDF File
home.auto-rename.desc=Auto renames a PDF file based on its detected header
home.adjust-contrast.title=Adjust Colors/Contrast
home.adjust-contrast.desc=Adjust Contrast, Saturation and Brightness of a PDF
home.crop.title=Crop PDF
home.crop.desc=Crop a PDF to reduce its size (maintains text!)
home.autoSplitPDF.title=Auto Split Pages
home.autoSplitPDF.desc=Auto Split Scanned PDF with physical scanned page splitter QR Code
home.sanitizePdf.title=Sanitize
home.sanitizePdf.desc=Remove scripts and other elements from PDF files
###########################
# #
# WEB PAGES #
# #
###########################
#sanitizePDF
sanitizePDF.title=Sanitize PDF
sanitizePDF.header=Sanitize a PDF file
sanitizePDF.selectText.1=Remove JavaScript actions
sanitizePDF.selectText.2=Remove embedded files
sanitizePDF.selectText.3=Remove metadata
sanitizePDF.selectText.4=Remove links
sanitizePDF.selectText.5=Remove fonts
sanitizePDF.submit=Sanitize PDF
#addPageNumbers
addPageNumbers.title=Add Page Numbers
addPageNumbers.header=Add Page Numbers
addPageNumbers.selectText.1=Select PDF file:
addPageNumbers.selectText.2=Margin Size
addPageNumbers.selectText.3=Position
addPageNumbers.selectText.4=Starting Number
addPageNumbers.selectText.5=Pages to Number
addPageNumbers.selectText.6=Custom Text
addPageNumbers.submit=Add Page Numbers
#auto-rename
auto-rename.title=Auto Rename
auto-rename.header=Auto Rename PDF
auto-rename.submit=Auto Rename
#adjustContrast
adjustContrast.title=Adjust Contrast
adjustContrast.header=Adjust Contrast
adjustContrast.contrast=Contrast:
adjustContrast.brightness=Brightness:
adjustContrast.saturation=Saturation:
adjustContrast.download=Download
#crop
crop.title=Crop
crop.header=Crop Image
crop.submit=Submit
#autoSplitPDF
autoSplitPDF.title=Auto Split PDF
autoSplitPDF.header=Auto Split PDF
autoSplitPDF.description=Print, Insert, Scan, upload, and let us auto-separate your documents. No manual work sorting needed.
autoSplitPDF.selectText.1=Print out some divider sheets from below (Black and white is fine).
autoSplitPDF.selectText.2=Scan all your documents at once by inserting the divider sheet between them.
autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirling PDF handle the rest.
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
autoSplitPDF.submit=Submit
#pipeline
pipeline.title=Pipeline
#pageLayout
pageLayout.title=Multi Page Layout
pageLayout.header=Multi Page Layout
pageLayout.pagesPerSheet=Pages per sheet:
pageLayout.submit=Submit
#scalePages
scalePages.title=Adjust page-scale
scalePages.header=Adjust page-scale
scalePages.pageSize=Size of a page of the document.
scalePages.scaleFactor=Zoom level (crop) of a page.
scalePages.submit=Submit
#certSign
certSign.title=Firma del certificato
certSign.header=Firma un PDF con il tuo certificato (Lavoro in corso)
certSign.selectPDF=Seleziona un file PDF per la firma:
@ -168,6 +294,8 @@ certSign.location=Posizione
certSign.name=Nome
certSign.submit=Firma PDF
#removeBlanks
removeBlanks.title=Rimuovi spazi vuoti
removeBlanks.header=Rimuovi pagine vuote
removeBlanks.threshold=Soglia:
@ -176,12 +304,16 @@ removeBlanks.whitePercent=Percentuale di bianco (%):
removeBlanks.whitePercentDesc=Percentuale della pagina che deve essere bianca per venire rimossa
removeBlanks.submit=Rimuovi
#compare
compare.title=Compara
compare.header=Compara PDF
compare.document.1=Documento 1
compare.document.2=Documento 2
compare.submit=Compara
#sign
sign.title=Firma
sign.header=Firma PDF
sign.upload=Carica immagine
@ -190,14 +322,20 @@ sign.text=Testo
sign.clear=Cancella
sign.add=Aggiungi
#repair
repair.title=Ripara
repair.header=Ripara PDF
repair.submit=Ripara
#flatten
flatten.title=Appiattisci
flatten.header=Appiattisci PDF
flatten.submit=Appiattisci
#ScannerImageSplit
ScannerImageSplit.selectText.1=Soglia angolo:
ScannerImageSplit.selectText.2=Imposta il minimo angolo richiesto perché l'immagine venga ruotata (default: 10).
ScannerImageSplit.selectText.3=Tolleranza:
@ -209,19 +347,6 @@ ScannerImageSplit.selectText.8=Imposta l'area minima del contorno di una foto
ScannerImageSplit.selectText.9=Spessore bordo:
ScannerImageSplit.selectText.10=Imposta lo spessore del bordo aggiunto o rimosso per prevenire bordi bianchi nel risultato (default: 1).
navbar.settings=Impostazioni
settings.title=Impostazioni
settings.update=Aggiornamento disponibile
settings.appVersion=Versione App:
settings.downloadOption.title=Scegli opzione di download (Per file singoli non compressi):
settings.downloadOption.1=Apri in questa finestra
settings.downloadOption.2=Apri in una nuova finestra
settings.downloadOption.3=Scarica file
settings.zipThreshold=Comprimi file in .zip quando il numero di download supera
#OCR
ocr.title=OCR / Pulisci scansioni
@ -243,7 +368,7 @@ ocr.credit=Questo servizio utilizza OCRmyPDF e Tesseract per l'OCR.
ocr.submit=Scansiona testo nel PDF con OCR
#extractImages
extractImages.title=Estrai immagini
extractImages.header=Estrai immagini
extractImages.selectText=Seleziona il formato in cui salvare le immagini estratte
@ -269,6 +394,7 @@ compress.selectText.4=Modalità automatica - Regola automaticamente la qualità
compress.selectText.5=Dimensioni PDF previste (ad es. 25 MB, 10,8 MB, 25 KB)
compress.submit=Comprimi
#Add image
addImage.title=Aggiungi Immagine
addImage.header=Aggiungi un'immagine ad un PDF
@ -282,11 +408,13 @@ merge.title=Unisci
merge.header=Unisci 2 o più PDF
merge.submit=Unisci
#pdfOrganiser
pdfOrganiser.title=Organizza pagine
pdfOrganiser.header=Organizza le pagine di un PDF
pdfOrganiser.submit=Riordina pagine
#multiTool
multiTool.title=Multifunzione PDF
multiTool.header=Multifunzione PDF
@ -298,6 +426,7 @@ pageRemover.header=Rimuovi pagine da un PDF
pageRemover.pagesToDelete=Pagine da eliminare (inserisci una lista di numeri separati da virgola):
pageRemover.submit=Rimuovi pagine
#rotate
rotate.title=Ruota PDF
rotate.header=Ruota PDF
@ -305,9 +434,7 @@ rotate.selectAngle=Scegli angolo di rotazione (in multipli di 90 gradi):
rotate.submit=Ruota
#split
#merge
split.title=Dividi PDF
split.header=Dividi PDF
split.desc.1=I numeri che scegli sono le pagine a cui desideri dividere il documento
@ -322,7 +449,7 @@ split.splitPages=Inserisci pagine a cui dividere:
split.submit=Dividi
#imageToPDF
#merge
imageToPDF.title=Immagine a PDF
imageToPDF.header=Immagine a PDF
imageToPDF.submit=Converti
@ -332,6 +459,7 @@ imageToPDF.selectText.3=Logica multi-file (funziona solo se ci sono più immagin
imageToPDF.selectText.4=Unisci in un unico PDF
imageToPDF.selectText.5=Converti in PDF separati
#pdfToImage
pdfToImage.title=PDF a immagine
pdfToImage.header=PDF a immagine
@ -345,6 +473,7 @@ pdfToImage.grey=Scala di grigi
pdfToImage.blackwhite=Bianco e Nero (potresti perdere dettagli!)
pdfToImage.submit=Converti
#addPassword
addPassword.title=Aggiungi Password
addPassword.header=Aggiungi password (crittografa)
@ -366,6 +495,7 @@ addPassword.selectText.15=Restricts what can be done with the document once it i
addPassword.selectText.16=Restricts the opening of the document itself
addPassword.submit=Crittografa
#watermark
watermark.title=Aggiungi Filigrana
watermark.header=Aggiungi filigrana
@ -378,6 +508,7 @@ watermark.selectText.6=spazio verticale (tra ogni filigrana):
watermark.selectText.7=Opacità (0% - 100%):
watermark.submit=Aggiungi Filigrana
#remove-watermark
remove-watermark.title=Rimuovi Filigrana
remove-watermark.header=Rimuovi filigrana
@ -385,6 +516,7 @@ remove-watermark.selectText.1=Seleziona PDF da cui rimuovere la filigrana:
remove-watermark.selectText.2=Testo:
remove-watermark.submit=Rimuovi Filigrana
#Change permissions
permissions.title=Cambia Permessi
permissions.header=Cambia permessi
@ -401,6 +533,7 @@ permissions.selectText.9=Previeni stampa
permissions.selectText.10=Previeni stampa in diversi formati
permissions.submit=Cambia Permessi
#remove password
removePassword.title=Rimuovi Password
removePassword.header=Rimuovi password (de-crittografa)
@ -408,7 +541,9 @@ removePassword.selectText.1=Seleziona PDF da decrittare
removePassword.selectText.2=Password
removePassword.submit=Rimuovi Password
changeMetadata.title=Cambia Proprietà
#changeMetadata
changeMetadata.title=Titolo:
changeMetadata.header=Cambia Proprietà
changeMetadata.selectText.1=Imposta i dati che vuoi cambiare
changeMetadata.selectText.2=Cancella tutte le proprietà
@ -426,27 +561,30 @@ changeMetadata.selectText.4=Altre proprietà:
changeMetadata.selectText.5=Aggiungi proprietà personalizzata:
changeMetadata.submit=Cambia Proprietà
#xlsToPdf
xlsToPdf.title=Da Excel a PDF
xlsToPdf.header=Da Excel a PDF
xlsToPdf.selectText.1=Seleziona un foglio XLS o XLSX da convertire
xlsToPdf.convert=Converti
#pdfToPDFA
pdfToPDFA.title=Da PDF a PDF/A
pdfToPDFA.header=Da PDF a PDF/A
pdfToPDFA.credit=Questo servizio utilizza OCRmyPDF per la conversione in PDF/A.
pdfToPDFA.submit=Converti
#PDFToWord
PDFToWord.title=Da PDF a Word
PDFToWord.header=Da PDF a Word
PDFToWord.selectText.1=Formato file di output
PDFToWord.credit=Questo servizio utilizza LibreOffice per la conversione.
PDFToWord.submit=Converti
#PDFToPresentation
PDFToPresentation.title=Da PDF a presentazione
PDFToPresentation.header=Da PDF a presentazione
PDFToPresentation.selectText.1=Formato file di output
@ -454,6 +592,7 @@ PDFToPresentation.credit=Questo servizio utilizza LibreOffice per la conversione
PDFToPresentation.submit=Converti
#PDFToText
PDFToText.title=Da PDF a testo/RTF
PDFToText.header=Da PDF a testo/RTF
PDFToText.selectText.1=Formato file di output
@ -461,11 +600,14 @@ PDFToText.credit=Questo servizio utilizza LibreOffice per la conversione.
PDFToText.submit=Converti
#PDFToHTML
PDFToHTML.title=Da PDF a HTML
PDFToHTML.header=Da PDF a HTML
PDFToHTML.credit=Questo servizio utilizza LibreOffice per la conversione.
PDFToHTML.submit=Converti
#PDFToXML
PDFToXML.title=Da PDF a XML
PDFToXML.header=Da PDF a XML
PDFToXML.credit=Questo servizio utilizza LibreOffice per la conversione.

View file

@ -21,23 +21,62 @@ filesSelected=개 파일 선택됨
noFavourites=즐겨찾기 없음
bored=기다리는 게 지루하신가요?
alphabet=\uC54C\uD30C\uBCB3
downloadPdf=PDF 다운로드
text=텍스트
font=폰트
selectFillter=-- 선택 --
pageNum=페이지 번호
##########################
### TODO: Translate ###
##########################
sizes.small=Small
sizes.medium=Medium
sizes.large=Large
sizes.x-large=X-Large
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
#############
# NAVBAR #
#############
navbar.convert=변환
navbar.security=보안
navbar.other=기타
navbar.darkmode=다크 모드
navbar.pageOps=Page Operations
navbar.settings=설정
#############
# SETTINGS #
#############
settings.title=설정
settings.update=업데이트 가능
settings.appVersion=앱 버전:
settings.downloadOption.title=다운로드 옵션 선택 (zip 파일이 아닌 단일 파일 다운로드 시):
settings.downloadOption.1=현재 창에서 열기
settings.downloadOption.2=새 창에서 열기
settings.downloadOption.3=다운로드
settings.zipThreshold=다운로드한 파일 수가 초과된 경우 파일 압축하기
#############
# HOME-PAGE #
#############
home.desc=당신의 PDF에 필요한 모든 것이 있는 로컬 호스팅된 원스톱 숍입니다.
navbar.convert=변환
navbar.security=보안
navbar.other=기타
navbar.darkmode=다크 모드
navbar.pageOps=Page Operations
home.multiTool.title=PDF 멀티 툴
home.multiTool.desc=페이지를 병합, 회전, 재배열, 제거하세요.
##########################
### TODO: Translate ###
##########################
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
home.merge.title=병합
home.merge.desc=여러 개의 PDF를 쉽게 하나로 합치세요.
##########################
### TODO: Translate ###
##########################
merge.tags=merge,Page operations,Back end,server side
home.split.title=분할
home.split.desc=PDF를 여러 개의 문서로 분할하세요.
@ -60,9 +99,6 @@ home.addImage.desc=PDF의 설정된 위치에 이미지를 추가하세요.(개
home.watermark.title=워터마크 추가
home.watermark.desc=PDF 문서에 사용자 지정 워터마크를 추가하세요.
home.remove-watermark.title=워터마크 제거
home.remove-watermark.desc=PDF 문서에서 워터마크를 제거하세요.
home.permissions.title=권한 변경
home.permissions.desc=PDF 문서의 권한을 변경하세요.
@ -135,25 +171,116 @@ home.pageLayout.desc=Merge multiple pages of a PDF document into a single page
home.scalePages.title=Adjust page size/scale
home.scalePages.desc=Change the size/scale of page and/or its contents.
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
##########################
### TODO: Translate ###
##########################
home.pipeline.title=Pipeline (Advanced)
home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts
downloadPdf=PDF 다운로드
text=텍스트
font=폰트
selectFillter=-- 선택 --
pageNum=페이지 번호
home.add-page-numbers.title=Add Page Numbers
home.add-page-numbers.desc=Add Page numbers throughout a document in a set location
home.auto-rename.title=Auto Rename PDF File
home.auto-rename.desc=Auto renames a PDF file based on its detected header
home.adjust-contrast.title=Adjust Colors/Contrast
home.adjust-contrast.desc=Adjust Contrast, Saturation and Brightness of a PDF
home.crop.title=Crop PDF
home.crop.desc=Crop a PDF to reduce its size (maintains text!)
home.autoSplitPDF.title=Auto Split Pages
home.autoSplitPDF.desc=Auto Split Scanned PDF with physical scanned page splitter QR Code
home.sanitizePdf.title=Sanitize
home.sanitizePdf.desc=Remove scripts and other elements from PDF files
###########################
# #
# WEB PAGES #
# #
###########################
#sanitizePDF
sanitizePDF.title=Sanitize PDF
sanitizePDF.header=Sanitize a PDF file
sanitizePDF.selectText.1=Remove JavaScript actions
sanitizePDF.selectText.2=Remove embedded files
sanitizePDF.selectText.3=Remove metadata
sanitizePDF.selectText.4=Remove links
sanitizePDF.selectText.5=Remove fonts
sanitizePDF.submit=Sanitize PDF
#addPageNumbers
addPageNumbers.title=Add Page Numbers
addPageNumbers.header=Add Page Numbers
addPageNumbers.selectText.1=Select PDF file:
addPageNumbers.selectText.2=Margin Size
addPageNumbers.selectText.3=Position
addPageNumbers.selectText.4=Starting Number
addPageNumbers.selectText.5=Pages to Number
addPageNumbers.selectText.6=Custom Text
addPageNumbers.submit=Add Page Numbers
#auto-rename
auto-rename.title=Auto Rename
auto-rename.header=Auto Rename PDF
auto-rename.submit=Auto Rename
#adjustContrast
adjustContrast.title=Adjust Contrast
adjustContrast.header=Adjust Contrast
adjustContrast.contrast=Contrast:
adjustContrast.brightness=Brightness:
adjustContrast.saturation=Saturation:
adjustContrast.download=Download
#crop
crop.title=Crop
crop.header=Crop Image
crop.submit=Submit
#autoSplitPDF
autoSplitPDF.title=Auto Split PDF
autoSplitPDF.header=Auto Split PDF
autoSplitPDF.description=Print, Insert, Scan, upload, and let us auto-separate your documents. No manual work sorting needed.
autoSplitPDF.selectText.1=Print out some divider sheets from below (Black and white is fine).
autoSplitPDF.selectText.2=Scan all your documents at once by inserting the divider sheet between them.
autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirling PDF handle the rest.
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
autoSplitPDF.submit=Submit
#pipeline
pipeline.title=Pipeline
#pageLayout
pageLayout.title=Multi Page Layout
pageLayout.header=Multi Page Layout
pageLayout.pagesPerSheet=Pages per sheet:
pageLayout.submit=Submit
#scalePages
scalePages.title=Adjust page-scale
scalePages.header=Adjust page-scale
scalePages.pageSize=Size of a page of the document.
scalePages.scaleFactor=Zoom level (crop) of a page.
scalePages.submit=Submit
#certSign
certSign.title=인증서로 서명
certSign.header=PDF에 당신의 인증서로 서명하세요 (개발 중)
certSign.selectPDF=서명할 PDF를 선택하세요:
@ -166,11 +293,10 @@ certSign.showSig=서명 보기
certSign.reason=이유
certSign.location=위치
certSign.name=이름
certSign.submit=PDF 서명
#removeBlanks
removeBlanks.title=빈 페이지 제거
removeBlanks.header=빈 페이지 제거
removeBlanks.threshold=임계값:
@ -179,12 +305,16 @@ removeBlanks.whitePercent=흰색 비율 (%):
removeBlanks.whitePercentDesc=제거될 페이지의 흰색 픽셀 비율
removeBlanks.submit=빈 페이지 제거
#compare
compare.title=비교
compare.header=PDF 비교
compare.document.1=문서 1
compare.document.2=문서 2
compare.submit=비교
#sign
sign.title=서명
sign.header=PDF에 서명
sign.upload=이미지 업로드
@ -193,14 +323,20 @@ sign.text=텍스트 입력
sign.clear=초기화
sign.add=추가
#repair
repair.title=복구
repair.header=PDF 복구
repair.submit=복구
#flatten
flatten.title=합치기
flatten.header=PDF 합치기
flatten.submit=합치기
#ScannerImageSplit
ScannerImageSplit.selectText.1=각도 임계값:
ScannerImageSplit.selectText.2=이미지를 회전하는 데 필요한 최소 절대 각도를 설정합니다(기본값: 10).
ScannerImageSplit.selectText.3=오차 범위:
@ -212,19 +348,6 @@ ScannerImageSplit.selectText.8=사진의 최소 윤곽선 영역 임계값을
ScannerImageSplit.selectText.9=테두리 크기:
ScannerImageSplit.selectText.10=출력에서 흰색 테두리를 방지하기 위해 추가 및 제거되는 테두리의 크기를 설정합니다(기본값: 1).
navbar.settings=설정
settings.title=설정
settings.update=업데이트 가능
settings.appVersion=앱 버전:
settings.downloadOption.title=다운로드 옵션 선택 (zip 파일이 아닌 단일 파일 다운로드 시):
settings.downloadOption.1=현재 창에서 열기
settings.downloadOption.2=새 창에서 열기
settings.downloadOption.3=다운로드
settings.zipThreshold=다운로드한 파일 수가 초과된 경우 파일 압축하기
#OCR
ocr.title=OCR / 깔끔하게 스캔
@ -246,7 +369,7 @@ ocr.credit=이 서비스는 OCR에 OCRmyPDF와 Tesseract를 사용합니다.
ocr.submit=OCR로 PDF 처리
#extractImages
extractImages.title=이미지 추출
extractImages.header=이미지 추출
extractImages.selectText=추출된 이미지를 변환할 이미지 형식을 선택하세요.
@ -286,11 +409,13 @@ merge.title=병합
merge.header=여러 개의 PDF 병합 (2개 이상)
merge.submit=병합
#pdfOrganiser
pdfOrganiser.title=페이지 정렬 도구
pdfOrganiser.header=PDF 페이지 정렬
pdfOrganiser.submit=페이지 재정렬
#multiTool
multiTool.title=PDF 멀티 툴
multiTool.header=PDF 멀티 툴
@ -302,6 +427,7 @@ pageRemover.header=PDF 페이지 제거 도구
pageRemover.pagesToDelete=제거할 페이지 (쉼표로 구분된 페이지 번호 입력):
pageRemover.submit=페이지 제거
#rotate
rotate.title=PDF 회전
rotate.header=PDF 회전
@ -309,8 +435,6 @@ rotate.selectAngle=회전 각도 선택 (90도의 배수로):
rotate.submit=회전
#merge
split.title=PDF 분할
split.header=PDF 분할
@ -326,31 +450,7 @@ split.splitPages=분할할 페이지 입력:
split.submit=분할
#imageToPdf
imageToPDF.title=Image to PDF
imageToPDF.header=이미지를 PDF로 변환
imageToPDF.submit=변환
imageToPDF.selectText.1=맞춤 크기로 늘리기
imageToPDF.selectText.2=PDF 자동 회전
imageToPDF.selectText.3=다중 파일 로직 (여러 이미지로 작업하는 경우에만 활성화됨)
imageToPDF.selectText.4=단일 PDF로 병합
imageToPDF.selectText.5=별개의 PDF로 변환
#pdfToImage
pdfToImage.title=PDF to Image
pdfToImage.header=PDF를 이미지로 변환
pdfToImage.selectText=이미지 형식
pdfToImage.singleOrMultiple=이미지 결과 유형
pdfToImage.single=단일 큰 이미지
pdfToImage.multi=여러 이미지
pdfToImage.colorType=색상 유형
pdfToImage.color=컬러
pdfToImage.grey=그레이스케일
pdfToImage.blackwhite=흑백 (데이터 손실 가능성 있음!)
pdfToImage.submit=변환하기
#imageToPdf
#merge
imageToPDF.title=이미지를 PDF로 변환
imageToPDF.header=이미지를 PDF로 변환
imageToPDF.submit=변환하기
@ -360,6 +460,7 @@ imageToPDF.selectText.3=다중 파일 로직 (여러 이미지로 작업하는
imageToPDF.selectText.4=단일 PDF로 병합
imageToPDF.selectText.5=별도의 PDF로 변환
#pdfToImage
pdfToImage.title=PDF를 이미지로 변환
pdfToImage.header=PDF를 이미지로 변환
@ -373,6 +474,7 @@ pdfToImage.grey=그레이스케일
pdfToImage.blackwhite=흑백 (데이터 손실 가능성 있음!)
pdfToImage.submit=변환하기
#addPassword
addPassword.title=암호 추가
addPassword.header=암호 추가 (암호화)
@ -394,6 +496,7 @@ addPassword.selectText.15=Restricts what can be done with the document once it i
addPassword.selectText.16=Restricts the opening of the document itself<6C>
addPassword.submit=암호화
#watermark
watermark.title=워터마크 추가
watermark.header=워터마크 추가
@ -406,6 +509,7 @@ watermark.selectText.6=세로 간격 (각 워터마크 사이의 세로 공간):
watermark.selectText.7=투명도 (0% - 100%):
watermark.submit=워터마크 추가
#remove-watermark
remove-watermark.title=워터마크 제거
remove-watermark.header=워터마크 제거
@ -413,6 +517,7 @@ remove-watermark.selectText.1=워터마크를 제거할 PDF 선택:
remove-watermark.selectText.2=워터마크 텍스트:
remove-watermark.submit=워터마크 제거
#Change permissions
permissions.title=권한 변경
permissions.header=권한 변경
@ -429,6 +534,7 @@ permissions.selectText.9=인쇄 방지
permissions.selectText.10=다른 형식으로 인쇄 방지
permissions.submit=변경
#remove password
removePassword.title=암호 제거
removePassword.header=암호 제거 (복호화)
@ -436,7 +542,9 @@ removePassword.selectText.1=복호화할 PDF 선택
removePassword.selectText.2=암호
removePassword.submit=제거
changeMetadata.title=메타데이터 변경
#changeMetadata
changeMetadata.title=제목:
changeMetadata.header=메타데이터 변경
changeMetadata.selectText.1=변경하려는 변수를 편집해주세요
changeMetadata.selectText.2=모든 메타데이터 삭제
@ -454,27 +562,30 @@ changeMetadata.selectText.4=기타 메타데이터:
changeMetadata.selectText.5=사용자 정의 메타데이터 항목 추가
changeMetadata.submit=변경
#xlsToPdf
xlsToPdf.title=Excel to PDF
xlsToPdf.header=Excel을 PDF로 변환
xlsToPdf.selectText.1=변환할 XLS 또는 XLSX Excel 시트 선택
xlsToPdf.convert=변환하기
#pdfToPDFA
pdfToPDFA.title=PDF To PDF/A
pdfToPDFA.header=PDF를 PDF/A로 변환
pdfToPDFA.credit=이 서비스는 PDF/A 변환을 위해 OCRmyPDF를 사용합니다.
pdfToPDFA.submit=변환
#PDFToWord
PDFToWord.title=PDF to Word
PDFToWord.header=PDF를 Word로 변환
PDFToWord.selectText.1=출력 파일 형식
PDFToWord.credit=이 서비스는 파일 변환을 위해 LibreOffice를 사용합니다.
PDFToWord.submit=변환
#PDFToPresentation
PDFToPresentation.title=PDF to Presentation
PDFToPresentation.header=PDF를 프레젠테이션으로 변환
PDFToPresentation.selectText.1=출력 파일 형식
@ -482,6 +593,7 @@ PDFToPresentation.credit=이 서비스는 파일 변환을 위해 LibreOffice를
PDFToPresentation.submit=변환
#PDFToText
PDFToText.title=PDF to Text/RTF
PDFToText.header=PDF를 텍스트/RTF로 변환
PDFToText.selectText.1=출력 파일 형식
@ -489,24 +601,15 @@ PDFToText.credit=이 서비스는 파일 변환을 위해 LibreOffice를 사용
PDFToText.submit=변환
#PDFToHTML
PDFToHTML.title=PDF to HTML
PDFToHTML.header=PDF를 HTML로 변환
PDFToHTML.credit=이 서비스는 파일 변환을 위해 LibreOffice를 사용합니다.
PDFToHTML.submit=변환
#PDFToXML
PDFToXML.title=PDF to XML
PDFToXML.header=PDF를 XML로 변환
PDFToXML.credit=이 서비스는 파일 변환을 위해 LibreOffice를 사용합니다.
PDFToXML.submit=변환

View file

@ -21,23 +21,62 @@ filesSelected=wybrane pliki
noFavourites=Nie dodano ulubionych
bored=Znudzony czekaniem?
alphabet=Alfabet
downloadPdf=Pobierz PDF
text=Tekst
font=Czcionka
selectFillter=-- Wybierz --
pageNum=Numer strony
##########################
### TODO: Translate ###
##########################
sizes.small=Small
sizes.medium=Medium
sizes.large=Large
sizes.x-large=X-Large
error.pdfPassword=Dokument PDF jest zabezpieczony hasłem, musisz podać prawidłowe hasło.
#############
# NAVBAR #
#############
navbar.convert=Konwertuj
navbar.security=Bezpieczeństwo
navbar.other=Inne
navbar.darkmode=Tryb nocny
navbar.pageOps=Strony
navbar.settings=Ustawienia
#############
# SETTINGS #
#############
settings.title=Ustawienia
settings.update=Dostępna aktualizacja
settings.appVersion=Wersia aplikacji:
settings.downloadOption.title=Wybierz opcję pobierania (w przypadku pobierania pojedynczych plików innych niż ZIP):
settings.downloadOption.1=Otwórz w tym samym oknie
settings.downloadOption.2=Otwórz w nowym oknie
settings.downloadOption.3=Pobierz plik
settings.zipThreshold=Spakuj pliki, gdy liczba pobranych plików przekroczy
#############
# HOME-PAGE #
#############
home.desc=Twoja lokalna aplikacja do kompleksowej obsługi Twoich potrzeb związanych z dokumentami PDF.
navbar.convert=Konwertuj
navbar.security=Bezpieczeństwo
navbar.other=Inne
navbar.darkmode=Tryb nocny
navbar.pageOps=Strony
home.multiTool.title=Multi narzędzie PDF
home.multiTool.desc=Łącz, dziel, obracaj, zmieniaj kolejność i usuwaj strony
##########################
### TODO: Translate ###
##########################
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
home.merge.title=Połącz
home.merge.desc=Łatwe łączenie wielu dokumentów PDF w jeden.
##########################
### TODO: Translate ###
##########################
merge.tags=merge,Page operations,Back end,server side
home.split.title=Podziel
home.split.desc=Podziel dokument PDF na wiele dokumentów
@ -60,9 +99,6 @@ home.addImage.desc=Dodaje obraz w wybranym miejscu w dokumencie PDF (moduł w bu
home.watermark.title=Dodaj znak wodny
home.watermark.desc=Dodaj niestandardowy znak wodny do dokumentu PDF.
home.remove-watermark.title=Usuń znak wodny
home.remove-watermark.desc=Usuń znaki wodne z dokumentu PDF.
home.permissions.title=Zmień uprawnienia
home.permissions.desc=Zmień uprawnienia dokumentu PDF
@ -135,25 +171,116 @@ home.pageLayout.desc=Scal wiele stron dokumentu PDF w jedną stronę
home.scalePages.title=Dopasuj rozmiar stron
home.scalePages.desc=Dopasuj rozmiar stron wybranego dokumentu PDF
error.pdfPassword=Dokument PDF jest zabezpieczony hasłem, musisz podać prawidłowe hasło.
##########################
### TODO: Translate ###
##########################
home.pipeline.title=Pipeline (Advanced)
home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts
downloadPdf=Pobierz PDF
text=Tekst
font=Czcionka
selectFillter=-- Wybierz --
pageNum=Numer strony
home.add-page-numbers.title=Add Page Numbers
home.add-page-numbers.desc=Add Page numbers throughout a document in a set location
home.auto-rename.title=Auto Rename PDF File
home.auto-rename.desc=Auto renames a PDF file based on its detected header
home.adjust-contrast.title=Adjust Colors/Contrast
home.adjust-contrast.desc=Adjust Contrast, Saturation and Brightness of a PDF
home.crop.title=Crop PDF
home.crop.desc=Crop a PDF to reduce its size (maintains text!)
home.autoSplitPDF.title=Auto Split Pages
home.autoSplitPDF.desc=Auto Split Scanned PDF with physical scanned page splitter QR Code
home.sanitizePdf.title=Sanitize
home.sanitizePdf.desc=Remove scripts and other elements from PDF files
###########################
# #
# WEB PAGES #
# #
###########################
#sanitizePDF
sanitizePDF.title=Sanitize PDF
sanitizePDF.header=Sanitize a PDF file
sanitizePDF.selectText.1=Remove JavaScript actions
sanitizePDF.selectText.2=Remove embedded files
sanitizePDF.selectText.3=Remove metadata
sanitizePDF.selectText.4=Remove links
sanitizePDF.selectText.5=Remove fonts
sanitizePDF.submit=Sanitize PDF
#addPageNumbers
addPageNumbers.title=Add Page Numbers
addPageNumbers.header=Add Page Numbers
addPageNumbers.selectText.1=Select PDF file:
addPageNumbers.selectText.2=Margin Size
addPageNumbers.selectText.3=Position
addPageNumbers.selectText.4=Starting Number
addPageNumbers.selectText.5=Pages to Number
addPageNumbers.selectText.6=Custom Text
addPageNumbers.submit=Add Page Numbers
#auto-rename
auto-rename.title=Auto Rename
auto-rename.header=Auto Rename PDF
auto-rename.submit=Auto Rename
#adjustContrast
adjustContrast.title=Adjust Contrast
adjustContrast.header=Adjust Contrast
adjustContrast.contrast=Contrast:
adjustContrast.brightness=Brightness:
adjustContrast.saturation=Saturation:
adjustContrast.download=Download
#crop
crop.title=Crop
crop.header=Crop Image
crop.submit=Submit
#autoSplitPDF
autoSplitPDF.title=Auto Split PDF
autoSplitPDF.header=Auto Split PDF
autoSplitPDF.description=Print, Insert, Scan, upload, and let us auto-separate your documents. No manual work sorting needed.
autoSplitPDF.selectText.1=Print out some divider sheets from below (Black and white is fine).
autoSplitPDF.selectText.2=Scan all your documents at once by inserting the divider sheet between them.
autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirling PDF handle the rest.
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
autoSplitPDF.submit=Submit
#pipeline
pipeline.title=Pipeline
#pageLayout
pageLayout.title=Układ wielu stron
pageLayout.header=Układ wielu stron
pageLayout.pagesPerSheet=Stron na jednym arkuszu:
pageLayout.submit=Wykonaj
#scalePages
scalePages.title=Dopasuj rozmiar stron
scalePages.header=Dopasuj rozmiar stron
scalePages.pageSize=Rozmiar stron dokumentu:
scalePages.scaleFactor=Poziom powiększenia (przycięcia) stron:
scalePages.submit=Wykonaj
#certSign
certSign.title=Podpisywanie certyfikatem
certSign.header=Podpisz dokument PDF certyfikatem prywatnym (moduł w budowie)
certSign.selectPDF=Wybierz dokument PDF do podpisania:
@ -168,6 +295,8 @@ certSign.location=Lokalizacja
certSign.name=Nazwa
certSign.submit=Podpisz PDF
#removeBlanks
removeBlanks.title=Usuń puste
removeBlanks.header=Usuń puste strony
removeBlanks.threshold=Próg:
@ -176,12 +305,16 @@ removeBlanks.whitePercent=Procent białego (%):
removeBlanks.whitePercentDesc=Procent strony, która musi być biała, aby została usunięta
removeBlanks.submit=Usuń puste
#compare
compare.title=Porównaj
compare.header=Porównaj PDF(y)
compare.document.1=Dokument 1
compare.document.2=Dokument 2
compare.submit=Porównaj
#sign
sign.title=Podpis
sign.header=Dodaj podpis do dokumentu PDF
sign.upload=Wczytaj opbraz
@ -190,14 +323,20 @@ sign.text=Wprowadź tekst
sign.clear=Wyczyść
sign.add=Dodaj
#repair
repair.title=Napraw
repair.header=Napraw dokument(y) PDF
repair.submit=Napraw
#flatten
flatten.title=Spłaszcz
flatten.header=Spłaszcz dokument(y) PDF
flatten.submit=Spłaszcz
#ScannerImageSplit
ScannerImageSplit.selectText.1=Próg kąta:
ScannerImageSplit.selectText.2=Ustawia minimalny kąt bezwzględny wymagany do obrócenia obrazu (domyślnie: 10).
ScannerImageSplit.selectText.3=Tolerancja:
@ -209,19 +348,6 @@ ScannerImageSplit.selectText.8=Ustawia próg minimalnego obszaru konturu dla zdj
ScannerImageSplit.selectText.9=Rozmiar obramowania:
ScannerImageSplit.selectText.10=Ustawia rozmiar dodawanego i usuwanego obramowania, aby uniknąć białych obramowań na wyjściu (domyślnie: 1).
navbar.settings=Ustawienia
settings.title=Ustawienia
settings.update=Dostępna aktualizacja
settings.appVersion=Wersia aplikacji:
settings.downloadOption.title=Wybierz opcję pobierania (w przypadku pobierania pojedynczych plików innych niż ZIP):
settings.downloadOption.1=Otwórz w tym samym oknie
settings.downloadOption.2=Otwórz w nowym oknie
settings.downloadOption.3=Pobierz plik
settings.zipThreshold=Spakuj pliki, gdy liczba pobranych plików przekroczy
#OCR
ocr.title=OCR / Zamiana na tekst
@ -243,7 +369,7 @@ ocr.credit=Ta usługa używa OCRmyPDF i Tesseract do OCR.
ocr.submit=Przetwarzaj PDF za pomocą OCR
#extractImages
extractImages.title=Wyodrębnij obrazy
extractImages.header=Wyodrębnij obrazy
extractImages.selectText=Wybierz format obrazu, na który chcesz przekonwertować wyodrębniony obraz.
@ -269,6 +395,7 @@ compress.selectText.4=Tryb automatyczny - Automatycznie dostosowuje jakość, ab
compress.selectText.5=Oczekiwany rozmiar pliku PDF (np. 25 MB, 10,8 MB, 25 KB)
compress.submit=Kompresuj
#Add image
addImage.title=Dodaj obraz
addImage.header=Dodaj obraz do PDF
@ -282,11 +409,13 @@ merge.title=Połącz
merge.header=Połącz wiele dokumentów PDF (2+)
merge.submit=Połącz
#pdfOrganiser
pdfOrganiser.title=Kolejność stron
pdfOrganiser.header=Kolejność stron PDF
pdfOrganiser.submit=Zmień kolejność stron
#multiTool
multiTool.title=Multi narzędzie PDF
multiTool.header=Multi narzędzie PDF
@ -298,6 +427,7 @@ pageRemover.header=Narzędzie do usuwania stron w dokumentach PDF
pageRemover.pagesToDelete=Strony do usunięcia (wprowadź listę numerów stron oddzielonych przecinkami):
pageRemover.submit=Usuń strony
#rotate
rotate.title=Obróć dokument PDF
rotate.header=Obróć dokument PDF
@ -305,8 +435,6 @@ rotate.selectAngle=Wybierz kąt obrotu (domyślnie 90 stopni):
rotate.submit=Obróć
#merge
split.title=Podziel dokument PDF
split.header=Podziel dokument PDF
@ -332,6 +460,7 @@ imageToPDF.selectText.3=Logika wielu plików (dostępna tylko w przypadku pracy
imageToPDF.selectText.4=Połącz w jeden dokument PDF
imageToPDF.selectText.5=Konwertuj na osobne dokumenty PDF
#pdfToImage
pdfToImage.title=PDF na Obraz
pdfToImage.header=PDF na Obraz
@ -345,6 +474,7 @@ pdfToImage.grey=Odcień szarości
pdfToImage.blackwhite=Czarno-biały (może spowodować utratę danych!)
pdfToImage.submit=Konwertuj
#addPassword
addPassword.title=Dodaj hasło
addPassword.header=Dodaj hasło (zaszyfruj)
@ -366,6 +496,7 @@ addPassword.selectText.15=Restricts what can be done with the document once it i
addPassword.selectText.16=Restricts the opening of the document itself
addPassword.submit=Zablokuj
#watermark
watermark.title=Dodaj znak wodny
watermark.header=Dodaj znak wodny
@ -378,6 +509,7 @@ watermark.selectText.6=Odstęp w pionie (odstęp między każdym znakiem wodnym
watermark.selectText.7=Nieprzezroczystość (0% - 100%):
watermark.submit=Dodaj znak wodny
#remove-watermark
remove-watermark.title=Usuń znak wodny
remove-watermark.header=Usuń znak wodny
@ -385,6 +517,7 @@ remove-watermark.selectText.1=Wybierz dokument PDF, aby usunąć znak wodny z:
remove-watermark.selectText.2=Treść zanku wodnego:
remove-watermark.submit=Usuń znak wodny
#Change permissions
permissions.title=Zmień uprawnienia
permissions.header=Zmień uprawnienia
@ -401,6 +534,7 @@ permissions.selectText.9=Zablokuj drukowanie
permissions.selectText.10=Zablokuj drukowanie różnych formatów
permissions.submit=Zmień
#remove password
removePassword.title=Usuń hasło
removePassword.header=Usuń hasło (odszyfruj)
@ -408,7 +542,9 @@ removePassword.selectText.1=Wybierz dokument PDF do odszyfrowania
removePassword.selectText.2=Hasło
removePassword.submit=Usuń
changeMetadata.title=Zmień metadane
#changeMetadata
changeMetadata.title=Tytuł:
changeMetadata.header=Zmień metadane
changeMetadata.selectText.1=Edytuj zmienne, które chcesz zmienić
changeMetadata.selectText.2=Usuń wszystkie metadane
@ -426,27 +562,30 @@ changeMetadata.selectText.4=Inne metadane:
changeMetadata.selectText.5=Dodaj niestandardowy wpis w metadanych
changeMetadata.submit=Zmień
#xlsToPdf
xlsToPdf.title=Excel na PDF
xlsToPdf.header=Excel na PDF
xlsToPdf.selectText.1=Wybierz arkusz Microsoft Excel XLS lub XLSX do konwersji
xlsToPdf.convert=Konwertuj
#pdfToPDFA
pdfToPDFA.title=PDF na PDF/A
pdfToPDFA.header=PDF na PDF/A
pdfToPDFA.credit=Ta usługa używa OCRmyPDF do konwersji PDF/A
pdfToPDFA.submit=Konwertuj
#PDFToWord
PDFToWord.title=PDF na Word
PDFToWord.header=PDF na Word
PDFToWord.selectText.1=Format pliku wyjściowego
PDFToWord.credit=Ta usługa używa LibreOffice do konwersji plików.
PDFToWord.submit=Konwertuj
#PDFToPresentation
PDFToPresentation.title=PDF na Prezentację
PDFToPresentation.header=PDF na Prezentację
PDFToPresentation.selectText.1=Format pliku wyjściowego
@ -454,6 +593,7 @@ PDFToPresentation.credit=Ta usługa używa LibreOffice do konwersji plików.
PDFToPresentation.submit=Konwertuj
#PDFToText
PDFToText.title=PDF na Tekst/RTF
PDFToText.header=PDF na Tekst/RTF
PDFToText.selectText.1=Format pliku wyjściowego
@ -461,11 +601,14 @@ PDFToText.credit=Ta usługa używa LibreOffice do konwersji plików.
PDFToText.submit=Konwertuj
#PDFToHTML
PDFToHTML.title=PDF na HTML
PDFToHTML.header=PDF na HTML
PDFToHTML.credit=Ta usługa używa LibreOffice do konwersji plików.
PDFToHTML.submit=Konwertuj
#PDFToXML
PDFToXML.title=PDF na XML
PDFToXML.header=PDF na XML
PDFToXML.credit=Ta usługa używa LibreOffice do konwersji plików.

View file

@ -1,7 +1,7 @@
###########
# Generic #
###########
# the direction that the language is written (ltr =esquerda para a direita, rtl = direita para a esquerda)
# the direction that the language is written (ltr = left to right, rtl = right to left)
language.direction=ltr
pdfPrompt=Selecione PDF(s)
@ -21,23 +21,62 @@ filesSelected=arquivos selecionados
noFavourites=Nenhum favorito adicionado
bored=Entediado esperando?
alphabet=Alfabeto
downloadPdf=baixar PDF
text=Texto
font=Fonte
selectFillter=-- Selecione --
pageNum=Número de página
##########################
### TODO: Translate ###
##########################
sizes.small=Small
sizes.medium=Medium
sizes.large=Large
sizes.x-large=X-Large
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
#############
# NAVBAR #
#############
navbar.convert=Converter
navbar.security=Segurança
navbar.other=Outro
navbar.darkmode=Modo Escuro
navbar.pageOps=Operações de página
navbar.settings=Configurações
#############
# SETTINGS #
#############
settings.title=Configurações
settings.update=Atualização disponível
settings.appVersion=Versão do aplicativo:
settings.downloadOption.title=Escolha a opção de download (para downloads não compactados de arquivo único):
settings.downloadOption.1=Abrir na mesma janela
settings.downloadOption.2=Abrir em nova janela
settings.downloadOption.3=⇬ Fazer download do arquivo
settings.zipThreshold=Compactar arquivos quando o número de arquivos baixados exceder
#############
# HOME-PAGE #
#############
home.desc=Seu melhor utilitário para as necessidades de PDF.
navbar.convert=Converter
navbar.security=Segurança
navbar.other=Outro
navbar.darkmode=Modo Escuro
navbar.pageOps=Operações de página
home.multiTool.title=Multiferramenta de PDF
home.multiTool.desc=Mesclar, girar, reorganizar e remover páginas
##########################
### TODO: Translate ###
##########################
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
home.merge.title=mesclar
home.merge.desc=Mescle facilmente vários PDFs em um.
##########################
### TODO: Translate ###
##########################
merge.tags=merge,Page operations,Back end,server side
home.split.title=Dividir
home.split.desc=Dividir PDFs em vários documentos
@ -60,9 +99,6 @@ home.addImage.desc=Adiciona uma imagem em um local definido no PDF (trabalho em
home.watermark.title=Adicione uma Marca d'água
home.watermark.desc=Adicione uma marca d'água personalizada ao seu documento PDF.
home.remove-watermark.title=Remover marca d'água
home.remove-watermark.desc=Remova marcas d'água do seu documento PDF.
home.permissions.title=Alterar permissões
home.permissions.desc=Altere as permissões do seu documento PDF
@ -135,25 +171,115 @@ home.pageLayout.desc=Merge multiple pages of a PDF document into a single page
home.scalePages.title=Adjust page size/scale
home.scalePages.desc=Change the size/scale of page and/or its contents.
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
##########################
### TODO: Translate ###
##########################
home.pipeline.title=Pipeline (Advanced)
home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts
downloadPdf=baixar PDF
text=Texto
font=Fonte
selectFillter=-- Selecione --
pageNum=Número de página
home.add-page-numbers.title=Add Page Numbers
home.add-page-numbers.desc=Add Page numbers throughout a document in a set location
home.auto-rename.title=Auto Rename PDF File
home.auto-rename.desc=Auto renames a PDF file based on its detected header
home.adjust-contrast.title=Adjust Colors/Contrast
home.adjust-contrast.desc=Adjust Contrast, Saturation and Brightness of a PDF
home.crop.title=Crop PDF
home.crop.desc=Crop a PDF to reduce its size (maintains text!)
home.autoSplitPDF.title=Auto Split Pages
home.autoSplitPDF.desc=Auto Split Scanned PDF with physical scanned page splitter QR Code
home.sanitizePdf.title=Sanitize
home.sanitizePdf.desc=Remove scripts and other elements from PDF files
###########################
# #
# WEB PAGES #
# #
###########################
#sanitizePDF
sanitizePDF.title=Sanitize PDF
sanitizePDF.header=Sanitize a PDF file
sanitizePDF.selectText.1=Remove JavaScript actions
sanitizePDF.selectText.2=Remove embedded files
sanitizePDF.selectText.3=Remove metadata
sanitizePDF.selectText.4=Remove links
sanitizePDF.selectText.5=Remove fonts
sanitizePDF.submit=Sanitize PDF
#addPageNumbers
addPageNumbers.title=Add Page Numbers
addPageNumbers.header=Add Page Numbers
addPageNumbers.selectText.1=Select PDF file:
addPageNumbers.selectText.2=Margin Size
addPageNumbers.selectText.3=Position
addPageNumbers.selectText.4=Starting Number
addPageNumbers.selectText.5=Pages to Number
addPageNumbers.selectText.6=Custom Text
addPageNumbers.submit=Add Page Numbers
#auto-rename
auto-rename.title=Auto Rename
auto-rename.header=Auto Rename PDF
auto-rename.submit=Auto Rename
#adjustContrast
adjustContrast.title=Adjust Contrast
adjustContrast.header=Adjust Contrast
adjustContrast.contrast=Contrast:
adjustContrast.brightness=Brightness:
adjustContrast.saturation=Saturation:
adjustContrast.download=Download
#crop
crop.title=Crop
crop.header=Crop Image
crop.submit=Submit
#autoSplitPDF
autoSplitPDF.title=Auto Split PDF
autoSplitPDF.header=Auto Split PDF
autoSplitPDF.description=Print, Insert, Scan, upload, and let us auto-separate your documents. No manual work sorting needed.
autoSplitPDF.selectText.1=Print out some divider sheets from below (Black and white is fine).
autoSplitPDF.selectText.2=Scan all your documents at once by inserting the divider sheet between them.
autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirling PDF handle the rest.
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
autoSplitPDF.submit=Submit
#pipeline
pipeline.title=Pipeline
#pageLayout
pageLayout.title=Multi Page Layout
pageLayout.header=Multi Page Layout
pageLayout.pagesPerSheet=Pages per sheet:
pageLayout.submit=Submit
#scalePages
scalePages.title=Adjust page-scale
scalePages.header=Adjust page-scale
scalePages.pageSize=Size of a page of the document.
scalePages.scaleFactor=Zoom level (crop) of a page.
scalePages.submit=Submit
#certSign
certSign.title=Assinatura de certificado
certSign.header=Assine um PDF com seu certificado (Trabalho em andamento)
certSign.selectPDF=Selecione um arquivo PDF para assinatura:
@ -166,11 +292,10 @@ certSign.showSig=Mostrar assinatura
certSign.reason=Razão
certSign.location=Localização
certSign.name=Nome
certSign.submit=Assinar PDF
#removeBlanks
removeBlanks.title=Remover espaços em branco
removeBlanks.header=Remover páginas em branco
removeBlanks.threshold=Limite:
@ -179,12 +304,16 @@ removeBlanks.whitePercent=Porcentagem branca (%):
removeBlanks.whitePercentDesc=Porcentagem da página que deve ser branca para ser removida
removeBlanks.submit=Remover espaços em branco
#compare
compare.title=Comparar
compare.header=Comparar PDFs
compare.document.1=Documento 1
compare.document.2=Documento 2
compare.submit=Comparar
#sign
sign.title=Sinal
sign.header=Assinar PDFs
sign.upload=Enviar Imagem
@ -193,14 +322,20 @@ sign.text=Entrada de texto
sign.clear=Claro
sign.add=Adicionar
#repair
repair.title=Reparar
repair.header=Reparar PDFs
repair.submit=Reparar
#flatten
flatten.title=achatar
flatten.header=Achatar PDFs
flatten.submit=achatar
#ScannerImageSplit
ScannerImageSplit.selectText.1=Limite de Ângulo:
ScannerImageSplit.selectText.2=Define o ângulo absoluto mínimo necessário para que a imagem seja girada (padrão: 10).
ScannerImageSplit.selectText.3=Tolerância:
@ -212,19 +347,6 @@ ScannerImageSplit.selectText.8=Define o limite mínimo da área de contorno para
ScannerImageSplit.selectText.9=Tamanho da Borda:
ScannerImageSplit.selectText.10=Define o tamanho da borda adicionada e removida para evitar bordas brancas na saída (padrão: 1).
navbar.settings=Configurações
settings.title=Configurações
settings.update=Atualização disponível
settings.appVersion=Versão do aplicativo:
settings.downloadOption.title=Escolha a opção de download (para downloads não compactados de arquivo único):
settings.downloadOption.1=Abrir na mesma janela
settings.downloadOption.2=Abrir em nova janela
settings.downloadOption.3=⇬ Fazer download do arquivo
settings.zipThreshold=Compactar arquivos quando o número de arquivos baixados exceder
#OCR
ocr.title=OCR / Limpeza de digitalização
@ -246,7 +368,7 @@ ocr.credit=Este serviço usa OCRmyPDF e Tesseract para OCR.
ocr.submit=Processar PDF com OCR
#extractImages
extractImages.title=Extrair Imagens
extractImages.header=Extrair Imagens
extractImages.selectText=Selecione o formato de imagem para converter as imagens extraídas em
@ -286,11 +408,13 @@ merge.title=mesclar
merge.header=Mesclar vários PDFs (2+)
merge.submit=mesclar
#pdfOrganiser
pdfOrganiser.title=Organizador de página
pdfOrganiser.header=Organizador de páginas PDF
pdfOrganiser.submit=Reorganizar páginas
#multiTool
multiTool.title=Multiferramenta de PDF
multiTool.header=Multiferramenta de PDF
@ -302,6 +426,7 @@ pageRemover.header=Removedor de página PDF
pageRemover.pagesToDelete=Páginas a serem excluídas (digite uma lista separada por vírgulas de números de página):
pageRemover.submit=Excluir páginas
#rotate
rotate.title=Girar PDF
rotate.header=Girar PDF
@ -309,8 +434,6 @@ rotate.selectAngle=Selecione o ângulo de rotação (em múltiplos de 90 graus):
rotate.submit=Girar
#merge
split.title=PDF dividido
split.header=PDF dividido
@ -336,6 +459,7 @@ imageToPDF.selectText.3=Lógica de vários arquivos (Ativado apenas se estiver t
imageToPDF.selectText.4=Mesclar em um único PDF
imageToPDF.selectText.5=Converter em PDFs separados
#pdfToImage
pdfToImage.title=PDF para imagem
pdfToImage.header=PDF para imagem
@ -349,6 +473,7 @@ pdfToImage.grey=Escala de cinza
pdfToImage.blackwhite=Preto e branco (pode perder dados!)
pdfToImage.submit=Converter
#addPassword
addPassword.title=Adicionar senha
addPassword.header=Adicionar senha (Criptografar)
@ -370,6 +495,7 @@ addPassword.selectText.15=Restricts what can be done with the document once it i
addPassword.selectText.16=Restricts the opening of the document itself
addPassword.submit=criptografar
#watermark
watermark.title=Adicione uma Marca d'água
watermark.header=Adicione uma Marca d'água
@ -382,6 +508,7 @@ watermark.selectText.6=heightSpacer (espaço entre cada marca d'água verticalme
watermark.selectText.7=Opacidade (0% - 100%):
watermark.submit=Adicione uma Marca d'água
#remove-watermark
remove-watermark.title=Remover marca d'água
remove-watermark.header=Remover marca d'água
@ -389,6 +516,7 @@ remove-watermark.selectText.1=Selecione PDF para remover a marca d'água de:
remove-watermark.selectText.2=Texto da marca d'água:
remove-watermark.submit=Remover marca d'água
#Change permissions
permissions.title=Alterar permissões
permissions.header=Alterar permissões
@ -405,6 +533,7 @@ permissions.selectText.9=Impedir a impressão
permissions.selectText.10=Impedir a impressão de formatos diferentes
permissions.submit=Mudar
#remove password
removePassword.title=Remover senha
removePassword.header=Remover senha (Descriptografar)
@ -412,7 +541,9 @@ removePassword.selectText.1=Selecione PDF para descriptografar
removePassword.selectText.2=Senha
removePassword.submit=Remover
changeMetadata.title=Alterar metadados
#changeMetadata
changeMetadata.title=Título:
changeMetadata.header=Alterar metadados
changeMetadata.selectText.1=Edite as variáveis que deseja alterar
changeMetadata.selectText.2=Excluir todos os metadados
@ -430,27 +561,30 @@ changeMetadata.selectText.4=Outros metadados:
changeMetadata.selectText.5=Adicionar entrada de metadados personalizados
changeMetadata.submit=Mudar
#xlsToPdf
xlsToPdf.title=Excel para PDF
xlsToPdf.header=Excel para PDF
xlsToPdf.selectText.1=Selecione planilha Excel XLS ou XLSX para converter
xlsToPdf.convert=converter
#pdfToPDFA
pdfToPDFA.title=PDF para PDF/A
pdfToPDFA.header=PDF para PDF/A
pdfToPDFA.credit=Este serviço usa OCRmyPDF para conversão de PDF/A
pdfToPDFA.submit=Converter
#PDFToWord
PDFToWord.title=PDF para Word
PDFToWord.header=PDF para Word
PDFToWord.selectText.1=Formato do arquivo de saída
PDFToWord.credit=Este serviço usa o LibreOffice para conversão de arquivos.
PDFToWord.submit=Converter
#PDFToPresentation
PDFToPresentation.title=PDF para apresentação
PDFToPresentation.header=PDF para apresentação
PDFToPresentation.selectText.1=Formato do arquivo de saída
@ -458,6 +592,7 @@ PDFToPresentation.credit=Este serviço usa o LibreOffice para conversão de arqu
PDFToPresentation.submit=Converter
#PDFToText
PDFToText.title=PDF para Texto/RTF
PDFToText.header=PDF para Texto/RTF
PDFToText.selectText.1=Formato do arquivo de saída
@ -465,24 +600,15 @@ PDFToText.credit=Este serviço usa o LibreOffice para conversão de arquivos.
PDFToText.submit=Converter
#PDFToHTML
PDFToHTML.title=PDF para HTML
PDFToHTML.header=PDF para HTML
PDFToHTML.credit=Este serviço usa o LibreOffice para conversão de arquivos.
PDFToHTML.submit=Converter
#PDFToXML
PDFToXML.title=PDF para XML
PDFToXML.header=PDF para XML
PDFToXML.credit=Este serviço usa o LibreOffice para conversão de arquivos.
PDFToXML.submit=Converter

View file

@ -21,22 +21,62 @@ filesSelected=fișiere selectate
noFavourites=Niciun favorit adăugat
bored=Plictisit așteptând?
alphabet=Alfabet
#############
# HOME-PAGE #
#############
home.desc=Un singur punct de oprire găzduit local pentru toate nevoile tale legate de fișiere PDF.
downloadPdf=Descarcă PDF
text=Text
font=Font
selectFillter=-- Selectează --
pageNum=Numărul paginii
##########################
### TODO: Translate ###
##########################
sizes.small=Small
sizes.medium=Medium
sizes.large=Large
sizes.x-large=X-Large
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
#############
# NAVBAR #
#############
navbar.convert=Converteste
navbar.security=Securitate
navbar.other=Altele
navbar.darkmode=Mod întunecat
navbar.pageOps=Operații pe pagină
navbar.settings=Setări
#############
# SETTINGS #
#############
settings.title=Setări
settings.update=Actualizare disponibilă
settings.appVersion=Versiune aplicație:
settings.downloadOption.title=Alege opțiunea de descărcare (pentru descărcarea unui singur fișier non-zip):
settings.downloadOption.1=Deschide în aceeași fereastră
settings.downloadOption.2=Deschide într-o fereastră nouă
settings.downloadOption.3=Descarcă fișierul
settings.zipThreshold=Împachetează fișierele când numărul de fișiere descărcate depășește
#############
# HOME-PAGE #
#############
home.desc=Un singur punct de oprire găzduit local pentru toate nevoile tale legate de fișiere PDF.
home.multiTool.title=Instrument multiplu PDF
home.multiTool.desc=Unifică, rotește, rearanjează și elimină pagini
##########################
### TODO: Translate ###
##########################
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
home.merge.title=Unifică
home.merge.desc=Unifică cu ușurință mai multe fișiere PDF într-unul singur.
##########################
### TODO: Translate ###
##########################
merge.tags=merge,Page operations,Back end,server side
home.split.title=Desparte
home.split.desc=Desparte fișierele PDF în mai multe documente.
@ -59,9 +99,6 @@ home.addImage.desc=Adaugă o imagine într-o locație specifică pe PDF (în cur
home.watermark.title=Adaugă Filigran
home.watermark.desc=Adaugă un filigran personalizat la documentul PDF.
home.remove-watermark.title=Elimină Filigran
home.remove-watermark.desc=Elimină filigranele din documentul PDF.
home.permissions.title=Schimbă permisiuni
home.permissions.desc=Schimbă permisiunile documentului PDF
@ -70,40 +107,58 @@ home.removePages.desc=Șterge paginile nedorite din documentul PDF.
home.addPassword.title=Adaugă Parolă
home.addPassword.desc=Criptează documentul PDF cu o parolă.
home.removePassword.title=Elimină Parola
home.removePassword.desc=Elimină protecția cu parolă din documentul PDF.
home.compressPdfs.title=Comprimă
home.compressPdfs.desc=Comprimă fișierele PDF pentru a reduce dimensiunea lor.
home.changeMetadata.title=Schimbă Metadatele
home.changeMetadata.desc=Schimbă/Elimină/Adaugă metadate într-un document PDF.
home.fileToPDF.title=Convertește fișierul în PDF
home.fileToPDF.desc=Convertește aproape orice fișier în format PDF (DOCX, PNG, XLS, PPT, TXT și altele).
home.ocr.title=OCR / Curățare scanări
home.ocr.desc=Curăță scanările și detectează textul din imaginile dintr-un PDF și îl adaugă ca text.
home.extractImages.title=Extrage Imagini
home.extractImages.desc=Extrage toate imaginile dintr-un PDF și le salvează într-un fișier zip.
home.pdfToPDFA.title=PDF în PDF/A
home.pdfToPDFA.desc=Convertește un document PDF în format PDF/A pentru stocare pe termen lung.
home.PDFToWord.title=PDF în Word
home.PDFToWord.desc=Convertește un document PDF în formate Word (DOC, DOCX și ODT).
home.PDFToPresentation.title=PDF în Prezentare
home.PDFToPresentation.desc=Convertește un document PDF în formate de prezentare (PPT, PPTX și ODP).
home.PDFToText.title=PDF în Text/RTF
home.PDFToText.desc=Convertește un document PDF în format Text sau RTF.
home.PDFToHTML.title=PDF în HTML
home.PDFToHTML.desc=Convertește un document PDF în format HTML.
home.PDFToXML.title=PDF în XML
home.PDFToXML.desc=Convertește un document PDF în format XML.
home.ScannerImageSplit.title=Detectează/Împarte poze scanate
home.ScannerImageSplit.desc=Împarte mai multe poze dintr-o poză/PDF.
home.sign.title=Semnează
home.sign.desc=Adaugă o semnătură la documentul PDF prin desenare, text sau imagine.
home.flatten.title=Nivelare
home.flatten.desc=Elimină toate elementele interactive și formularele dintr-un PDF.
home.repair.title=Repară
home.repair.desc=Încearcă să repare un document PDF corupt/defect.
home.removeBlanks.title=Elimină pagini goale
home.removeBlanks.desc=Detectează și elimină paginile goale dintr-un document.
home.compare.title=Compară
home.compare.desc=Compară și arată diferențele dintre 2 documente PDF.
@ -116,40 +171,132 @@ home.pageLayout.desc=Merge multiple pages of a PDF document into a single page
home.scalePages.title=Adjust page size/scale
home.scalePages.desc=Change the size/scale of page and/or its contents.
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
##########################
### TODO: Translate ###
##########################
home.pipeline.title=Pipeline (Advanced)
home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts
downloadPdf=Descarcă PDF
text=Text
font=Font
selectFillter=-- Selectează --
pageNum=Numărul paginii
home.add-page-numbers.title=Add Page Numbers
home.add-page-numbers.desc=Add Page numbers throughout a document in a set location
home.auto-rename.title=Auto Rename PDF File
home.auto-rename.desc=Auto renames a PDF file based on its detected header
home.adjust-contrast.title=Adjust Colors/Contrast
home.adjust-contrast.desc=Adjust Contrast, Saturation and Brightness of a PDF
home.crop.title=Crop PDF
home.crop.desc=Crop a PDF to reduce its size (maintains text!)
home.autoSplitPDF.title=Auto Split Pages
home.autoSplitPDF.desc=Auto Split Scanned PDF with physical scanned page splitter QR Code
home.sanitizePdf.title=Sanitize
home.sanitizePdf.desc=Remove scripts and other elements from PDF files
###########################
# #
# WEB PAGES #
# #
###########################
#sanitizePDF
sanitizePDF.title=Sanitize PDF
sanitizePDF.header=Sanitize a PDF file
sanitizePDF.selectText.1=Remove JavaScript actions
sanitizePDF.selectText.2=Remove embedded files
sanitizePDF.selectText.3=Remove metadata
sanitizePDF.selectText.4=Remove links
sanitizePDF.selectText.5=Remove fonts
sanitizePDF.submit=Sanitize PDF
#addPageNumbers
addPageNumbers.title=Add Page Numbers
addPageNumbers.header=Add Page Numbers
addPageNumbers.selectText.1=Select PDF file:
addPageNumbers.selectText.2=Margin Size
addPageNumbers.selectText.3=Position
addPageNumbers.selectText.4=Starting Number
addPageNumbers.selectText.5=Pages to Number
addPageNumbers.selectText.6=Custom Text
addPageNumbers.submit=Add Page Numbers
#auto-rename
auto-rename.title=Auto Rename
auto-rename.header=Auto Rename PDF
auto-rename.submit=Auto Rename
#adjustContrast
adjustContrast.title=Adjust Contrast
adjustContrast.header=Adjust Contrast
adjustContrast.contrast=Contrast:
adjustContrast.brightness=Brightness:
adjustContrast.saturation=Saturation:
adjustContrast.download=Download
#crop
crop.title=Crop
crop.header=Crop Image
crop.submit=Submit
#autoSplitPDF
autoSplitPDF.title=Auto Split PDF
autoSplitPDF.header=Auto Split PDF
autoSplitPDF.description=Print, Insert, Scan, upload, and let us auto-separate your documents. No manual work sorting needed.
autoSplitPDF.selectText.1=Print out some divider sheets from below (Black and white is fine).
autoSplitPDF.selectText.2=Scan all your documents at once by inserting the divider sheet between them.
autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirling PDF handle the rest.
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
autoSplitPDF.submit=Submit
#pipeline
pipeline.title=Pipeline
#pageLayout
pageLayout.title=Multi Page Layout
pageLayout.header=Multi Page Layout
pageLayout.pagesPerSheet=Pages per sheet:
pageLayout.submit=Submit
#scalePages
scalePages.title=Adjust page-scale
scalePages.header=Adjust page-scale
scalePages.pageSize=Size of a page of the document.
scalePages.scaleFactor=Zoom level (crop) of a page.
scalePages.submit=Submit
certSign.title = Semnare certificat
certSign.header = Semnează un fișier PDF cu certificatul tău (În curs de desfășurare)
certSign.selectPDF = Selectează un fișier PDF pentru semnare:
certSign.selectKey = Selectează fișierul cheie privată (format PKCS#8, poate fi .pem sau .der):
certSign.selectCert = Selectează fișierul de certificat (format X.509, poate fi .pem sau .der):
certSign.selectP12 = Selectează fișierul de stocare cheie PKCS#12 (.p12 sau .pfx) (Opțional, dacă este furnizat, ar trebui să conțină cheia privată și certificatul tău):
certSign.certType = Tipul certificatului
certSign.password = Introdu parola pentru stocarea cheie sau cheia privată (dacă există):
certSign.showSig = Afișează semnătura
certSign.reason = Motivul
certSign.location = Locația
certSign.name = Numele
certSign.submit = Semnează PDF
#certSign
certSign.title=Semnare certificat
certSign.header=Semnează un fișier PDF cu certificatul tău (În curs de desfășurare)
certSign.selectPDF=Selectează un fișier PDF pentru semnare:
certSign.selectKey=Selectează fișierul cheie privată (format PKCS#8, poate fi .pem sau .der):
certSign.selectCert=Selectează fișierul de certificat (format X.509, poate fi .pem sau .der):
certSign.selectP12=Selectează fișierul de stocare cheie PKCS#12 (.p12 sau .pfx) (Opțional, dacă este furnizat, ar trebui să conțină cheia privată și certificatul tău):
certSign.certType=Tipul certificatului
certSign.password=Introdu parola pentru stocarea cheie sau cheia privată (dacă există):
certSign.showSig=Afișează semnătura
certSign.reason=Motivul
certSign.location=Locația
certSign.name=Numele
certSign.submit=Semnează PDF
#removeBlanks
removeBlanks.title=Elimină pagini goale
removeBlanks.header=Elimină pagini goale
removeBlanks.threshold=Prag:
@ -157,12 +304,17 @@ removeBlanks.thresholdDesc=Prag pentru determinarea cât de alb trebuie să fie
removeBlanks.whitePercent=Procent alb (%):
removeBlanks.whitePercentDesc=Procentul paginii care trebuie să fie alb pentru a fi eliminată
removeBlanks.submit=Elimină pagini goale
#compare
compare.title=Compară
compare.header=Compară PDF-uri
compare.document.1=Document 1
compare.document.2=Document 2
compare.submit=Compară
#sign
sign.title=Semnează
sign.header=Semnează documente PDF
sign.upload=Încarcă Imaginea
@ -171,14 +323,20 @@ sign.text=Introdu Textul
sign.clear=Curăță
sign.add=Adaugă
#repair
repair.title=Repară
repair.header=Repară documente PDF
repair.submit=Repară
#flatten
flatten.title=Nivelare
flatten.header=Nivelează documente PDF
flatten.submit=Nivelează
#ScannerImageSplit
ScannerImageSplit.selectText.1=Prag unghi:
ScannerImageSplit.selectText.2=Stabilește unghiul absolut minim necesar pentru ca imaginea să fie rotită (implicit: 5).
ScannerImageSplit.selectText.3=Toleranță:
@ -190,19 +348,6 @@ ScannerImageSplit.selectText.8=Stabilește pragul minim de arie a conturului pen
ScannerImageSplit.selectText.9=Mărimea marginii:
ScannerImageSplit.selectText.10=Stabilește mărimea marginii adăugate și eliminate pentru a evita marginile albe în rezultat (implicit: 1).
navbar.settings=Setări
settings.title=Setări
settings.update=Actualizare disponibilă
settings.appVersion=Versiune aplicație:
settings.downloadOption.title=Alege opțiunea de descărcare (pentru descărcarea unui singur fișier non-zip):
settings.downloadOption.1=Deschide în aceeași fereastră
settings.downloadOption.2=Deschide într-o fereastră nouă
settings.downloadOption.3=Descarcă fișierul
settings.zipThreshold=Împachetează fișierele când numărul de fișiere descărcate depășește
#OCR
ocr.title=OCR / Curățare scanare
@ -223,6 +368,8 @@ ocr.help=Citiți documentația pentru a afla cum să utilizați acest serviciu p
ocr.credit=Acest serviciu utilizează OCRmyPDF și Tesseract pentru OCR.
ocr.submit=Procesează PDF-ul cu OCR
#extractImages
extractImages.title=Extrage Imagini
extractImages.header=Extrage Imagini
extractImages.selectText=Selectați formatul imaginii în care să se convertească imaginile extrase
@ -246,10 +393,9 @@ compress.selectText.2=0 (Fără optimizare)
compress.selectText.3=1 (Implicit, optimizare fără pierdere)
compress.selectText.4=2 (Optimizare cu pierdere)
compress.selectText.5=3 (Optimizare cu pierdere, mai agresivă)
compress.selectText.6=Activare vizualizare rapidă pe web (linearizare PDF)
compress.selectText.7=Activare codificare JBIG2 cu pierdere
compress.submit=Comprimare
#Add image
addImage.title=Adăugare imagine
addImage.header=Adăugare imagine în PDF
@ -257,32 +403,38 @@ addImage.everyPage=Pe fiecare pagină?
addImage.upload=Adăugare imagine
addImage.submit=Adăugare imagine
#merge
merge.title=Unire
merge.header=Unirea mai multor PDF-uri (2+)
merge.submit=Unire
#pdfOrganiser
pdfOrganiser.title=Organizator de pagini
pdfOrganiser.header=Organizator de pagini PDF
pdfOrganiser.submit=Rearanjați paginile
#multiTool
multiTool.title=Instrument PDF multiplu
multiTool.header=Instrument PDF multiplu
#pageRemover
pageRemover.title=Înlăturare pagini
pageRemover.header=Înlăturare pagini din PDF
pageRemover.pagesToDelete=Pagini de șters (Introduceți o listă de numere de pagini separate prin virgulă):
pageRemover.submit=Ștergere pagini
#rotate
rotate.title=Rotește PDF
rotate.header=Rotește PDF
rotate.selectAngle=Selectați un unghi de rotație (în multiplicate de 90 de grade):
rotate.submit=Rotește
#merge
split.title=Împarte PDF
split.header=Împarte PDF
@ -308,6 +460,7 @@ imageToPDF.selectText.3=Logica pentru mai multe fișiere (activată numai dacă
imageToPDF.selectText.4=Unifică într-un singur PDF
imageToPDF.selectText.5=Convertă în PDF-uri separate
#pdfToImage
pdfToImage.title=PDF în Imagine
pdfToImage.header=PDF în Imagine
@ -321,6 +474,7 @@ pdfToImage.grey=Scală de gri
pdfToImage.blackwhite=Alb și negru (Poate pierde date!)
pdfToImage.submit=Convertă
#addPassword
addPassword.title=Adăugați parolă
addPassword.header=Adăugați o parolă (Criptare)
@ -342,6 +496,7 @@ addPassword.selectText.15=Restricts what can be done with the document once it i
addPassword.selectText.16=Restricts the opening of the document itself
addPassword.submit=Criptare
#watermark
watermark.title=Adăugați Filigran
watermark.header=Adăugați Filigran
@ -354,6 +509,7 @@ watermark.selectText.6=heightSpacer (Spațiu între fiecare filigran pe vertical
watermark.selectText.7=Opacitate (0% - 100%):
watermark.submit=Adăugați Filigran
#remove-watermark
remove-watermark.title=Eliminați Filigran
remove-watermark.header=Eliminați Filigran
@ -361,6 +517,7 @@ remove-watermark.selectText.1=Selectați PDF-ul de la care să eliminați filigr
remove-watermark.selectText.2=Textul Filigranului:
remove-watermark.submit=Eliminați Filigran
#Change permissions
permissions.title=Schimbați Permisiunile
permissions.header=Schimbați Permisiunile
@ -377,6 +534,7 @@ permissions.selectText.9=Preveniți tipărirea
permissions.selectText.10=Preveniți tipărirea în formate diferite
permissions.submit=Schimbare
#remove password
removePassword.title=Eliminați parola
removePassword.header=Eliminați parola (Decodificați)
@ -384,7 +542,9 @@ removePassword.selectText.1=Selectați PDF-ul pentru decodificare
removePassword.selectText.2=Parolă
removePassword.submit=Eliminați
changeMetadata.title=Schimbați Metadatele
#changeMetadata
changeMetadata.title=Titlu:
changeMetadata.header=Schimbați Metadatele
changeMetadata.selectText.1=Vă rugăm să editați variabilele pe care doriți să le schimbați
changeMetadata.selectText.2=Ștergeți toate metadatele
@ -402,39 +562,53 @@ changeMetadata.selectText.4=Alte Metadate:
changeMetadata.selectText.5=Adăugați Intrare Metadate Personalizate
changeMetadata.submit=Schimbare
#xlsToPdf
xlsToPdf.title=Excel to PDF
xlsToPdf.header=Excel to PDF
xlsToPdf.selectText.1=Selectați fișierul Excel XLS sau XLSX pentru a converti
xlsToPdf.convert=convert
#pdfToPDFA
pdfToPDFA.title=PDF către PDF/A
pdfToPDFA.header=PDF către PDF/A
pdfToPDFA.credit=Acest serviciu utilizează OCRmyPDF pentru conversia în PDF/A
pdfToPDFA.submit=Convert
#PDFToWord
PDFToWord.title=PDF către Word
PDFToWord.header=PDF către Word
PDFToWord.selectText.1=Format fișier de ieșire
PDFToWord.credit=Acest serviciu utilizează LibreOffice pentru conversia fișierului.
PDFToWord.submit=Convert
#PDFToPresentation
PDFToPresentation.title=PDF către Prezentare
PDFToPresentation.header=PDF către Prezentare
PDFToPresentation.selectText.1=Format fișier de ieșire
PDFToPresentation.credit=Acest serviciu utilizează LibreOffice pentru conversia fișierului.
PDFToPresentation.submit=Convert
#PDFToText
PDFToText.title=PDF către Text/RTF
PDFToText.header=PDF către Text/RTF
PDFToText.selectText.1=Format fișier de ieșire
PDFToText.credit=Acest serviciu utilizează LibreOffice pentru conversia fișierului.
PDFToText.submit=Convert
#PDFToHTML
PDFToHTML.title=PDF către HTML
PDFToHTML.header=PDF către HTML
PDFToHTML.credit=Acest serviciu utilizează LibreOffice pentru conversia fișierului.
PDFToHTML.submit=Convert
#PDFToXML
PDFToXML.title=PDF către XML
PDFToXML.header=PDF către XML
PDFToXML.credit=Acest serviciu utilizează LibreOffice pentru conversia fișierului.

View file

@ -21,23 +21,62 @@ filesSelected=файлов выбрано
noFavourites=Нет избранного
bored=Скучно ждать?
alphabet=\u0430\u043B\u0444\u0430\u0432\u0438\u0442
downloadPdf=Скачать PDF
text=Текст
font=Шрифт
selectFillter=-- Выбрать --
pageNum=номер страницы
##########################
### TODO: Translate ###
##########################
sizes.small=Small
sizes.medium=Medium
sizes.large=Large
sizes.x-large=X-Large
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
#############
# NAVBAR #
#############
navbar.convert=Конвертировать
navbar.security=Безопасность
navbar.other=Другое
navbar.darkmode=Темный режим
navbar.pageOps=Операции со страницей
navbar.settings=Настройки
#############
# SETTINGS #
#############
settings.title=Настройки
settings.update=Доступно обновление
settings.appVersion=Версия приложения:
settings.downloadOption.title=Выберите вариант загрузки (для загрузки одного файла без zip):
settings.downloadOption.1=Открыть в том же окне
settings.downloadOption.2=Открыть в новом окне
settings.downloadOption.3=Загрузить файл
settings.zipThreshold=Zip-файлы, когда количество загруженных файлов превышает
#############
# HOME-PAGE #
#############
home.desc=Ваш локальный универсальный магазин для всех ваших потребностей в PDF.
navbar.convert=Конвертировать
navbar.security=Безопасность
navbar.other=Другое
navbar.darkmode=Темный режим
navbar.pageOps=Операции со страницей
home.multiTool.title=Мультиинструмент PDF
home.multiTool.desc=Объединение, поворот, изменение порядка и удаление страниц
##########################
### TODO: Translate ###
##########################
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
home.merge.title=Объединить
home.merge.desc=Легко объединяйте несколько PDF-файлов в один.
##########################
### TODO: Translate ###
##########################
merge.tags=merge,Page operations,Back end,server side
home.split.title=Разделить
home.split.desc=Разделить PDF-файлы на несколько документов
@ -60,9 +99,6 @@ home.addImage.desc=Добавляет изображение в заданное
home.watermark.title=Добавить водяной знак
home.watermark.desc=Добавьте собственный водяной знак в документ PDF.
home.remove-watermark.title=Удалить водяной знак
home.remove-watermark.desc=Удалите водяные знаки из документа PDF.
home.permissions.title=Изменить разрешения
home.permissions.desc=Измените разрешения вашего PDF-документа
@ -135,25 +171,116 @@ home.pageLayout.desc=Merge multiple pages of a PDF document into a single page
home.scalePages.title=Adjust page size/scale
home.scalePages.desc=Change the size/scale of page and/or its contents.
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
##########################
### TODO: Translate ###
##########################
home.pipeline.title=Pipeline (Advanced)
home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts
downloadPdf=Скачать PDF
text=Текст
font=Шрифт
selectFillter=-- Выбрать --
pageNum=номер страницы
home.add-page-numbers.title=Add Page Numbers
home.add-page-numbers.desc=Add Page numbers throughout a document in a set location
home.auto-rename.title=Auto Rename PDF File
home.auto-rename.desc=Auto renames a PDF file based on its detected header
home.adjust-contrast.title=Adjust Colors/Contrast
home.adjust-contrast.desc=Adjust Contrast, Saturation and Brightness of a PDF
home.crop.title=Crop PDF
home.crop.desc=Crop a PDF to reduce its size (maintains text!)
home.autoSplitPDF.title=Auto Split Pages
home.autoSplitPDF.desc=Auto Split Scanned PDF with physical scanned page splitter QR Code
home.sanitizePdf.title=Sanitize
home.sanitizePdf.desc=Remove scripts and other elements from PDF files
###########################
# #
# WEB PAGES #
# #
###########################
#sanitizePDF
sanitizePDF.title=Sanitize PDF
sanitizePDF.header=Sanitize a PDF file
sanitizePDF.selectText.1=Remove JavaScript actions
sanitizePDF.selectText.2=Remove embedded files
sanitizePDF.selectText.3=Remove metadata
sanitizePDF.selectText.4=Remove links
sanitizePDF.selectText.5=Remove fonts
sanitizePDF.submit=Sanitize PDF
#addPageNumbers
addPageNumbers.title=Add Page Numbers
addPageNumbers.header=Add Page Numbers
addPageNumbers.selectText.1=Select PDF file:
addPageNumbers.selectText.2=Margin Size
addPageNumbers.selectText.3=Position
addPageNumbers.selectText.4=Starting Number
addPageNumbers.selectText.5=Pages to Number
addPageNumbers.selectText.6=Custom Text
addPageNumbers.submit=Add Page Numbers
#auto-rename
auto-rename.title=Auto Rename
auto-rename.header=Auto Rename PDF
auto-rename.submit=Auto Rename
#adjustContrast
adjustContrast.title=Adjust Contrast
adjustContrast.header=Adjust Contrast
adjustContrast.contrast=Contrast:
adjustContrast.brightness=Brightness:
adjustContrast.saturation=Saturation:
adjustContrast.download=Download
#crop
crop.title=Crop
crop.header=Crop Image
crop.submit=Submit
#autoSplitPDF
autoSplitPDF.title=Auto Split PDF
autoSplitPDF.header=Auto Split PDF
autoSplitPDF.description=Print, Insert, Scan, upload, and let us auto-separate your documents. No manual work sorting needed.
autoSplitPDF.selectText.1=Print out some divider sheets from below (Black and white is fine).
autoSplitPDF.selectText.2=Scan all your documents at once by inserting the divider sheet between them.
autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirling PDF handle the rest.
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
autoSplitPDF.submit=Submit
#pipeline
pipeline.title=Pipeline
#pageLayout
pageLayout.title=Multi Page Layout
pageLayout.header=Multi Page Layout
pageLayout.pagesPerSheet=Pages per sheet:
pageLayout.submit=Submit
#scalePages
scalePages.title=Adjust page-scale
scalePages.header=Adjust page-scale
scalePages.pageSize=Size of a page of the document.
scalePages.scaleFactor=Zoom level (crop) of a page.
scalePages.submit=Submit
#certSign
certSign.title=Подписание сертификата
certSign.header=Подпишите PDF своим сертификатом (работа в процессе)
certSign.selectPDF=Выберите файл PDF для подписи:
@ -168,6 +295,8 @@ certSign.location=Местоположение
certSign.name=Имя
certSign.submit=Подписать PDF
#removeBlanks
removeBlanks.title=Удалить Пустые
removeBlanks.header=Удалить Пустые Страницы
removeBlanks.threshold=Порог:
@ -176,12 +305,16 @@ removeBlanks.whitePercent=Процент Белого (%):
removeBlanks.whitePercentDesc=Общий процент белого на странице, для удаления
removeBlanks.submit=Удалить Пустые
#compare
compare.title=Сравнение
compare.header=Сравнение PDFы
compare.document.1=Документ 1
compare.document.2=Документ 2
compare.submit=Сравнить
#sign
sign.title=Подпись
sign.header=Подписать PDFы
sign.upload=Загрузить изображение
@ -190,14 +323,20 @@ sign.text=Ввод текста
sign.clear=Очистить
sign.add=Добавить
#repair
repair.title=Ремонт
repair.header=Ремонт PDF ов
repair.submit=Ремонт
#flatten
flatten.title=Сглаживание
flatten.header=Сглаживание PDF ов
flatten.submit=Сгладить
#ScannerImageSplit
ScannerImageSplit.selectText.1=Угловой порог:
ScannerImageSplit.selectText.2=Устанавливает минимальный абсолютный угол, необходимый для поворота изображения (по умолчанию: 10).
ScannerImageSplit.selectText.3=Допуск:
@ -209,19 +348,6 @@ ScannerImageSplit.selectText.8=Устанавливает минимальный
ScannerImageSplit.selectText.9=Размер границы:
ScannerImageSplit.selectText.10=Устанавливает размер добавляемой и удаляемой границы, чтобы предотвратить появление белых границ на выходе (по умолчанию: 1).
navbar.settings=Настройки
settings.title=Настройки
settings.update=Доступно обновление
settings.appVersion=Версия приложения:
settings.downloadOption.title=Выберите вариант загрузки (для загрузки одного файла без zip):
settings.downloadOption.1=Открыть в том же окне
settings.downloadOption.2=Открыть в новом окне
settings.downloadOption.3=Загрузить файл
settings.zipThreshold=Zip-файлы, когда количество загруженных файлов превышает
#OCR
ocr.title=OCR / Очистка сканирования
@ -243,7 +369,7 @@ ocr.credit=Этот сервис использует OCRmyPDF и Tesseract дл
ocr.submit=Обработка PDF с OCR
#extractImages
extractImages.title=Извлечь изображения
extractImages.header=Извлечь изображения
extractImages.selectText=Выберите формат изображения для преобразования извлеченных изображений в
@ -283,11 +409,13 @@ merge.title=Объединить
merge.header=Объединение нескольких PDF-файлов (2+)
merge.submit=Объединить
#pdfOrganiser
pdfOrganiser.title=Организатор страниц
pdfOrganiser.header=Организатор PDF-страниц
pdfOrganiser.submit=Переупорядочить страницы
#multiTool
multiTool.title=Мультиинструмент PDF
multiTool.header=Мультиинструмент PDF
@ -299,6 +427,7 @@ pageRemover.header=Удаление PDF-страниц
pageRemover.pagesToDelete=Страницы для удаления (введите список номеров страниц через запятую):
pageRemover.submit=Удалить страницы
#rotate
rotate.title=Повернуть PDF
rotate.header=Повернуть PDF
@ -306,8 +435,6 @@ rotate.selectAngle=Выберите угол поворота (кратный 90
rotate.submit=Повернуть
#merge
split.title=Разделить PDF
split.header=Разделить PDF
@ -333,6 +460,7 @@ imageToPDF.selectText.3=Многофайловая логика (включен
imageToPDF.selectText.4=Объединить в один PDF
imageToPDF.selectText.5=Преобразование в отдельные PDF-файлы
#pdfToImage
pdfToImage.title=PDF в изображение
pdfToImage.header=PDF в изображение
@ -346,6 +474,7 @@ pdfToImage.grey=Оттенки серого
pdfToImage.blackwhite=Черно-белый (может потерять данные!)
pdfToImage.submit=Конвертировать
#addPassword
addPassword.title=Добавить пароль
addPassword.header=Добавить пароль (зашифровать)
@ -367,6 +496,7 @@ addPassword.selectText.15=Restricts what can be done with the document once it i
addPassword.selectText.16=Restricts the opening of the document itself
addPassword.submit=Шифровать
#watermark
watermark.title=Добавить водяной знак
watermark.header=Добавить водяной знак
@ -379,6 +509,7 @@ watermark.selectText.6=heightSpacer (пробел между каждым вод
watermark.selectText.7=Непрозрачность (0% - 100%):
watermark.submit=Добавить водяной знак
#remove-watermark
remove-watermark.title=Удалить водяной знак
remove-watermark.header=Удалить водяной знак
@ -386,6 +517,7 @@ remove-watermark.selectText.1=Выберите PDF, чтобы удалить в
remove-watermark.selectText.2=Текст водяного знака:
remove-watermark.submit=Удалить водяной знак
#Change permissions
permissions.title=Изменить разрешения
permissions.header=Изменить разрешения
@ -402,6 +534,7 @@ permissions.selectText.9=Запретить печать
permissions.selectText.10=Запретить печать разных форматов
permissions.submit=Изменить
#remove password
removePassword.title=Удалить пароль
removePassword.header=Удалить пароль (Расшифровка)
@ -409,7 +542,9 @@ removePassword.selectText.1=Выберите PDF для расшифровки
removePassword.selectText.2=Пароль
removePassword.submit=Удалить
changeMetadata.title=Изменить метаданные
#changeMetadata
changeMetadata.title=Заголовок:
changeMetadata.header=Изменить метаданные
changeMetadata.selectText.1=Пожалуйста, отредактируйте переменные, которые вы хотите изменить
changeMetadata.selectText.2=Удалить все метаданные
@ -427,27 +562,30 @@ changeMetadata.selectText.4=Другие метаданные:
changeMetadata.selectText.5=Добавить пользовательскую запись метаданных
changeMetadata.submit=Изменить
#xlsToPdf
xlsToPdf.title=Excel в PDF
xlsToPdf.header=Excel в PDF
xlsToPdf.selectText.1=Выберите книгу Excel XLS или XLSX для преобразования
xlsToPdf.convert=Конвертировать
#pdfToPDFA
pdfToPDFA.title=PDF в PDF/A
pdfToPDFA.header=PDF в PDF/A
pdfToPDFA.credit=Этот сервис использует OCRmyPDF для преобразования PDF/A
pdfToPDFA.submit=Конвертировать
#PDFToWord
PDFToWord.title=PDF в Word
PDFToWord.header=PDF в Word
PDFToWord.selectText.1=Формат выходного файла
PDFToWord.credit=Этот сервис использует LibreOffice для преобразования файлов.
PDFToWord.submit=Конвертировать
#PDFToPresentation
PDFToPresentation.title=PDF в Презентацию
PDFToPresentation.header=PDF в Презентацию
PDFToPresentation.selectText.1=Формат выходного файла
@ -455,6 +593,7 @@ PDFToPresentation.credit=Этот сервис использует LibreOffice
PDFToPresentation.submit=Конвертировать
#PDFToText
PDFToText.title=PDF в Text/RTF
PDFToText.header=PDF в Text/RTF
PDFToText.selectText.1=Формат выходного файла
@ -462,24 +601,15 @@ PDFToText.credit=Этот сервис использует LibreOffice для
PDFToText.submit=Конвертировать
#PDFToHTML
PDFToHTML.title=PDF в HTML
PDFToHTML.header=PDF в HTML
PDFToHTML.credit=Этот сервис использует LibreOffice для преобразования файлов.
PDFToHTML.submit=Конвертировать
#PDFToXML
PDFToXML.title=PDF в XML
PDFToXML.header=PDF в XML
PDFToXML.credit=Этот сервис использует LibreOffice для преобразования файлов.
PDFToXML.submit=Конвертировать

View file

@ -1,7 +1,7 @@
###########
# Generisk #
# Generic #
###########
# riktningen som språket skrivs (ltr = vänster till höger, rtl = höger till vänster)
# the direction that the language is written (ltr = left to right, rtl = right to left)
language.direction=ltr
pdfPrompt=Välj PDF(er)
@ -12,7 +12,10 @@ genericSubmit=Skicka
processTimeWarning=Varning: Denna process kan ta upp till en minut beroende på filstorlek
pageOrderPrompt=Sidordning (Ange en kommaseparerad lista med sidnummer) :
goToPage=Gå till
sant=Sant
##########################
### TODO: Translate ###
##########################
true=True
false=Falskt
unknown=Okänt
save=Spara
@ -21,23 +24,62 @@ filesSelected=filer valda
noFavourites=Inga favoriter har lagts till
bored=Utråkad att vänta?
alphabet=Alfabet
#############
# HEMSIDA #
#############
home.desc=Din lokala one-stop-shop för alla dina PDF-behov.
downloadPdf=Ladda ner PDF
text=Text
font=Teckensnitt
selectFillter=-- Välj --
pageNum=Sidnummer
##########################
### TODO: Translate ###
##########################
sizes.small=Small
sizes.medium=Medium
sizes.large=Large
sizes.x-large=X-Large
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
#############
# NAVBAR #
#############
navbar.convert=Konvertera
navbar.security=Säkerhet
navbar.other=Annat
navbar.darkmode=Mörkt läge
navbar.pageOps=Sidoperationer
navbar.settings=Inställningar
#############
# SETTINGS #
#############
settings.title=Inställningar
settings.update=Uppdatering tillgänglig
settings.appVersion=Appversion:
settings.downloadOption.title=Välj nedladdningsalternativ (för nedladdning av en fil utan zip):
settings.downloadOption.1=Öppnas i samma fönster
settings.downloadOption.2=Öppna i nytt fönster
settings.downloadOption.3=Ladda ner fil
settings.zipThreshold=Zip-filer när antalet nedladdade filer överskrider
#############
# HOME-PAGE #
#############
home.desc=Din lokala one-stop-shop för alla dina PDF-behov.
home.multiTool.title=PDF Multi-verktyg
home.multiTool.desc=Sammanfoga, rotera, ordna om och ta bort sidor
##########################
### TODO: Translate ###
##########################
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
home.merge.title=Sammanfoga
home.merge.desc=Sammanfoga enkelt flera PDF-filer till en.
##########################
### TODO: Translate ###
##########################
merge.tags=merge,Page operations,Back end,server side
home.split.title=Dela
home.split.desc=Dela upp PDF-filer i flera dokument
@ -60,9 +102,6 @@ home.addImage.desc=Lägger till en bild på en angiven plats i PDF:en (pågår a
home.watermark.title=Lägg till vattenstämpel
home.watermark.desc=Lägg till en anpassad vattenstämpel till ditt PDF-dokument.
home.remove-watermark.title=Ta bort vattenstämpel
home.remove-watermark.desc=Ta bort vattenstämplar från ditt PDF-dokument.
home.permissions.title=Ändra behörigheter
home.permissions.desc=Ändra behörigheterna för ditt PDF-dokument
@ -135,25 +174,116 @@ home.pageLayout.desc=Merge multiple pages of a PDF document into a single page
home.scalePages.title=Adjust page size/scale
home.scalePages.desc=Change the size/scale of page and/or its contents.
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
##########################
### TODO: Translate ###
##########################
home.pipeline.title=Pipeline (Advanced)
home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts
downloadPdf=Ladda ner PDF
text=Text
font=Teckensnitt
selectFillter=-- Välj --
pageNum=Sidnummer
home.add-page-numbers.title=Add Page Numbers
home.add-page-numbers.desc=Add Page numbers throughout a document in a set location
home.auto-rename.title=Auto Rename PDF File
home.auto-rename.desc=Auto renames a PDF file based on its detected header
home.adjust-contrast.title=Adjust Colors/Contrast
home.adjust-contrast.desc=Adjust Contrast, Saturation and Brightness of a PDF
home.crop.title=Crop PDF
home.crop.desc=Crop a PDF to reduce its size (maintains text!)
home.autoSplitPDF.title=Auto Split Pages
home.autoSplitPDF.desc=Auto Split Scanned PDF with physical scanned page splitter QR Code
home.sanitizePdf.title=Sanitize
home.sanitizePdf.desc=Remove scripts and other elements from PDF files
###########################
# #
# WEB PAGES #
# #
###########################
#sanitizePDF
sanitizePDF.title=Sanitize PDF
sanitizePDF.header=Sanitize a PDF file
sanitizePDF.selectText.1=Remove JavaScript actions
sanitizePDF.selectText.2=Remove embedded files
sanitizePDF.selectText.3=Remove metadata
sanitizePDF.selectText.4=Remove links
sanitizePDF.selectText.5=Remove fonts
sanitizePDF.submit=Sanitize PDF
#addPageNumbers
addPageNumbers.title=Add Page Numbers
addPageNumbers.header=Add Page Numbers
addPageNumbers.selectText.1=Select PDF file:
addPageNumbers.selectText.2=Margin Size
addPageNumbers.selectText.3=Position
addPageNumbers.selectText.4=Starting Number
addPageNumbers.selectText.5=Pages to Number
addPageNumbers.selectText.6=Custom Text
addPageNumbers.submit=Add Page Numbers
#auto-rename
auto-rename.title=Auto Rename
auto-rename.header=Auto Rename PDF
auto-rename.submit=Auto Rename
#adjustContrast
adjustContrast.title=Adjust Contrast
adjustContrast.header=Adjust Contrast
adjustContrast.contrast=Contrast:
adjustContrast.brightness=Brightness:
adjustContrast.saturation=Saturation:
adjustContrast.download=Download
#crop
crop.title=Crop
crop.header=Crop Image
crop.submit=Submit
#autoSplitPDF
autoSplitPDF.title=Auto Split PDF
autoSplitPDF.header=Auto Split PDF
autoSplitPDF.description=Print, Insert, Scan, upload, and let us auto-separate your documents. No manual work sorting needed.
autoSplitPDF.selectText.1=Print out some divider sheets from below (Black and white is fine).
autoSplitPDF.selectText.2=Scan all your documents at once by inserting the divider sheet between them.
autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirling PDF handle the rest.
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
autoSplitPDF.submit=Submit
#pipeline
pipeline.title=Pipeline
#pageLayout
pageLayout.title=Multi Page Layout
pageLayout.header=Multi Page Layout
pageLayout.pagesPerSheet=Pages per sheet:
pageLayout.submit=Submit
#scalePages
scalePages.title=Adjust page-scale
scalePages.header=Adjust page-scale
scalePages.pageSize=Size of a page of the document.
scalePages.scaleFactor=Zoom level (crop) of a page.
scalePages.submit=Submit
#certSign
certSign.title=Certifikatsignering
certSign.header=Skriv under en PDF med ditt certifikat (Pågående arbete)
certSign.selectPDF=Välj en PDF-fil för signering:
@ -168,6 +298,8 @@ certSign.location=Plats
certSign.name=Namn
certSign.submit=Skriv under PDF
#removeBlanks
removeBlanks.title=Ta bort tomrum
removeBlanks.header=Ta bort tomma sidor
removeBlanks.threshold=Tröskel:
@ -176,12 +308,16 @@ removeBlanks.whitePercent=Vit procent (%):
removeBlanks.whitePercentDesc=Procentandel av sidan som måste vara vit för att kunna tas bort
removeBlanks.submit=Ta bort tomrum
#compare
compare.title=Jämför
compare.header=Jämför PDF-filer
compare.document.1=Dokument 1
compare.document.2=Dokument 2
compare.submit=Jämför
#sign
sign.title=Signera
sign.header=Skriv under PDF-filer
sign.upload=Ladda upp bild
@ -190,14 +326,20 @@ sign.text=Textinmatning
sign.clear=Rensa
sign.add=Lägg till
#repair
repair.title=Reparera
repair.header=Reparera PDF-filer
repair.submit=Reparera
#flatten
flatten.title=Platta till
flatten.header=Placera PDF-filer
flatten.submit=Platta till
#ScannerImageSplit
ScannerImageSplit.selectText.1=Vinkeltröskel:
ScannerImageSplit.selectText.2=Ställer in den minsta absoluta vinkeln som krävs för att bilden ska roteras (standard: 10).
ScannerImageSplit.selectText.3=Tolerans:
@ -209,19 +351,6 @@ ScannerImageSplit.selectText.8=Ställer in minsta tröskelvärde för konturarea
ScannerImageSplit.selectText.9=Kantstorlek:
ScannerImageSplit.selectText.10=Ställer in storleken på kanten som läggs till och tas bort för att förhindra vita kanter i utdata (standard: 1).
navbar.settings=Inställningar
settings.title=Inställningar
settings.update=Uppdatering tillgänglig
settings.appVersion=Appversion:
settings.downloadOption.title=Välj nedladdningsalternativ (för nedladdning av en fil utan zip):
settings.downloadOption.1=Öppnas i samma fönster
settings.downloadOption.2=Öppna i nytt fönster
settings.downloadOption.3=Ladda ner fil
settings.zipThreshold=Zip-filer när antalet nedladdade filer överskrider
#OCR
ocr.title=OCR / Scan Cleanup
@ -243,14 +372,14 @@ ocr.credit=Denna tjänst använder OCRmyPDF och Tesseract för OCR.
ocr.submit=Bearbeta PDF med OCR
#extractImages
extractImages.title=Extrahera bilder
extractImages.header=Extrahera bilder
extractImages.selectText=Välj bildformat att konvertera extraherade bilder till
extractImages.submit=Extrahera
#Fil till PDF
#File to PDF
fileToPDF.title=Fil till PDF
fileToPDF.header=Konvertera valfri fil till PDF
fileToPDF.credit=Denna tjänst använder LibreOffice och Unoconv för filkonvertering.
@ -258,7 +387,7 @@ fileToPDF.supportedFileTypes=Filtyper som stöds bör inkludera nedanstående me
fileToPDF.submit=Konvertera till PDF
#komprimera
#compress
compress.title=Komprimera
compress.header=Komprimera PDF
compress.credit=Denna tjänst använder Ghostscript för PDF-komprimering/optimering.
@ -270,7 +399,7 @@ compress.selectText.5=Förväntad PDF-storlek (t.ex. 25MB, 10,8MB, 25KB)
compress.submit=Komprimera
#Lägg till bild
#Add image
addImage.title=Lägg till bild
addImage.header=Lägg till bild till PDF
addImage.everyPage=Varje sida?
@ -278,17 +407,19 @@ addImage.upload=Lägg till bild
addImage.submit=Lägg till bild
#sammanfoga
#merge
merge.title=Sammanfoga
merge.header=Slå samman flera PDF-filer (2+)
merge.submit=Slå samman
#pdfArrangör
#pdfOrganiser
pdfOrganiser.title=Sidorganisatör
pdfOrganiser.header=PDF-sidorganisatör
pdfOrganiser.submit=Ordna om sidor
#multiverktyg
#multiTool
multiTool.title=PDF-multiverktyg
multiTool.header=PDF Multi-verktyg
@ -299,16 +430,15 @@ pageRemover.header=PDF Sidborttagning
pageRemover.pagesToDelete=Sidor att radera (Ange en kommaseparerad lista med sidnummer) :
pageRemover.submit=Ta bort sidor
#rotera
#rotate
rotate.title=Rotera PDF
rotate.header=Rotera PDF
rotate.selectAngle=Välj rotationsvinkel (i multipler av 90 grader):
rotate.submit=Rotera
#sammanfoga
#merge
split.title=Dela upp PDF
split.header=Dela upp PDF
split.desc.1=Siffrorna du väljer är sidnumret du vill göra en split på
@ -323,7 +453,7 @@ split.splitPages=Ange sidor att dela på:
split.submit=Dela
#sammanfoga
#merge
imageToPDF.title=Bild till PDF
imageToPDF.header=Bild till PDF
imageToPDF.submit=Konvertera
@ -333,6 +463,7 @@ imageToPDF.selectText.3=Multifillogik (Endast aktiverad om man arbetar med flera
imageToPDF.selectText.4=Slå samman till en enda PDF
imageToPDF.selectText.5=Konvertera till separata PDF-filer
#pdfToImage
pdfToImage.title=PDF till bild
pdfToImage.header=PDF till bild
@ -346,6 +477,7 @@ pdfToImage.grey=Gråskala
pdfToImage.blackwhite=Svartvitt (kan förlora data!)
pdfToImage.submit=Konvertera
#addPassword
addPassword.title=Lägg till lösenord
addPassword.header=Lägg till lösenord (kryptera)
@ -367,7 +499,8 @@ addPassword.selectText.15=Restricts what can be done with the document once it i
addPassword.selectText.16=Restricts the opening of the document itself
addPassword.submit=Kryptera
#vattenstämpel
#watermark
watermark.title=Lägg till vattenstämpel
watermark.header=Lägg till vattenstämpel
watermark.selectText.1=Välj PDF för att lägga till vattenstämpel till:
@ -379,6 +512,7 @@ watermark.selectText.6=heightSpacer (mellanrum mellan varje vattenstämpel verti
watermark.selectText.7=Opacitet (0% - 100%):
watermark.submit=Lägg till vattenstämpel
#remove-watermark
remove-watermark.title=Ta bort vattenstämpel
remove-watermark.header=Ta bort vattenstämpel
@ -386,7 +520,8 @@ remove-watermark.selectText.1=Välj PDF för att ta bort vattenstämpel från:
remove-watermark.selectText.2=Vattenstämpeltext:
remove-watermark.submit=Ta bort vattenstämpel
#Ändra behörigheter
#Change permissions
permissions.title=Ändra behörigheter
permissions.header=Ändra behörigheter
permissions.warning=Varning för att dessa behörigheter ska vara oföränderliga, det rekommenderas att ställa in dem med ett lösenord via sidan Lägg till lösenord
@ -402,14 +537,17 @@ permissions.selectText.9=Förhindra utskrift
permissions.selectText.10=Förhindra utskrift av olika format
permissions.submit=Ändra
#ta bort lösenord
#remove password
removePassword.title=Ta bort lösenord
removePassword.header=Ta bort lösenord (Dekryptera)
removePassword.selectText.1=Välj PDF att dekryptera
removePassword.selectText.2=Lösenord
removePassword.submit=Ta bort
changeMetadata.title=Ändra metadata
#changeMetadata
changeMetadata.title=Titel:
changeMetadata.header=Ändra metadata
changeMetadata.selectText.1=Redigera de variabler du vill ändra
changeMetadata.selectText.2=Ta bort all metadata
@ -427,27 +565,30 @@ changeMetadata.selectText.4=Andra metadata:
changeMetadata.selectText.5=Lägg till anpassad metadatapost
changeMetadata.submit=Ändra
#xlsToPdf
xlsToPdf.title=Excel till PDF
xlsToPdf.header=Excel till PDF
xlsToPdf.selectText.1=Välj XLS eller XLSX Excel-ark att konvertera
xlsToPdf.convert=konvertera
#pdfToPDFA
pdfToPDFA.title=PDF till PDF/A
pdfToPDFA.header=PDF till PDF/A
pdfToPDFA.credit=Denna tjänst använder OCRmyPDF för PDF/A-konvertering
pdfToPDFA.submit=Konvertera
#PDFToWord
PDFToWord.title=PDF till Word
PDFToWord.header=PDF till Word
PDFToWord.selectText.1=Utdatafilformat
PDFToWord.credit=Denna tjänst använder LibreOffice för filkonvertering.
PDFToWord.submit=Konvertera
#PDFToPresentation
PDFToPresentation.title=PDF till presentation
PDFToPresentation.header=PDF till presentation
PDFToPresentation.selectText.1=Utdatafilformat
@ -455,6 +596,7 @@ PDFToPresentation.credit=Denna tjänst använder LibreOffice för filkonverterin
PDFToPresentation.submit=Konvertera
#PDFToText
PDFToText.title=PDF till text/RTF
PDFToText.header=PDF till text/RTF
PDFToText.selectText.1=Utdatafilformat
@ -462,24 +604,15 @@ PDFToText.credit=Denna tjänst använder LibreOffice för filkonvertering.
PDFToText.submit=Konvertera
#PDFToHTML
PDFToHTML.title=PDF till HTML
PDFToHTML.header=PDF till HTML
PDFToHTML.credit=Denna tjänst använder LibreOffice för filkonvertering.
PDFToHTML.submit=Konvertera
#PDFToXML
PDFToXML.title=PDF till XML
PDFToXML.header=PDF till XML
PDFToXML.credit=Denna tjänst använder LibreOffice för filkonvertering.
PDFToXML.submit=Konvertera

View file

@ -21,23 +21,62 @@ filesSelected=\u9009\u62E9\u7684\u6587\u4EF6
noFavourites=\u6CA1\u6709\u6DFB\u52A0\u6536\u85CF\u5939
bored=\u65E0\u804A\u7B49\u5F85\uFF1F
alphabet=\u5B57\u6BCD\u8868
downloadPdf=\u4E0B\u8F7DPDF
text=\u6587\u672C
font=\u5B57\u4F53
selectFillter=-- 选择--
pageNum=页码
##########################
### TODO: Translate ###
##########################
sizes.small=Small
sizes.medium=Medium
sizes.large=Large
sizes.x-large=X-Large
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
#############
# NAVBAR #
#############
navbar.convert=转换
navbar.security=安全
navbar.other=其他
navbar.darkmode=暗模式
navbar.pageOps=页面操作
navbar.settings=设置
#############
# SETTINGS #
#############
settings.title=设置
settings.update=可更新
settings.appVersion=应用程序版本:
settings.downloadOption.title=选择下载选项(单个文件非压缩文件):
settings.downloadOption.1=在同一窗口打开
settings.downloadOption.2=在新窗口中打开
settings.downloadOption.3=下载文件
settings.zipThreshold=当下载的文件数量超过限制时,将文件压缩。
#############
# HOME-PAGE #
#############
home.desc=您的本地托管一站式服务满足您的所有PDF需求。
navbar.convert=转换
navbar.security=安全
navbar.other=其他
navbar.darkmode=暗模式
navbar.pageOps=页面操作
home.multiTool.title=PDF多功能工具
home.multiTool.desc=合并、旋转、重新排列和删除PDF页面
##########################
### TODO: Translate ###
##########################
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
home.merge.title=合并
home.merge.desc=轻松合并多个PDF为一个。
##########################
### TODO: Translate ###
##########################
merge.tags=merge,Page operations,Back end,server side
home.split.title=拆分
home.split.desc=将 PDF 拆分为多个文档。
@ -60,9 +99,6 @@ home.addImage.desc=将图像添加到PDF的设定位置上
home.watermark.title=添加水印
home.watermark.desc=在PDF中添加一个自定义的水印。
home.remove-watermark.title=去除水印
home.remove-watermark.desc=从你的PDF文档中去除水印。
home.permissions.title=更改权限
home.permissions.desc=改变你的PDF文档的权限。
@ -135,25 +171,116 @@ home.pageLayout.desc=Merge multiple pages of a PDF document into a single page
home.scalePages.title=Adjust page size/scale
home.scalePages.desc=Change the size/scale of page and/or its contents.
error.pdfPassword=The PDF Document is passworded and either the password was not provided or was incorrect
##########################
### TODO: Translate ###
##########################
home.pipeline.title=Pipeline (Advanced)
home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts
downloadPdf=\u4E0B\u8F7DPDF
text=\u6587\u672C
font=\u5B57\u4F53
selectFillter=-- 选择--
pageNum=页码
home.add-page-numbers.title=Add Page Numbers
home.add-page-numbers.desc=Add Page numbers throughout a document in a set location
home.auto-rename.title=Auto Rename PDF File
home.auto-rename.desc=Auto renames a PDF file based on its detected header
home.adjust-contrast.title=Adjust Colors/Contrast
home.adjust-contrast.desc=Adjust Contrast, Saturation and Brightness of a PDF
home.crop.title=Crop PDF
home.crop.desc=Crop a PDF to reduce its size (maintains text!)
home.autoSplitPDF.title=Auto Split Pages
home.autoSplitPDF.desc=Auto Split Scanned PDF with physical scanned page splitter QR Code
home.sanitizePdf.title=Sanitize
home.sanitizePdf.desc=Remove scripts and other elements from PDF files
###########################
# #
# WEB PAGES #
# #
###########################
#sanitizePDF
sanitizePDF.title=Sanitize PDF
sanitizePDF.header=Sanitize a PDF file
sanitizePDF.selectText.1=Remove JavaScript actions
sanitizePDF.selectText.2=Remove embedded files
sanitizePDF.selectText.3=Remove metadata
sanitizePDF.selectText.4=Remove links
sanitizePDF.selectText.5=Remove fonts
sanitizePDF.submit=Sanitize PDF
#addPageNumbers
addPageNumbers.title=Add Page Numbers
addPageNumbers.header=Add Page Numbers
addPageNumbers.selectText.1=Select PDF file:
addPageNumbers.selectText.2=Margin Size
addPageNumbers.selectText.3=Position
addPageNumbers.selectText.4=Starting Number
addPageNumbers.selectText.5=Pages to Number
addPageNumbers.selectText.6=Custom Text
addPageNumbers.submit=Add Page Numbers
#auto-rename
auto-rename.title=Auto Rename
auto-rename.header=Auto Rename PDF
auto-rename.submit=Auto Rename
#adjustContrast
adjustContrast.title=Adjust Contrast
adjustContrast.header=Adjust Contrast
adjustContrast.contrast=Contrast:
adjustContrast.brightness=Brightness:
adjustContrast.saturation=Saturation:
adjustContrast.download=Download
#crop
crop.title=Crop
crop.header=Crop Image
crop.submit=Submit
#autoSplitPDF
autoSplitPDF.title=Auto Split PDF
autoSplitPDF.header=Auto Split PDF
autoSplitPDF.description=Print, Insert, Scan, upload, and let us auto-separate your documents. No manual work sorting needed.
autoSplitPDF.selectText.1=Print out some divider sheets from below (Black and white is fine).
autoSplitPDF.selectText.2=Scan all your documents at once by inserting the divider sheet between them.
autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirling PDF handle the rest.
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
autoSplitPDF.submit=Submit
#pipeline
pipeline.title=Pipeline
#pageLayout
pageLayout.title=Multi Page Layout
pageLayout.header=Multi Page Layout
pageLayout.pagesPerSheet=Pages per sheet:
pageLayout.submit=Submit
#scalePages
scalePages.title=Adjust page-scale
scalePages.header=Adjust page-scale
scalePages.pageSize=Size of a page of the document.
scalePages.scaleFactor=Zoom level (crop) of a page.
scalePages.submit=Submit
#certSign
certSign.title=证书签名
certSign.header=使用您的证书签署 PDF进行中
certSign.selectPDF=选择要签名的 PDF 文件:
@ -168,6 +295,8 @@ certSign.location=位置
certSign.name=名称
certSign.submit=签署 PDF
#removeBlanks
removeBlanks.title=\u5220\u9664\u7A7A\u767D
removeBlanks.header=\u5220\u9664\u7A7A\u767D\u9875
removeBlanks.threshold=\u9608\u503C\uFF1A
@ -176,12 +305,16 @@ removeBlanks.whitePercent=\u767D\u8272\u767E\u5206\u6BD4\uFF08%\uFF09\uFF1A
removeBlanks.whitePercentDesc=\u5FC5\u987B\u4E3A\u767D\u8272\u624D\u80FD\u5220\u9664\u7684\u9875\u9762\u767E\u5206\u6BD4
removeBlanks.submit=\u5220\u9664\u7A7A\u767D
#compare
compare.title=\u6BD4\u8F83
compare.header=\u6BD4\u8F83 PDF
compare.document.1=\u6587\u6863 1
compare.document.2=\u6587\u6863 2
compare.submit=\u6BD4\u8F83
#sign
sign.title=\u7B7E\u540D
sign.header=\u7B7E\u7F72 PDF
sign.upload=\u4E0A\u4F20\u56FE\u7247
@ -190,14 +323,20 @@ sign.text=\u6587\u672C\u8F93\u5165
sign.clear=\u6E05\u9664
sign.add=\u6DFB\u52A0
#repair
repair.title=\u4FEE\u590D
repair.header=\u4FEE\u590D PDF
repair.submit=\u4FEE\u590D
#flatten
flatten.title=\u5C55\u5E73
flatten.header=\u5C55\u5E73 PDF
flatten.submit=\u5C55\u5E73
#ScannerImageSplit
ScannerImageSplit.selectText.1=角度阈值:
ScannerImageSplit.selectText.2=设置图像被旋转所需的最小绝对角度默认10
ScannerImageSplit.selectText.3=公差:
@ -209,18 +348,6 @@ ScannerImageSplit.selectText.8=设置照片的最小轮廓面积阈值。
ScannerImageSplit.selectText.9=边框尺寸:
ScannerImageSplit.selectText.10=设置添加和删除的边框大小以防止输出中出现白边默认值1
navbar.settings=设置
settings.title=设置
settings.update=可更新
settings.appVersion=应用程序版本:
settings.downloadOption.title=选择下载选项(单个文件非压缩文件):
settings.downloadOption.1=在同一窗口打开
settings.downloadOption.2=在新窗口中打开
settings.downloadOption.3=下载文件
settings.zipThreshold=当下载的文件数量超过限制时,将文件压缩。
#OCR
ocr.title=OCR/扫描清理
@ -242,7 +369,7 @@ ocr.credit=此服务使用OCRmyPDF和Tesseract进行OCR。
ocr.submit=用OCR处理PDF
#extractImages
extractImages.title=提取图像
extractImages.header=提取图像
extractImages.selectText=选择图像格式,将提取的图像转换为
@ -282,11 +409,13 @@ merge.title=合并
merge.header=合并多个PDF2个以上
merge.submit=合并
#pdfOrganiser
pdfOrganiser.title=页面排序
pdfOrganiser.header=PDF页面排序
pdfOrganiser.submit=重新排列页面
#multiTool
multiTool.title=PDF多功能工具
multiTool.header=PDF多功能工具
@ -298,6 +427,7 @@ pageRemover.header=PDF页面移除器
pageRemover.pagesToDelete=要删除的页面(输入一个用逗号分隔的页码列表):
pageRemover.submit=删除页面
#rotate
rotate.title=旋转PDF
rotate.header=旋转PDF
@ -305,8 +435,6 @@ rotate.selectAngle=选择旋转角度以90度的倍数
rotate.submit=旋转
#merge
split.title=拆分PDF
split.header=拆分PDF
@ -332,6 +460,7 @@ imageToPDF.selectText.3=多文件逻辑(仅在处理多个图像时启用)
imageToPDF.selectText.4=合并成一个PDF文件
imageToPDF.selectText.5=转换为独立的PDF文件
#pdfToImage
pdfToImage.title=PDF to Image
pdfToImage.header=PDF转图片
@ -345,6 +474,7 @@ pdfToImage.grey=灰度
pdfToImage.blackwhite=黑白(可能会丢失数据!)。
pdfToImage.submit=转换
#addPassword
addPassword.title=添加密码
addPassword.header=添加密码(加密)。
@ -366,6 +496,7 @@ addPassword.selectText.15=Restricts what can be done with the document once it i
addPassword.selectText.16=Restricts the opening of the document itself<6C>
addPassword.submit=加密
#watermark
watermark.title=添加水印
watermark.header=添加水印
@ -378,6 +509,7 @@ watermark.selectText.6=heightSpacer每个水印之间的垂直空间
watermark.selectText.7=透明度0% - 100%
watermark.submit=添加水印
#remove-watermark
remove-watermark.title=去除水印
remove-watermark.header=去除水印
@ -385,6 +517,7 @@ remove-watermark.selectText.1=选择要去除水印的PDF
remove-watermark.selectText.2=水印文本:
remove-watermark.submit=移除水印
#Change permissions
permissions.title=更改权限
permissions.header=改变权限
@ -401,6 +534,7 @@ permissions.selectText.9=防止打印
permissions.selectText.10=防止打印不同的格式
permissions.submit=改变
#remove password
removePassword.title=删除密码
removePassword.header=移除密码(解密)。
@ -408,7 +542,9 @@ removePassword.selectText.1=选择要解密的PDF
removePassword.selectText.2=密码
removePassword.submit=删除
changeMetadata.title=更改元数据
#changeMetadata
changeMetadata.title=标题:
changeMetadata.header=更改元数据
changeMetadata.selectText.1=请编辑你想要改变的变量。
changeMetadata.selectText.2=删除所有元数据
@ -426,27 +562,30 @@ changeMetadata.selectText.4=其他元数据:
changeMetadata.selectText.5=添加自定义元数据条目
changeMetadata.submit=更改
#xlsToPdf
xlsToPdf.title=Excel转PDF
xlsToPdf.header=Excel转PDF
xlsToPdf.selectText.1=选择要转换的XLS或XLSX Excel表格
xlsToPdf.convert=转换
#pdfToPDFA
pdfToPDFA.title=PDF To PDF/A
pdfToPDFA.header=PDF to PDF/A
pdfToPDFA.credit=此服务使用OCRmyPDF进行PDF/A转换
pdfToPDFA.submit=转换
#PDFToWord
PDFToWord.title=PDF to Word
PDFToWord.header=将PDF转换成Word
PDFToWord.selectText.1=输出文件格式
PDFToWord.credit=此服务使用LibreOffice进行文件转换。
PDFToWord.submit=转换
#PDFToPresentation
PDFToPresentation.title=PDF To Presentation
PDFToPresentation.header=将PDF转为演示文稿
PDFToPresentation.selectText.1=输出文件格式
@ -454,6 +593,7 @@ PDFToPresentation.credit=该服务使用LibreOffice进行文件转换。
PDFToPresentation.submit=转换
#PDFToText
PDFToText.title=PDF To Text/RTF
PDFToText.header=将PDF转换成文本/RTF
PDFToText.selectText.1=输出文件格式
@ -461,11 +601,14 @@ PDFToText.credit=该服务使用LibreOffice进行文件转换。
PDFToText.submit=转换
#PDFToHTML
PDFToHTML.title=PDF To HTML
PDFToHTML.header=将PDF转换成HTML
PDFToHTML.credit=此服务使用LibreOffice进行文件转换。
PDFToHTML.submit=转换
#PDFToXML
PDFToXML.title=PDF To XML
PDFToXML.header=将PDF转换为XML
PDFToXML.credit=此服务使用LibreOffice进行文件转换。

View file

@ -66,3 +66,7 @@ html[lang-direction="rtl"] label.form-check-label {
.margin-center {
margin: 0 auto;
}
#pdf-canvas {
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
width: 100%;
}

View file

@ -1,3 +1,17 @@
#searchBar {
background-image: url('/images/search.svg');
background-position: 16px 16px;
background-repeat: no-repeat;
width: 100%;
font-size: 16px;
margin-bottom: 12px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
}
.features-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(21rem, 3fr));

View file

@ -17,9 +17,13 @@
display: flex;
justify-content: flex-end;
}
.arrows .btn {
margin: 0 3px;
}
.move-up span,
.move-down span {
font-weight: bold;
font-size: 1.2em;
}

View file

@ -1,3 +1,41 @@
#navbarSearch {
top: 100%;
right: 0;
}
#searchForm {
width: 200px; /* Adjust this value as needed */
}
/* Style the search results to match the navbar */
#searchResults {
max-height: 200px; /* Adjust this value as needed */
overflow-y: auto;
width: 100%;
}
#searchResults .dropdown-item {
display: flex;
align-items: center;
white-space: nowrap;
height: 50px; /* Fixed height */
overflow: hidden; /* Hide overflow */
}
#searchResults .icon {
margin-right: 10px;
}
#searchResults .icon-text {
display: inline;
overflow: hidden; /* Hide overflow */
text-overflow: ellipsis; /* Add ellipsis for long text */
}
.main-icon {
width: 36px;
height: 36px;

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-123" viewBox="0 0 16 16">
<path d="M2.873 11.297V4.142H1.699L0 5.379v1.137l1.64-1.18h.06v5.961h1.174Zm3.213-5.09v-.063c0-.618.44-1.169 1.196-1.169.676 0 1.174.44 1.174 1.106 0 .624-.42 1.101-.807 1.526L4.99 10.553v.744h4.78v-.99H6.643v-.069L8.41 8.252c.65-.724 1.237-1.332 1.237-2.27C9.646 4.849 8.723 4 7.308 4c-1.573 0-2.36 1.064-2.36 2.15v.057h1.138Zm6.559 1.883h.786c.823 0 1.374.481 1.379 1.179.01.707-.55 1.216-1.421 1.21-.77-.005-1.326-.419-1.379-.953h-1.095c.042 1.053.938 1.918 2.464 1.918 1.478 0 2.642-.839 2.62-2.144-.02-1.143-.922-1.651-1.551-1.714v-.063c.535-.09 1.347-.66 1.326-1.678-.026-1.053-.933-1.855-2.359-1.845-1.5.005-2.317.88-2.348 1.898h1.116c.032-.498.498-.944 1.206-.944.703 0 1.206.435 1.206 1.07.005.64-.504 1.106-1.2 1.106h-.75v.96Z"/>
</svg>

After

Width:  |  Height:  |  Size: 870 B

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-palette" viewBox="0 0 16 16">
<path d="M8 5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm4 3a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zM5.5 7a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm.5 6a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/>
<path d="M16 8c0 3.15-1.866 2.585-3.567 2.07C11.42 9.763 10.465 9.473 10 10c-.603.683-.475 1.819-.351 2.92C9.826 14.495 9.996 16 8 16a8 8 0 1 1 8-8zm-8 7c.611 0 .654-.171.655-.176.078-.146.124-.464.07-1.119-.014-.168-.037-.37-.061-.591-.052-.464-.112-1.005-.118-1.462-.01-.707.083-1.61.704-2.314.369-.417.845-.578 1.272-.618.404-.038.812.026 1.16.104.343.077.702.186 1.025.284l.028.008c.346.105.658.199.953.266.653.148.904.083.991.024C14.717 9.38 15 9.161 15 8a7 7 0 1 0-7 7z"/>
</svg>

After

Width:  |  Height:  |  Size: 795 B

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-crop" viewBox="0 0 16 16">
<path d="M3.5.5A.5.5 0 0 1 4 1v13h13a.5.5 0 0 1 0 1h-2v2a.5.5 0 0 1-1 0v-2H3.5a.5.5 0 0 1-.5-.5V4H1a.5.5 0 0 1 0-1h2V1a.5.5 0 0 1 .5-.5zm2.5 3a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 .5.5v8a.5.5 0 0 1-1 0V4H6.5a.5.5 0 0 1-.5-.5z"/>
</svg>

After

Width:  |  Height:  |  Size: 353 B

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-fonts" viewBox="0 0 16 16">
<path d="M12.258 3h-8.51l-.083 2.46h.479c.26-1.544.758-1.783 2.693-1.845l.424-.013v7.827c0 .663-.144.82-1.3.923v.52h4.082v-.52c-1.162-.103-1.306-.26-1.306-.923V3.602l.431.013c1.934.062 2.434.301 2.693 1.846h.479L12.258 3z"/>
</svg>

After

Width:  |  Height:  |  Size: 357 B

View file

@ -0,0 +1 @@
<svg height="48" viewBox="0 0 48 48" width="48" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h48v48h-48z" fill="none"/><path d="m8.091 21c0 1.089-.576 1.695-1.304 2.464-.755.797-1.696 1.788-1.696 3.394v11.142c0 2.757 2.243 5 5 5h12c2.757 0 5-2.243 5-5v-11.143c0-2.316-2.045-3.302-4.022-4.254-2.447-1.179-4.978-2.397-4.978-6.104v-.215l-.088-.195c-.081-.179-.287-.608-.6-1.09h1.969l2.032-1.242 5.949 5.949 1.414-1.414-5.608-5.608 1.841-1.123v-6.561h-14.186l-5.713 3.428-.12 6.572h3.46c-.219.456-.351.961-.351 1.5v4.5zm-1.01-11.428 4.287-2.572h11.632v3.439l-4.19 2.561h-4.219-3-4.572zm3.01 11.428v-4.5c0-.827.673-1.5 1.5-1.5h3c.341 0 1.054.832 1.502 1.731.108 4.784 3.569 6.451 6.107 7.674 1.846.89 2.89 1.441 2.89 2.452v11.143c0 1.654-1.346 3-3 3h-12c-1.654 0-3-1.346-3-3v-11.143c0-.771.415-1.244 1.147-2.017.826-.87 1.854-1.953 1.854-3.84z"/><path d="m15.091 38h2v-5h5v-2h-5v-5h-2v5h-5v2h5z"/><circle cx="30.091" cy="8" r="2"/><circle cx="36.091" cy="8" r="2"/><circle cx="42.091" cy="8" r="2"/><circle cx="33.091" cy="13" r="2"/><circle cx="37.091" cy="17" r="2"/></svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -1,8 +1,65 @@
document.addEventListener('DOMContentLoaded', function() {
let overlay;
let dragCounter = 0;
const dragenterListener = function() {
dragCounter++;
if (!overlay) {
// Create and show the overlay
overlay = document.createElement('div');
overlay.style.position = 'fixed';
overlay.style.top = 0;
overlay.style.left = 0;
overlay.style.width = '100%';
overlay.style.height = '100%';
overlay.style.background = 'rgba(0, 0, 0, 0.5)';
overlay.style.color = '#fff';
overlay.style.zIndex = '1000';
overlay.style.display = 'flex';
overlay.style.alignItems = 'center';
overlay.style.justifyContent = 'center';
overlay.style.pointerEvents = 'none';
overlay.innerHTML = '<p>Drop files anywhere to upload</p>';
document.getElementById('content-wrap').appendChild(overlay);
}
};
const dragleaveListener = function() {
dragCounter--;
if (dragCounter === 0) {
// Hide and remove the overlay
if (overlay) {
overlay.remove();
overlay = null;
}
}
};
const dropListener = function(e) {
const dt = e.dataTransfer;
const files = dt.files;
// Access the file input element and assign dropped files
const fileInput = document.getElementById(elementID);
fileInput.files = files;
// Hide and remove the overlay
if (overlay) {
overlay.remove();
overlay = null;
}
// Reset drag counter
dragCounter = 0;
//handleFileInputChange(fileInput);
fileInput.dispatchEvent(new Event('change', { bubbles: true }));
};
// Prevent default behavior for drag events
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
fileInput.addEventListener(eventName, preventDefaults, false);
document.body.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
@ -10,21 +67,18 @@ document.addEventListener('DOMContentLoaded', function() {
e.stopPropagation();
}
document.body.addEventListener('dragenter', dragenterListener);
document.body.addEventListener('dragleave', dragleaveListener);
// Add drop event listener
fileInput.addEventListener('drop', handleDrop, false);
document.body.addEventListener('drop', dropListener);
function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
fileInput.files = files;
handleFileInputChange(fileInput)
}
});
$("#"+elementID).on("change", function() {
handleFileInputChange(this);
});
function handleFileInputChange(inputElement) {
const files = $(inputElement).get(0).files;
const fileNames = Array.from(files).map(f => f.name);

View file

@ -1,3 +1,24 @@
function filterCards() {
var input = document.getElementById('searchBar');
var filter = input.value.toUpperCase();
var cards = document.querySelectorAll('.feature-card');
for (var i = 0; i < cards.length; i++) {
var card = cards[i];
var title = card.querySelector('h5.card-title').innerText;
var text = card.querySelector('p.card-text').innerText;
var tags = card.getAttribute('data-tags');
var content = title + ' ' + text + ' ' + tags;
if (content.toUpperCase().indexOf(filter) > -1) {
card.style.display = "";
} else {
card.style.display = "none";
}
}
}
function toggleFavorite(element) {
var img = element.querySelector('img');
var card = element.closest('.feature-card');
@ -13,6 +34,7 @@ function toggleFavorite(element) {
}
reorderCards();
updateFavoritesDropdown();
filterCards();
}
function reorderCards() {
@ -45,5 +67,7 @@ function initializeCards() {
});
reorderCards();
updateFavoritesDropdown();
filterCards();
}
window.onload = initializeCards;

View file

@ -74,14 +74,20 @@ document.getElementById('submitConfigBtn').addEventListener('click', function()
"pipeline": [{
"operation": selectedOperation,
"parameters": parameters
}]
}],
"_examples": {
"outputDir": "{outputFolder}/{folderName}",
"outputFileName": "{filename}-{pipelineName}-{date}-{time}"
},
"outputDir": "httpWebRequest",
"outputFileName": "{filename}"
};
let pipelineConfigJson = JSON.stringify(pipelineConfig, null, 2);
let formData = new FormData();
let fileInput = document.getElementById('fileInput');
let fileInput = document.getElementById('fileInput-input');
let files = fileInput.files;
for (let i = 0; i < files.length; i++) {
@ -171,7 +177,11 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
let listItem = document.createElement('li');
listItem.className = "list-group-item";
let hasSettings = (apiDocs[selectedOperation] && apiDocs[selectedOperation].post &&
apiDocs[selectedOperation].post.parameters && apiDocs[selectedOperation].post.parameters.length > 0);
((apiDocs[selectedOperation].post.parameters && apiDocs[selectedOperation].post.parameters.length > 0) ||
(apiDocs[selectedOperation].post.requestBody &&
apiDocs[selectedOperation].post.requestBody.content['multipart/form-data'].schema.properties)));
listItem.innerHTML = `
@ -216,10 +226,20 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
let pipelineSettingsModal = document.getElementById('pipelineSettingsModal');
let pipelineSettingsContent = document.getElementById('pipelineSettingsContent');
let operationData = apiDocs[operation].post.parameters || [];
let requestBodyData = apiDocs[operation].post.requestBody.content['multipart/form-data'].schema.properties || {};
// Combine operationData and requestBodyData into a single array
operationData = operationData.concat(Object.keys(requestBodyData).map(key => ({
name: key,
schema: requestBodyData[key]
})));
pipelineSettingsContent.innerHTML = '';
operationData.forEach(parameter => {
// If the parameter name is 'fileInput', return early to skip the rest of this iteration
if (parameter.name === 'fileInput') return;
let parameterDiv = document.createElement('div');
parameterDiv.className = "form-group";
@ -229,12 +249,45 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
parameterDiv.appendChild(parameterLabel);
let parameterInput;
// check if enum exists in schema
if (parameter.schema.enum) {
// if enum exists, create a select element
parameterInput = document.createElement('select');
parameterInput.className = "form-control";
// iterate over each enum value and create an option for it
parameter.schema.enum.forEach(value => {
let option = document.createElement('option');
option.value = value;
option.text = value;
parameterInput.appendChild(option);
});
} else {
// switch-case statement for handling non-enum types
switch (parameter.schema.type) {
case 'string':
if (parameter.schema.format === 'binary') {
// This is a file input
//parameterInput = document.createElement('input');
//parameterInput.type = 'file';
//parameterInput.className = "form-control";
parameterInput = document.createElement('input');
parameterInput.type = 'text';
parameterInput.className = "form-control";
parameterInput.value = "automatedFileInput";
} else {
parameterInput = document.createElement('input');
parameterInput.type = 'text';
parameterInput.className = "form-control";
}
break;
case 'number':
case 'integer':
parameterInput = document.createElement('input');
parameterInput.type = parameter.schema.type === 'string' ? 'text' : 'number';
parameterInput.type = 'number';
parameterInput.className = "form-control";
break;
case 'boolean':
@ -247,21 +300,12 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
parameterInput.placeholder = `Enter a JSON formatted ${parameter.schema.type}`;
parameterInput.className = "form-control";
break;
case 'enum':
parameterInput = document.createElement('select');
parameterInput.className = "form-control";
parameter.schema.enum.forEach(option => {
let optionElement = document.createElement('option');
optionElement.value = option;
optionElement.text = option;
parameterInput.appendChild(optionElement);
});
break;
default:
parameterInput = document.createElement('input');
parameterInput.type = 'text';
parameterInput.className = "form-control";
}
}
parameterInput.id = parameter.name;
if (operationSettings[operation] && operationSettings[operation][parameter.name] !== undefined) {
@ -340,10 +384,17 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
if (validatePipeline() === false) {
return;
}
var pipelineName = document.getElementById('pipelineName').value;
let pipelineList = document.getElementById('pipelineList').children;
let pipelineConfig = {
"name": "uniquePipelineName",
"pipeline": []
"name": pipelineName,
"pipeline": [],
"_examples": {
"outputDir": "{outputFolder}/{folderName}",
"outputFileName": "{filename}-{pipelineName}-{date}-{time}"
},
"outputDir": "httpWebRequest",
"outputFileName": "{filename}"
};
for (let i = 0; i < pipelineList.length; i++) {
@ -368,30 +419,27 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
document.body.removeChild(a);
});
document.getElementById('uploadPipelineBtn').addEventListener('click', function() {
document.getElementById('uploadPipelineInput').click();
});
document.getElementById('uploadPipelineInput').addEventListener('change', function(e) {
let reader = new FileReader();
reader.onload = function(event) {
let pipelineConfig = JSON.parse(event.target.result);
async function processPipelineConfig(configString) {
let pipelineConfig = JSON.parse(configString);
let pipelineList = document.getElementById('pipelineList');
while (pipelineList.firstChild) {
pipelineList.removeChild(pipelineList.firstChild);
}
pipelineConfig.pipeline.forEach(operationConfig => {
document.getElementById('pipelineName').value = pipelineConfig.name
for (const operationConfig of pipelineConfig.pipeline) {
let operationsDropdown = document.getElementById('operationsDropdown');
operationsDropdown.value = operationConfig.operation;
operationSettings[operationConfig.operation] = operationConfig.parameters;
// assuming addOperation is async
await new Promise((resolve) => {
document.getElementById('addOperationBtn').addEventListener('click', resolve, { once: true });
document.getElementById('addOperationBtn').click();
});
let lastOperation = pipelineList.lastChild;
lastOperation.querySelector('.pipelineSettings').click();
Object.keys(operationConfig.parameters).forEach(parameterName => {
let input = document.getElementById(parameterName);
if (input) {
@ -402,6 +450,17 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
case 'number':
input.value = operationConfig.parameters[parameterName].toString();
break;
case 'file':
if (parameterName !== 'fileInput') {
// Create a new file input element
let newInput = document.createElement('input');
newInput.type = 'file';
newInput.id = parameterName;
// Add the new file input to the main page (change the selector according to your needs)
document.querySelector('#main').appendChild(newInput);
}
break;
case 'text':
case 'textarea':
default:
@ -410,10 +469,26 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
}
});
document.querySelector('#pipelineSettingsModal .btn-primary').click();
}
}
document.getElementById('uploadPipelineBtn').addEventListener('click', function() {
document.getElementById('uploadPipelineInput').click();
});
document.getElementById('uploadPipelineInput').addEventListener('change', function(e) {
let reader = new FileReader();
reader.onload = function(event) {
processPipelineConfig(event.target.result);
};
reader.readAsText(e.target.files[0]);
});
document.getElementById('pipelineSelect').addEventListener('change', function(e) {
let selectedPipelineJson = e.target.value; // assuming the selected value is the JSON string of the pipeline config
processPipelineConfig(selectedPipelineJson);
});
});

View file

@ -0,0 +1,72 @@
// Toggle search bar when the search icon is clicked
document.querySelector('#search-icon').addEventListener('click', function(e) {
e.preventDefault();
var searchBar = document.querySelector('#navbarSearch');
searchBar.classList.toggle('show');
});
window.onload = function() {
var items = document.querySelectorAll('.dropdown-item, .nav-link');
var dummyContainer = document.createElement('div');
dummyContainer.style.position = 'absolute';
dummyContainer.style.visibility = 'hidden';
dummyContainer.style.whiteSpace = 'nowrap'; // Ensure we measure full width
document.body.appendChild(dummyContainer);
var maxWidth = 0;
items.forEach(function(item) {
var clone = item.cloneNode(true);
dummyContainer.appendChild(clone);
var width = clone.offsetWidth;
if (width > maxWidth) {
maxWidth = width;
}
dummyContainer.removeChild(clone);
});
document.body.removeChild(dummyContainer);
// Store max width for later use
window.navItemMaxWidth = maxWidth;
};
// Show search results as user types in search box
document.querySelector('#navbarSearchInput').addEventListener('input', function(e) {
var searchText = e.target.value.toLowerCase();
var items = document.querySelectorAll('.dropdown-item, .nav-link');
var resultsBox = document.querySelector('#searchResults');
// Clear any previous results
resultsBox.innerHTML = '';
items.forEach(function(item) {
var titleElement = item.querySelector('.icon-text');
var iconElement = item.querySelector('.icon');
var itemHref = item.getAttribute('href');
if (titleElement && iconElement && itemHref !== '#') {
var title = titleElement.innerText;
if (title.toLowerCase().indexOf(searchText) !== -1 && !resultsBox.querySelector(`a[href="${item.getAttribute('href')}"]`)) {
var result = document.createElement('a');
result.href = itemHref;
result.classList.add('dropdown-item');
var resultIcon = document.createElement('img');
resultIcon.src = iconElement.src;
resultIcon.alt = 'icon';
resultIcon.classList.add('icon');
result.appendChild(resultIcon);
var resultText = document.createElement('span');
resultText.textContent = title;
resultText.classList.add('icon-text');
result.appendChild(resultText);
resultsBox.appendChild(result);
}
}
});
// Set the width of the search results box to the maximum width
resultsBox.style.width = window.navItemMaxWidth + 'px';
});

View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
<th:block th:insert="~{fragments/common :: head(title=#{autoSplitPDF.title})}"></th:block>
<body>
<th:block th:insert="~{fragments/common :: game}"></th:block>
<div id="page-container">
<div id="content-wrap">
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
<br> <br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6">
<h2 th:text="#{autoSplitPDF.header}"></h2>
<!-- Added a brief description -->
<p th:text="#{autoSplitPDF.description}"></p>
<ul>
<li th:text="#{autoSplitPDF.selectText.1}"></li>
<li th:text="#{autoSplitPDF.selectText.2}"></li>
<li th:text="#{autoSplitPDF.selectText.3}"></li>
<li th:text="#{autoSplitPDF.selectText.4}"></li>
</ul>
<form method="post" enctype="multipart/form-data">
<p th:text="#{autoSplitPDF.formPrompt}"></p>
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
<p><a th:href="@{files/Auto Splitter Divider (minimal).pdf}" download th:text="#{autoSplitPDF.dividerDownload1}"></a></p>
<p><a th:href="@{files/Auto Splitter Divider (with instructions).pdf}" download th:text="#{autoSplitPDF.dividerDownload2}"></a></p>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{autoSplitPDF.submit}"></button>
</form>
</div>
</div>
</div>
</div>
<div th:insert="~{fragments/footer.html :: footer}"></div>
</div>
</body>
</html>

View file

@ -0,0 +1,145 @@
<!DOCTYPE html>
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
<th:block th:insert="~{fragments/common :: head(title=#{crop.title})}"></th:block>
<body>
<div id="page-container">
<div id="content-wrap">
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
<br> <br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6">
<h2 th:text="#{crop.header}"></h2>
<form id="cropForm" action="/crop" method="post" enctype="multipart/form-data">
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
<input id="x" type="hidden" name="x">
<input id="y" type="hidden" name="y">
<input id="width" type="hidden" name="width">
<input id="height" type="hidden" name="height">
<button type="submit" class="btn btn-primary" th:text="#{crop.submit}"></button>
</form>
<div style="position: relative; display: inline-block;">
<canvas id="pdf-canvas" style="position: absolute; top: 0; left: 0; z-index: 1;"></canvas>
<canvas id="overlayCanvas" style="position: absolute; top: 0; left: 0; z-index: 2;"></canvas>
</div>
<script>
let pdfCanvas = document.getElementById('pdf-canvas');
let overlayCanvas = document.getElementById('overlayCanvas');
let context = pdfCanvas.getContext('2d');
let overlayContext = overlayCanvas.getContext('2d');
overlayCanvas.width = pdfCanvas.width;
overlayCanvas.height = pdfCanvas.height;
let isDrawing = false; // New flag to check if drawing is ongoing
let cropForm = document.getElementById('cropForm');
let fileInput = document.getElementById('fileInput-input');
let xInput = document.getElementById('x');
let yInput = document.getElementById('y');
let widthInput = document.getElementById('width');
let heightInput = document.getElementById('height');
let pdfDoc = null;
let currentPage = 1;
let totalPages = 0;
let startX = 0;
let startY = 0;
let rectWidth = 0;
let rectHeight = 0;
fileInput.addEventListener('change', function(e) {
let file = e.target.files[0];
if (file.type === 'application/pdf') {
let reader = new FileReader();
reader.onload = function(ev) {
let typedArray = new Uint8Array(reader.result);
pdfjsLib.getDocument(typedArray).promise.then(function(pdf) {
pdfDoc = pdf;
totalPages = pdf.numPages;
renderPage(currentPage);
});
};
reader.readAsArrayBuffer(file);
}
});
overlayCanvas.addEventListener('mousedown', function(e) {
// Clear previously drawn rectangle on the main canvas
context.clearRect(0, 0, pdfCanvas.width, pdfCanvas.height);
renderPage(currentPage); // Re-render the PDF
// Clear the overlay canvas to ensure old drawings are removed
overlayContext.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height);
startX = e.offsetX;
startY = e.offsetY;
isDrawing = true;
});
overlayCanvas.addEventListener('mousemove', function(e) {
if (!isDrawing) return;
overlayContext.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height); // Clear previous rectangle
rectWidth = e.offsetX - startX;
rectHeight = e.offsetY - startY;
overlayContext.strokeStyle = 'red';
overlayContext.strokeRect(startX, startY, rectWidth, rectHeight);
});
overlayCanvas.addEventListener('mouseup', function(e) {
isDrawing = false;
rectWidth = e.offsetX - startX;
rectHeight = e.offsetY - startY;
let flippedY = pdfCanvas.height - e.offsetY;
xInput.value = startX;
yInput.value = flippedY;
widthInput.value = rectWidth;
heightInput.value = rectHeight;
// Draw the final rectangle on the main canvas
context.strokeStyle = 'red';
context.strokeRect(startX, startY, rectWidth, rectHeight);
overlayContext.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height); // Clear the overlay
});
function renderPage(pageNumber) {
pdfDoc.getPage(pageNumber).then(function(page) {
let viewport = page.getViewport({ scale: 1.0 });
pdfCanvas.width = viewport.width;
pdfCanvas.height = viewport.height;
overlayCanvas.width = viewport.width; // Match overlay canvas size with PDF canvas
overlayCanvas.height = viewport.height;
let renderContext = { canvasContext: context, viewport: viewport };
page.render(renderContext);
});
}
</script>
</div>
</div>
</div>
</div>
<div th:insert="~{fragments/footer.html :: footer}"></div>
</div>
</body>
</html>

View file

@ -1,4 +1,4 @@
<div th:fragment="card" class="feature-card" th:id="${id}" th:if="${@endpointConfiguration.isEndpointEnabled(cardLink)}">
<div th:fragment="card" class="feature-card" th:id="${id}" th:if="${@endpointConfiguration.isEndpointEnabled(cardLink)}" data-tags="${tags}">
<a th:href="${cardLink}">
<div class="d-flex align-items-center"> <!-- Add a flex container to align the SVG and title -->
<img th:if="${svgPath}" id="card-icon" class="home-card-icon home-card-icon-colour" th:src="${svgPath}" alt="Icon" width="30" height="30">

View file

@ -13,7 +13,7 @@
<div class="container ">
<a class="navbar-brand" href="#" th:href="@{/}" >
<img th:if="${@navBarText} == 'Stirling PDF'" class="main-icon" src="favicon.svg" alt="icon">
<img class="main-icon" src="favicon.svg" alt="icon">
<span class="icon-text" th:text="${@navBarText}"></span>
</a>
@ -40,7 +40,7 @@
</li>-->
<li class="nav-item nav-item-separator"></li>
<li class="nav-item dropdown" th:classappend="${currentPage}=='remove-pages' OR ${currentPage}=='merge-pdfs' OR ${currentPage}=='split-pdfs' OR ${currentPage}=='pdf-organizer' OR ${currentPage}=='rotate-pdf' ? 'active' : ''">
<li class="nav-item dropdown" th:classappend="${currentPage}=='remove-pages' OR ${currentPage}=='merge-pdfs' OR ${currentPage}=='split-pdfs' OR ${currentPage}=='crop' OR ${currentPage}=='adjust-contrast' OR ${currentPage}=='pdf-organizer' OR ${currentPage}=='rotate-pdf' OR ${currentPage}=='multi-page-layout' OR ${currentPage}=='scale-pages' ? 'active' : ''">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<img class="icon" src="images/file-earmark-pdf.svg" alt="icon">
<span class="icon-text" th:text="#{navbar.pageOps}"></span>
@ -54,6 +54,10 @@
<div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'remove-pages', 'images/file-earmark-x.svg', 'home.removePages.title', 'home.removePages.desc')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'multi-page-layout', 'images/page-layout.svg', 'home.pageLayout.title', 'home.pageLayout.desc')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'scale-pages', 'images/scale-pages.svg', 'home.scalePages.title', 'home.scalePages.desc')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'auto-split-pdf', 'images/layout-split.svg', 'home.autoSplitPDF.title', 'home.autoSplitPDF.desc')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('adjust-contrast', 'images/adjust-contrast.svg', 'home.adjust-contrast.title', 'home.adjust-contrast.desc')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('crop', 'images/crop.svg', 'home.crop.title', 'home.crop.desc')}"></div>
</div>
</li>
@ -94,17 +98,19 @@
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('change-permissions', 'images/shield-lock.svg', 'home.permissions.title', 'home.permissions.desc')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('add-watermark', 'images/droplet.svg', 'home.watermark.title', 'home.watermark.desc')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('cert-sign', 'images/award.svg', 'home.certSign.title', 'home.certSign.desc')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('sanitize-pdf', 'images/sanitize.svg', 'home.sanitizePdf.title', 'home.sanitizePdf.desc')}"></div>
</div>
</li>
<li class="nav-item nav-item-separator"></li>
<li class="nav-item dropdown" th:classappend="${currentPage}=='sign' OR ${currentPage}=='repair' OR ${currentPage}=='compare' OR ${currentPage}=='flatten' OR ${currentPage}=='remove-blanks' OR ${currentPage}=='extract-image-scans' OR ${currentPage}=='change-metadata' OR ${currentPage}=='add-image' OR ${currentPage}=='ocr-pdf' OR ${currentPage}=='change-permissions' OR ${currentPage}=='extract-images' OR ${currentPage}=='compress-pdf' ? 'active' : ''">
<li class="nav-item dropdown" th:classappend="${currentPage}=='sign' OR ${currentPage}=='repair' OR ${currentPage}=='compare' OR ${currentPage}=='flatten' OR ${currentPage}=='remove-blanks' OR ${currentPage}=='extract-image-scans' OR ${currentPage}=='change-metadata' OR ${currentPage}=='add-image' OR ${currentPage}=='ocr-pdf' OR ${currentPage}=='change-permissions' OR ${currentPage}=='extract-images' OR ${currentPage}=='compress-pdf' OR ${currentPage}=='add-page-numbers' OR ${currentPage}=='auto-rename' ? 'active' : ''">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<img class="icon" src="images/card-list.svg" alt="icon" style="width: 16px; height: 16px; vertical-align: middle;">
<span class="icon-text" th:text="#{navbar.other}"></span>
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<!--<div th:replace="~{fragments/navbarEntry :: navbarEntry ('pipeline', 'images/pipeline.svg', 'home.pipeline.title', 'home.pipeline.desc')}"></div> -->
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('ocr-pdf', 'images/search.svg', 'home.ocr.title', 'home.ocr.desc')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('add-image', 'images/file-earmark-richtext.svg', 'home.addImage.title', 'home.addImage.desc')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('compress-pdf', 'images/file-zip.svg', 'home.compressPdfs.title', 'home.compressPdfs.desc')}"></div>
@ -116,6 +122,8 @@
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('repair', 'images/wrench.svg', 'home.repair.title', 'home.repair.desc')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('remove-blanks', 'images/blank-file.svg', 'home.removeBlanks.title', 'home.removeBlanks.desc')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('compare', 'images/scales.svg', 'home.compare.title', 'home.compare.desc')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('add-page-numbers', 'images/add-page-numbers.svg', 'home.add-page-numbers.title', 'home.add-page-numbers.desc')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('auto-rename', 'images/fonts.svg', 'home.auto-rename.title', 'home.auto-rename.desc')}"></div>
</div>
</li>
@ -203,6 +211,70 @@
</a>
</li>
<!-- Search Button and Search Bar -->
<li class="nav-item position-relative">
<a href="#" class="nav-link" id="search-icon">
<img class="navbar-icon" src="images/search.svg" alt="icon" width="24" height="24">
</a>
<!-- Search Bar -->
<div class="collapse position-absolute" id="navbarSearch">
<form class="d-flex p-2 bg-white border search-form" id="searchForm">
<input class="form-control search-input" type="search" placeholder="Search" aria-label="Search" id="navbarSearchInput">
</form>
<!-- Search Results -->
<div id="searchResults" class="border p-2 bg-white search-results"></div>
</div>
</li>
<style>
#search-icon i {
font-size: 24px; /* Adjust this to your desired size */
transition: color 0.3s;
}
#search-icon:hover i {
color: #666; /* Adjust this to your hover color */
}
#navbarSearch {
transition: all 0.3s;
max-height: 0;
overflow: hidden;
}
#navbarSearch.show {
max-height: 300px; /* Adjust this to your desired max height */
}
.search-input {
transition: border 0.3s, box-shadow 0.3s;
}
.search-input:focus {
border-color: #666; /* Adjust this to your focus color */
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* Adjust this to your desired shadow */
}
#searchResults {
max-width: 300px; /* Adjust to your preferred width */
transition: height 0.3s ease; /* Smooth height transition */
}
/* Set a fixed height and styling for each search result item */
.search-results a {
display: flex;
align-items: center;
gap: 10px; /* space between icon and text */
height: 40px; /* Adjust based on your design */
overflow: hidden; /* Prevent content from overflowing */
white-space: nowrap; /* Prevent text from wrapping to next line */
text-overflow: ellipsis; /* Truncate text if it's too long */
}
</style>
</ul>
@ -210,6 +282,7 @@
</div>
<script src="js/favourites.js"></script>
<script src="js/search.js"></script>
</nav>
<div th:insert="~{fragments/errorBannerPerPage.html :: errorBannerPerPage}"></div>

View file

@ -20,9 +20,14 @@
</div>
<br class="d-md-none">
<!-- Features -->
<div class="features-container container">
<script src="js/homecard.js"></script>
<!-- <div th:replace="~{fragments/card :: card(id='pipeline', cardTitle=#{home.pipeline.title}, cardText=#{home.pipeline.desc}, cardLink='pipeline', svgPath='images/pipeline.svg')}"></div>-->
<div class=" container">
<input type="text" id="searchBar" onkeyup="filterCards()" placeholder="Search for features...">
<div class="features-container ">
<!-- <div th:replace="~{fragments/card :: card(id='pipeline', cardTitle=#{home.pipeline.title}, cardText=#{home.pipeline.desc}, cardLink='pipeline', svgPath='images/pipeline.svg')}"></div> -->
<div th:replace="~{fragments/card :: card(id='multi-tool', cardTitle=#{home.multiTool.title}, cardText=#{home.multiTool.desc}, cardLink='multi-tool', svgPath='images/tools.svg')}"></div>
<div th:replace="~{fragments/card :: card(id='merge-pdfs', cardTitle=#{home.merge.title}, cardText=#{home.merge.desc}, cardLink='merge-pdfs', svgPath='images/union.svg')}"></div>
@ -68,11 +73,15 @@
<div th:replace="~{fragments/card :: card(id='multi-page-layout', cardTitle=#{home.pageLayout.title}, cardText=#{home.pageLayout.desc}, cardLink='multi-page-layout', svgPath='images/page-layout.svg')}"></div>
<div th:replace="~{fragments/card :: card(id='scale-pages', cardTitle=#{home.scalePages.title}, cardText=#{home.scalePages.desc}, cardLink='scale-pages', svgPath='images/scale-pages.svg')}"></div>
<div th:replace="~{fragments/card :: card(id='add-page-numbers', cardTitle=#{home.add-page-numbers.title}, cardText=#{home.add-page-numbers.desc}, cardLink='add-page-numbers', svgPath='images/add-page-numbers.svg')}"></div>
<div th:replace="~{fragments/card :: card(id='auto-rename', cardTitle=#{home.auto-rename.title}, cardText=#{home.auto-rename.desc}, cardLink='auto-rename', svgPath='images/fonts.svg')}"></div>
<div th:replace="~{fragments/card :: card(id='adjust-contrast', cardTitle=#{home.adjust-contrast.title}, cardText=#{home.adjust-contrast.desc}, cardLink='adjust-contrast', svgPath='images/adjust-contrast.svg')}"></div>
<div th:replace="~{fragments/card :: card(id='crop', cardTitle=#{home.crop.title}, cardText=#{home.crop.desc}, cardLink='crop', svgPath='images/crop.svg')}"></div>
<div th:replace="~{fragments/card :: card(id='auto-split-pdf', cardTitle=#{home.autoSplitPDF.title}, cardText=#{home.autoSplitPDF.desc}, cardLink='auto-split-pdf', svgPath='images/layout-split.svg')}"></div>
<div th:replace="~{fragments/card :: card(id='sanitize-pdf', cardTitle=#{home.sanitizePdf.title}, cardText=#{home.sanitizePdf.desc}, cardLink='sanitize-pdf', svgPath='images/sanitize.svg')}"></div>
<script src="js/homecard.js"></script>
</div>
</div>
</div> </div>
<div th:insert="~{fragments/footer.html :: footer}"></div>
</div>
</body>

View file

@ -0,0 +1,154 @@
<!DOCTYPE html>
<html th:lang="${#locale.toString()}"
th:lang-direction="#{language.direction}"
xmlns:th="http://www.thymeleaf.org">
<th:block
th:insert="~{fragments/common :: head(title=#{autoCrop.title})}"></th:block>
<body>
<th:block th:insert="~{fragments/common :: game}"></th:block>
<div id="page-container">
<div id="content-wrap">
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
<br> <br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6">
<h2 th:text="#{addPageNumbers.header}"></h2>
<form method="post" enctype="multipart/form-data"
th:action="@{add-page-numbers}">
<div
th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
<br>
<div class="form-group">
<label for="customMargin" th:text="#{addPageNumbers.selectText.2}"></label> <select
class="form-control" id="customMargin" name="customMargin"
required>
<option value="small" th:text="#{sizes.small}"></option>
<option value="medium" selected th:text="#{sizes.medium}"></option>
<option value="large" th:text="#{sizes.large}"></option>
<option value="x-large" th:text="#{sizes.x-large}"></option>
</select>
</div>
<style>
.a4container {
position: relative;
width: 50%;
aspect-ratio: 0.707;
border: 1px solid #ddd;
box-sizing: border-box;
background-color: white;
}
.pageNumber {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
font-size: 1em;
color: #333;
cursor: pointer;
background-color: #ccc;
width: 15%;
height: 15%;
transform: translate(-50%, -50%);
}
.pageNumber:hover {
background-color: #eee;
}
#myForm {
display: flex;
justify-content: center;
align-items: center;
margin-top: 20px;
}
.selectedPosition {
background-color: #0a0;
}
.selectedPosition.selectedHovered {
background-color: #006600;
}
</style>
<div class="form-group">
<label for="position" th:text="#{addPageNumbers.selectText.3}"></label>
<div class="a4container">
<div class="pageNumber" id="1" style="top: 10%; left: 10%;">1</div>
<div class="pageNumber" id="2" style="top: 10%; left: 50%;">2</div>
<div class="pageNumber" id="3" style="top: 10%; left: 90%;">3</div>
<div class="pageNumber" id="4" style="top: 50%; left: 10%;">4</div>
<div class="pageNumber" id="5" style="top: 50%; left: 50%;">5</div>
<div class="pageNumber" id="6" style="top: 50%; left: 90%;">6</div>
<div class="pageNumber" id="7" style="top: 90%; left: 10%;">7</div>
<div class="pageNumber" id="8" style="top: 90%; left: 50%;">8</div>
<div class="pageNumber" id="9" style="top: 90%; left: 90%;">9</div>
</div>
</div>
<input type="hidden" id="numberInput" name="position" min="1"
max="9" required>
<div class="form-group">
<label for="startingNumber" th:text="#{addPageNumbers.selectText.4}"></label> <input
type="number" class="form-control" id="startingNumber"
name="startingNumber" min="1" required value="1" />
</div>
<div class="form-group">
<label for="pagesToNumber" th:text="#{addPageNumbers.selectText.5}"></label> <input
type="text" class="form-control" id="pagesToNumber"
name="pagesToNumber"
placeholder="Which pages to number, default 'all', also accepts 1-5 or 2,5,9 etc" />
</div>
<div class="form-group">
<label for="customText" th:text="#{addPageNumbers.selectText.6}"></label> <input type="text"
class="form-control" id="customText" name="customText"
placeholder="Default just number, also accepts 'Page {n} of {total}', 'Tag-{n}' etc" />
</div>
<button type="submit" id="submitBtn" class="btn btn-primary"
th:text="#{addPageNumbers.submit}"></button>
</form>
</div>
</div>
</div>
<script>
let cells = document.querySelectorAll('.pageNumber');
let inputField = document.getElementById('numberInput');
cells.forEach(cell => {
cell.addEventListener('click', function(e) {
cells.forEach(cell => {
cell.classList.remove('selectedPosition'); // Remove selected class from all cells
cell.classList.remove('selectedHovered'); // Also remove selectedHovered class
});
let selectedLocation = e.target.id;
inputField.value = selectedLocation;
e.target.classList.add('selectedPosition'); // Add selected class to clicked cell
e.target.classList.add('selectedHovered'); // Add selectedHovered class
});
cell.addEventListener('mouseenter', function(e) {
if(e.target.classList.contains('selectedPosition')) {
e.target.classList.add('selectedHovered');
}
});
cell.addEventListener('mouseleave', function(e) {
if(e.target.classList.contains('selectedPosition')) {
e.target.classList.remove('selectedHovered');
}
});
});
</script>
</div>
<div th:insert="~{fragments/footer.html :: footer}"></div>
</div>
</body>
</html>

View file

@ -1,7 +1,10 @@
<!DOCTYPE html>
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
<html th:lang="${#locale.toString()}"
th:lang-direction="#{language.direction}"
xmlns:th="http://www.thymeleaf.org">
<th:block th:insert="~{fragments/common :: head(title=#{extractImages.title})}"></th:block>
<th:block
th:insert="~{fragments/common :: head(title=#{adjustContrast.title})}"></th:block>
<body>
@ -12,16 +15,274 @@
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6">
<h2 th:text="#{extractImages.header}"></h2>
<h2 th:text="#{adjustContrast.header}"></h2>
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf', remoteCall='false')}"></div>
<h4>
<span th:text="#{adjustContrast.contrast}"></span> <span id="contrast-val">100</span>%
</h4>
<input type="range" min="0" max="200" value="100"
id="contrast-slider" />
<form id="multiPdfForm" th:action="@{adjust-contrast}" method="post" enctype="multipart/form-data">
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
<div class="form-group">
<label for="contrastRange">Contrast</label>
<input name="contrastRange" type="range" class="form-control-range" id="contrastRange" min="-100" max="100" value="0" step="1">
</div>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{extractImages.submit}"></button>
</form>
<h4>
<span th:text="#{adjustContrast.brightness}"></span> <span id="brightness-val">100</span>%
</h4>
<input type="range" min="0" max="200" value="100"
id="brightness-slider" />
<h4>
<span th:text="#{adjustContrast.saturation}"></span> <span id="saturation-val">100</span>%
</h4>
<input type="range" min="0" max="200" value="100"
id="saturation-slider" />
</br>
<canvas id="pdf-canvas"></canvas>
<button id="download-button" class="btn btn-primary" th:text="#{adjustContrast.download}"></button>
<script src="pdfjs/pdf.js"></script>
<script>
var canvas = document.getElementById('pdf-canvas');
var context = canvas.getContext('2d');
var originalImageData = null;
var allPages = [];
var pdfDoc = null;
var pdf = null; // This is the current PDF document
async function renderPDFAndSaveOriginalImageData(file) {
var fileReader = new FileReader();
fileReader.onload = async function() {
var data = new Uint8Array(this.result);
pdf = await pdfjsLib.getDocument({data: data}).promise;
// Get the number of pages in the PDF
var numPages = pdf.numPages;
allPages = Array.from({length: numPages}, (_, i) => i + 1);
// Create a new PDF document
pdfDoc = await PDFLib.PDFDocument.create();
// Render the first page in the viewer
await renderPageAndAdjustImageProperties(1);
};
fileReader.readAsArrayBuffer(file);
}
// This function is now async and returns a promise
function renderPageAndAdjustImageProperties(pageNum) {
return new Promise(async function(resolve, reject) {
var page = await pdf.getPage(pageNum);
var scale = 1.5;
var viewport = page.getViewport({ scale: scale });
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: context,
viewport: viewport
};
var renderTask = page.render(renderContext);
renderTask.promise.then(function () {
originalImageData = context.getImageData(0, 0, canvas.width, canvas.height);
adjustImageProperties();
resolve();
});
});
}
function adjustImageProperties() {
var contrast = parseFloat(document.getElementById('contrast-slider').value);
var brightness = parseFloat(document.getElementById('brightness-slider').value);
var saturation = parseFloat(document.getElementById('saturation-slider').value);
contrast /= 100; // normalize to range [0, 2]
brightness /= 100; // normalize to range [0, 2]
saturation /= 100; // normalize to range [0, 2]
if (originalImageData) {
var newImageData = context.createImageData(originalImageData.width, originalImageData.height);
newImageData.data.set(originalImageData.data);
for(var i=0; i<newImageData.data.length; i+=4)
{
var r = newImageData.data[i];
var g = newImageData.data[i+1];
var b = newImageData.data[i+2];
// Adjust contrast
r = adjustContrastForPixel(r, contrast);
g = adjustContrastForPixel(g, contrast);
b = adjustContrastForPixel(b, contrast);
// Adjust brightness
r = adjustBrightnessForPixel(r, brightness);
g = adjustBrightnessForPixel(g, brightness);
b = adjustBrightnessForPixel(b, brightness);
// Adjust saturation
var rgb = adjustSaturationForPixel(r, g, b, saturation);
newImageData.data[i] = rgb[0];
newImageData.data[i+1] = rgb[1];
newImageData.data[i+2] = rgb[2];
}
context.putImageData(newImageData, 0, 0);
}
}
function rgbToHsl(r, g, b) {
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if (max === min) {
h = s = 0; // achromatic
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [h, s, l];
}
function hslToRgb(h, s, l) {
var r, g, b;
if (s === 0) {
r = g = b = l; // achromatic
} else {
var hue2rgb = function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
};
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return [r * 255, g * 255, b * 255];
}
function adjustContrastForPixel(pixel, contrast) {
// Normalize to range [-0.5, 0.5]
var normalized = pixel / 255 - 0.5;
// Apply contrast
normalized *= contrast;
// Denormalize back to [0, 255]
return (normalized + 0.5) * 255;
}
function clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
}
function adjustSaturationForPixel(r, g, b, saturation) {
var hsl = rgbToHsl(r, g, b);
// Adjust saturation
hsl[1] = clamp(hsl[1] * saturation, 0, 1);
// Convert back to RGB
var rgb = hslToRgb(hsl[0], hsl[1], hsl[2]);
// Return adjusted RGB values
return rgb;
}
function adjustBrightnessForPixel(pixel, brightness) {
return Math.max(0, Math.min(255, pixel * brightness));
}
async function downloadPDF() {
for (var i = 0; i < allPages.length; i++) {
await renderPageAndAdjustImageProperties(allPages[i]);
const pngImageBytes = canvas.toDataURL('image/png');
const pngImage = await pdfDoc.embedPng(pngImageBytes);
const pngDims = pngImage.scale(1);
// Create a blank page matching the dimensions of the image
const page = pdfDoc.addPage([pngDims.width, pngDims.height]);
// Draw the PNG image
page.drawImage(pngImage, {
x: 0,
y: 0,
width: pngDims.width,
height: pngDims.height
});
}
// Serialize the PDFDocument to bytes (a Uint8Array)
const pdfBytes = await pdfDoc.save();
// Create a Blob
const blob = new Blob([pdfBytes.buffer], {type: "application/pdf"});
// Create download link
const downloadLink = document.createElement('a');
downloadLink.href = URL.createObjectURL(blob);
downloadLink.download = "download.pdf";
downloadLink.click();
// After download, reset the viewer and clear stored data
allPages = []; // Clear the pages
originalImageData = null; // Clear the image data
// Go back to page 1 and render it in the viewer
if (pdf !== null) {
renderPageAndAdjustImageProperties(1);
}
}
// Event listeners
document.getElementById('fileInput-input').addEventListener('change', function(e) {
if (e.target.files.length > 0) {
renderPDFAndSaveOriginalImageData(e.target.files[0]);
}
});
document.getElementById('contrast-slider').addEventListener('input', function() {
document.getElementById('contrast-val').textContent = this.value;
adjustImageProperties();
});
document.getElementById('brightness-slider').addEventListener('input', function() {
document.getElementById('brightness-val').textContent = this.value;
adjustImageProperties();
});
document.getElementById('saturation-slider').addEventListener('input', function() {
document.getElementById('saturation-val').textContent = this.value;
adjustImageProperties();
});
document.getElementById('download-button').addEventListener('click', function() {
downloadPDF();
});
</script>
</div>
</div>
</div>

View file

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
<th:block th:insert="~{fragments/common :: head(title=#{auto-rename.title})}"></th:block>
<body>
<th:block th:insert="~{fragments/common :: game}"></th:block>
<div id="page-container">
<div id="content-wrap">
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
<br> <br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6">
<h2 th:text="#{auto-rename.header}"></h2>
<form method="post" enctype="multipart/form-data" th:action="@{auto-rename}">
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
<br>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{auto-rename.submit}"></button>
</form>
</div>
</div>
</div>
</div>
<div th:insert="~{fragments/footer.html :: footer}"></div>
</div>
</body>
</html>

View file

@ -3,107 +3,122 @@
th:lang-direction="#{language.direction}"
xmlns:th="http://www.thymeleaf.org">
<th:block th:insert="~{fragments/common :: head(title=#{pipeline.title})}"></th:block>
<th:block
th:insert="~{fragments/common :: head(title=#{pipeline.title})}"></th:block>
<style>
.btn-margin {
margin-right: 2px;
}
.bordered-box {
border: 1px solid #ddd;
padding: 20px;
margin: 20px;
width: 70%;
}
.center-element {
width: 80%;
text-align: center;
margin: auto;
}
.element-margin {
margin: 10px 0; /* Adjust this value to increase/decrease the margin as needed */
}
</style>
<body>
<div id="page-container">
<div id="content-wrap">
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
<br> <br>
<div class="container" id="dropContainer">
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="bordered-box">
<div class="text-right text-top">
<button id="uploadPipelineBtn" class="btn btn-primary">Upload
Custom</button>
<button type="button" class="btn btn-primary" data-toggle="modal"
data-target="#pipelineSettingsModal">Configure</button>
</div>
<div class="center-element">
<div class="element-margin">
<select id="pipelineSelect" class="custom-select">
<option value="">Select a pipeline</option>
<th:block th:each="config : ${pipelineConfigsWithNames}">
<option th:value="${config.json}" th:text="${config.name}"></option>
</th:block>
</select>
</div>
<div class="element-margin">
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=true)}"></div>
</div>
<div class="element-margin">
<button class="btn btn-primary" id="submitConfigBtn">Submit</button>
</div>
</div>
</div>
<!-- The Modal -->
<div class="modal" id="pipelineSettingsModal">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h2 class="modal-title">Pipeline Configuration</h2>
<button type="button" class="close" data-dismiss="modal">&times;</button>
</div>
<!-- Modal body -->
<div class="modal-body">
<div class="mb-3">
<button id="savePipelineBtn" class="btn btn-success">Download</button>
<button id="validateButton" class="btn btn-success">Validate</button>
<div class="btn-group">
<button id="uploadPipelineBtn" class="btn btn-primary">Upload</button>
<input type="file" id="uploadPipelineInput" accept=".json"
style="display: none;">
<label for="pipelineName" class="form-label">Pipeline
Name</label> <input type="text" id="pipelineName"
class="form-control" placeholder="Enter pipeline name here">
</div>
</div>
<div id="pipelineContainer" class="card">
<!-- Pipeline Configuration Card Header -->
<div class="card-header">
<h2 class="card-title">Pipeline Configuration</h2>
</div>
<!-- Pipeline Configuration Body -->
<div class="card-body">
<div class="mb-3">
<select id="operationsDropdown" class="form-select">
<!-- Options will be dynamically populated here -->
</select>
</div>
<div class="mb-3">
<button id="addOperationBtn" class="btn btn-primary">Add operation</button>
<button id="addOperationBtn" class="btn btn-primary">Add
operation</button>
</div>
<h3>Pipeline:</h3>
<ol id="pipelineList" class="list-group">
<!-- Pipeline operations will be dynamically populated here -->
</ol>
</div>
<input type="file" id="fileInput" multiple>
<button class="btn btn-primary" id="submitConfigBtn">Submit</button>
</div>
<!-- pipelineSettings modal -->
<div id="pipelineSettingsModal" class="modal">
<div class="modal-content">
<div class="modal-body">
<span class="close">&times;</span>
<h2>Operation Settings</h2>
<div id="pipelineSettingsContent">
<!-- pipelineSettings will be dynamically populated here -->
</div>
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button id="savePipelineBtn" class="btn btn-success">Download</button>
<button id="validateButton" class="btn btn-success">Validate</button>
<div class="btn-group">
<input type="file" id="uploadPipelineInput" accept=".json"
style="display: none;">
</div>
</div>
</div>
</div>
</div>
<script src="js/pipeline.js"></script>
</div>
</div>
</div>
</div>
</div>
<style>
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
padding-top: 100px; /* Location of the box */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0, 0, 0); /* Fallback color */
background-color: rgba(0, 0, 0, 0.4); /* Black w/ opacity */
}
/* Modal Content */
.modal-content {
background-color: #fefefe;
margin: auto;
padding: 20px;
border: 1px solid #888;
width: 50%;
}
</div>
</div>
</div>
.btn-margin {
margin-right: 2px;
}
.modal-body {
display: flex;
flex-direction: column;
}
</style>
<div th:insert="~{fragments/footer.html :: footer}"></div>
</div>

View file

@ -3,7 +3,7 @@
<th:block th:insert="~{fragments/common :: head(title=#{watermark.title})}"></th:block>
<body>
<body onload="toggleFileOption()">
<div id="page-container">
<div id="content-wrap">
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
@ -16,30 +16,36 @@
<form method="post" enctype="multipart/form-data" action="add-watermark">
<div class="form-group">
<label th:text="#{watermark.selectText.1}"></label>
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}">
<input type="file" id="fileInput" name="fileInput" class="form-control-file" accept="application/pdf" required />
</div>
</div>
<div class="form-group">
<label for="fontSize" th:text="#{alphabet} + ':'"></label>
<select class="form-control" name="alphabet" id="alphabet-select">
<option value="romain">Roman</option>
<option value="arabic">العربية</option>
<option value="japanese">日本語</option>
<option value="korean">한국어</option>
<option value="chinese">简体中文</option>
<label th:text="#{watermark.selectText.8}"></label>
<select class="form-control" id="watermarkType" name="watermarkType" onchange="toggleFileOption()">
<option value="text">Text</option>
<option value="image">Image</option>
</select>
</div>
<div class="form-group">
<div id="watermarkTextGroup" class="form-group">
<label for="watermarkText" th:text="#{watermark.selectText.2}"></label>
<input type="text" id="watermarkText" name="watermarkText" class="form-control" placeholder="Stirling-PDF" required />
</div>
<div id="watermarkImageGroup" class="form-group" style="display: none;">
<label for="watermarkImage" th:text="#{watermark.selectText.9}"></label>
<input type="file" id="watermarkImage" name="watermarkImage" class="form-control-file" accept="image/*" />
</div>
<div class="form-group">
<label for="fontSize" th:text="#{watermark.selectText.3}"></label>
<input type="text" id="fontSize" name="fontSize" class="form-control" value="30" />
</div>
<div class="form-group">
<label for="opacity" th:text="#{watermark.selectText.7}"></label>
<input type="text" id="opacity" name="opacityText" class="form-control" value="50" onblur="updateopacityValue()" />
<input type="text" id="opacity" name="opacityText" class="form-control" value="50" onblur="updateOpacityValue()" />
<input type="hidden" id="opacityReal" name="opacity" value="0.5">
</div>
@ -48,7 +54,7 @@
const opacityInput = document.getElementById('opacity');
const opacityRealInput = document.getElementById('opacityReal');
const updateopacityValue = () => {
const updateOpacityValue = () => {
let percentageValue = parseFloat(opacityInput.value.replace('%', ''));
if (isNaN(percentageValue)) {
percentageValue = 0;
@ -68,14 +74,15 @@
opacityInput.value = opacityInput.value.replace('%', '');
});
opacityInput.addEventListener('blur', () => {
updateopacityValue();
updateOpacityValue();
appendPercentageSymbol();
});
// Set initial values
updateopacityValue();
updateOpacityValue();
appendPercentageSymbol();
</script>
<div class="form-group">
<label for="rotation" th:text="#{watermark.selectText.4}"></label>
<input type="text" id="rotation" name="rotation" class="form-control" value="45" />
@ -92,6 +99,29 @@
<input type="submit" id="submitBtn" th:value="#{watermark.submit}" class="btn btn-primary" />
</div>
</form>
<script>
function toggleFileOption() {
const watermarkType = document.getElementById('watermarkType').value;
const watermarkTextGroup = document.getElementById('watermarkTextGroup');
const watermarkImageGroup = document.getElementById('watermarkImageGroup');
const watermarkText = document.getElementById('watermarkText');
const watermarkImage = document.getElementById('watermarkImage');
if (watermarkType === 'text') {
watermarkTextGroup.style.display = 'block';
watermarkText.required = true;
watermarkImageGroup.style.display = 'none';
watermarkImage.required = false;
} else if (watermarkType === 'image') {
watermarkTextGroup.style.display = 'none';
watermarkText.required = false;
watermarkImageGroup.style.display = 'block';
watermarkImage.required = true;
}
}
</script>
</div>
</div>
</div>

View file

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
<th:block th:insert="~{fragments/common :: head(title=#{sanitizePDF.title})}"></th:block>
<body>
<div id="page-container">
<div id="content-wrap">
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
<br> <br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6">
<h2 th:text="#{sanitizePDF.header}"></h2>
<form action="sanitize-pdf" method="post" enctype="multipart/form-data">
<div class="form-group">
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="removeJavaScript" name="removeJavaScript" checked>
<label class="form-check-label" for="removeJavaScript" th:text="#{sanitizePDF.selectText.1}"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="removeEmbeddedFiles" name="removeEmbeddedFiles" checked>
<label class="form-check-label" for="removeEmbeddedFiles" th:text="#{sanitizePDF.selectText.2}"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="removeMetadata" name="removeMetadata" checked>
<label class="form-check-label" for="removeMetadata" th:text="#{sanitizePDF.selectText.3}"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="removeLinks" name="removeLinks" checked>
<label class="form-check-label" for="removeLinks" th:text="#{sanitizePDF.selectText.4}"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="removeFonts" name="removeFonts" checked>
<label class="form-check-label" for="removeFonts" th:text="#{sanitizePDF.selectText.5}"></label>
</div>
<br />
<div class="form-group text-center">
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{sanitizePDF.submit}"></button>
</div>
</form>
</div>
</div>
</div>
</div>
<div th:insert="~{fragments/footer.html :: footer}"></div>
</div>
</body>
</html>

View file

@ -7,16 +7,27 @@
<script src="js/thirdParty/interact.min.js"></script>
</head>
<th:block th:each="font : ${fonts}">
<style th:inline="text">
@font-face {
font-family: "[[${font}]]";
src: url('fonts/[[${font}]].woff2') format('woff2');
}
#font-select option[value="[[${font}]]"] {
font-family: "[[${font}]]", cursive;
}
</style>
</th:block>
<style>
@font-face {
font-family: 'Estonia';
src: url(fonts/Estonia.woff2) format('woff2');
}
@font-face {
font-family: 'Tangerine';
src: url(fonts/Tangerine.woff2) format('woff2');
}
select#font-select, select#font-select option {
height: 60px; /* Adjust as needed */
font-size: 30px; /* Adjust as needed */
}
</style>
<body>
<div id="page-container">
<div id="content-wrap">
@ -169,8 +180,8 @@
<input type="text" class="form-control" id="sigText" name="sigText">
<label th:text="#{font}"></label>
<select class="form-control" name="font" id="font-select">
<option value="Estonia" class="estonia-font">Estonia</option>
<option value="Tangerine" class="tangerine-font">Tangerine</option>
<option th:each="font : ${fonts}" th:value="${font}" th:text="${font}" th:class="${font.toLowerCase()+'-font'}"></option>
</select>
<div class="margin-auto-parent">
<button id="save-text-signature" class="btn btn-outline-success mt-2 margin-center" onclick="addDraggableFromText()" th:text="#{sign.add}"></button>
@ -196,20 +207,37 @@
DraggableUtils.createDraggableCanvasFromUrl(dataURL);
}
</script>
<style>
#font-select option {
font-size: 30px;
<script>
const sigTextInput = document.getElementById('sigText');
const fontSelect = document.getElementById('font-select');
const updateOptionTexts = () => {
Array.from(fontSelect.options).forEach(option => {
const fontName = option.value.replace(/-regular$/i, '');
option.text = sigTextInput.value || fontName;
});
}
#font-select option[value="Estonia"] {
font-family: 'Estonia', sans-serif;
}
#font-select option[value="Tangerine"] {
font-family: 'Tangerine', cursive;
}
#font-select option[value="Windsong"] {
font-family: 'Windsong', cursive;
sigTextInput.addEventListener('input', updateOptionTexts);
fontSelect.addEventListener('change', (e) => {
e.target.style.fontFamily = e.target.value;
updateOptionTexts();
});
// Manually trigger the change event
fontSelect.dispatchEvent(new Event('change'));
</script>
<th:block th:each="font : ${fonts}">
<style th:inline="text">
#font-select option[value="/*[[${font}]]*/"] {
font-family: '/*[[${font}]]*/', cursive;
}
</style>
</th:block>
</div>
</div>
@ -240,10 +268,6 @@
position: relative;
margin: 20px 0;
}
#pdf-canvas {
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
width: 100%;
}
.draggable-buttons-box {
position: absolute;
top: 0;
@ -271,6 +295,7 @@
<div class="margin-auto-parent">
<button id="download-pdf" class="btn btn-primary mb-2 show-on-file-selected margin-center">Download PDF</button>
</div>
<script>
document.getElementById("download-pdf").addEventListener('click', async() => {
const modifiedPdf = await DraggableUtils.getOverlayedPdfDocument();