commit
37e2cd40da
73 changed files with 12846 additions and 8464 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -15,6 +15,13 @@ local.properties
|
|||
.classpath
|
||||
.project
|
||||
version.properties
|
||||
pipeline/
|
||||
|
||||
#### Stirling-PDF Files ###
|
||||
customFiles/
|
||||
config/
|
||||
watchedFolders/
|
||||
|
||||
|
||||
# Gradle
|
||||
.gradle
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 | | | | ✔️ | ✔️ | | | | ✔️ | | |
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 | ✔️ | ✔️ | ✔️
|
||||
|
|
|
@ -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")
|
||||
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
|
@ -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<>();
|
||||
|
|
|
@ -21,63 +21,79 @@ 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(
|
||||
@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)
|
||||
throws IOException, InterruptedException {
|
||||
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", 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());
|
||||
|
@ -92,52 +108,68 @@ 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(
|
||||
@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)
|
||||
throws IOException, InterruptedException {
|
||||
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", 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(
|
||||
@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)
|
||||
throws IOException, InterruptedException {
|
||||
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", 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());
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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,124 +35,164 @@ 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")
|
||||
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",
|
||||
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 {
|
||||
@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 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,
|
||||
@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,
|
||||
|
||||
// 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()) {
|
||||
@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(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 {
|
||||
|
||||
// Get the page's content stream
|
||||
PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true);
|
||||
// Load the input PDF
|
||||
PDDocument document = PDDocument.load(pdfFile.getInputStream());
|
||||
|
||||
// Set transparency
|
||||
PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();
|
||||
graphicsState.setNonStrokingAlphaConstant(opacity);
|
||||
contentStream.setGraphicsStateParameters(graphicsState);
|
||||
// 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);
|
||||
|
||||
// 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) {
|
||||
case "arabic":
|
||||
resourceDir = "static/fonts/NotoSansArabic-Regular.ttf";
|
||||
break;
|
||||
case "japanese":
|
||||
resourceDir = "static/fonts/Meiryo.ttf";
|
||||
break;
|
||||
case "korean":
|
||||
resourceDir = "static/fonts/malgun.ttf";
|
||||
break;
|
||||
case "chinese":
|
||||
resourceDir = "static/fonts/SimSun.ttf";
|
||||
break;
|
||||
case "roman":
|
||||
default:
|
||||
resourceDir = "static/fonts/NotoSans-Regular.ttf";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
String resourceDir = "";
|
||||
PDFont font = PDType1Font.HELVETICA_BOLD;
|
||||
switch (alphabet) {
|
||||
case "arabic":
|
||||
resourceDir = "static/fonts/NotoSansArabic-Regular.ttf";
|
||||
break;
|
||||
case "japanese":
|
||||
resourceDir = "static/fonts/Meiryo.ttf";
|
||||
break;
|
||||
case "korean":
|
||||
resourceDir = "static/fonts/malgun.ttf";
|
||||
break;
|
||||
case "chinese":
|
||||
resourceDir = "static/fonts/SimSun.ttf";
|
||||
break;
|
||||
case "roman":
|
||||
default:
|
||||
resourceDir = "static/fonts/NotoSans-Regular.ttf";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(!resourceDir.equals("")) {
|
||||
ClassPathResource classPathResource = new ClassPathResource(resourceDir);
|
||||
String fileExtension = resourceDir.substring(resourceDir.lastIndexOf("."));
|
||||
File tempFile = File.createTempFile("NotoSansFont", fileExtension);
|
||||
try (InputStream is = classPathResource.getInputStream(); FileOutputStream os = new FileOutputStream(tempFile)) {
|
||||
IOUtils.copy(is, os);
|
||||
}
|
||||
|
||||
font = PDType0Font.load(document, tempFile);
|
||||
tempFile.deleteOnExit();
|
||||
if(!resourceDir.equals("")) {
|
||||
ClassPathResource classPathResource = new ClassPathResource(resourceDir);
|
||||
String fileExtension = resourceDir.substring(resourceDir.lastIndexOf("."));
|
||||
File tempFile = File.createTempFile("NotoSansFont", fileExtension);
|
||||
try (InputStream is = classPathResource.getInputStream(); FileOutputStream os = new FileOutputStream(tempFile)) {
|
||||
IOUtils.copy(is, os);
|
||||
}
|
||||
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();
|
||||
float watermarkWidth = widthSpacer + font.getStringWidth(watermarkText) * fontSize / 1000;
|
||||
float watermarkHeight = heightSpacer + fontSize;
|
||||
int watermarkRows = (int) (pageHeight / watermarkHeight + 1);
|
||||
int watermarkCols = (int) (pageWidth / watermarkWidth + 1);
|
||||
|
||||
// Add the watermark text
|
||||
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.endText();
|
||||
|
||||
// Close the content stream
|
||||
contentStream.close();
|
||||
font = PDType0Font.load(document, tempFile);
|
||||
tempFile.deleteOnExit();
|
||||
}
|
||||
return WebResponseUtils.pdfDocToWebResponse(document, pdfFile.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_watermarked.pdf");
|
||||
}
|
||||
|
||||
contentStream.setFont(font, fontSize);
|
||||
contentStream.setNonStrokingColor(Color.LIGHT_GRAY);
|
||||
|
||||
// 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 text watermark
|
||||
for (int i = 0; i < watermarkRows; i++) {
|
||||
for (int j = 0; j < watermarkCols; j++) {
|
||||
contentStream.beginText();
|
||||
contentStream.setTextMatrix(Matrix.getRotateInstance((float) Math.toRadians(rotation),
|
||||
j * watermarkWidth, i * watermarkHeight));
|
||||
contentStream.showText(watermarkText);
|
||||
contentStream.endText();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
return "pipeline";
|
||||
|
||||
@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";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 + "]";
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,11 +107,16 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
public boolean containsTextInFile(PDDocument pdfDocument, String text, String pagesToCheck) throws IOException {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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 لتحويل الملفات.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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=변환
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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=Конвертировать
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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=合并多个PDF(2个以上)。
|
||||
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进行文件转换。
|
||||
|
|
|
@ -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%;
|
||||
}
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Binary file not shown.
Binary file not shown.
BIN
src/main/resources/static/fonts/DancingScript-Regular.woff2
Normal file
BIN
src/main/resources/static/fonts/DancingScript-Regular.woff2
Normal file
Binary file not shown.
BIN
src/main/resources/static/fonts/IndieFlower-Regular.woff2
Normal file
BIN
src/main/resources/static/fonts/IndieFlower-Regular.woff2
Normal file
Binary file not shown.
3
src/main/resources/static/images/add-page-numbers.svg
Normal file
3
src/main/resources/static/images/add-page-numbers.svg
Normal 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 |
4
src/main/resources/static/images/adjust-contrast.svg
Normal file
4
src/main/resources/static/images/adjust-contrast.svg
Normal 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 |
3
src/main/resources/static/images/crop.svg
Normal file
3
src/main/resources/static/images/crop.svg
Normal 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 |
3
src/main/resources/static/images/fonts.svg
Normal file
3
src/main/resources/static/images/fonts.svg
Normal 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 |
1
src/main/resources/static/images/sanitize.svg
Normal file
1
src/main/resources/static/images/sanitize.svg
Normal 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 |
|
@ -1,30 +1,84 @@
|
|||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const fileInput = document.getElementById(elementID);
|
||||
// Prevent default behavior for drag events
|
||||
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
||||
fileInput.addEventListener(eventName, preventDefaults, false);
|
||||
});
|
||||
|
||||
function preventDefaults(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
let overlay;
|
||||
let dragCounter = 0;
|
||||
|
||||
// Add drop event listener
|
||||
fileInput.addEventListener('drop', handleDrop, false);
|
||||
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 => {
|
||||
document.body.addEventListener(eventName, preventDefaults, false);
|
||||
});
|
||||
|
||||
function preventDefaults(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
document.body.addEventListener('dragenter', dragenterListener);
|
||||
document.body.addEventListener('dragleave', dragleaveListener);
|
||||
// Add drop event listener
|
||||
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);
|
||||
handleFileInputChange(this);
|
||||
});
|
||||
|
||||
|
||||
function handleFileInputChange(inputElement) {
|
||||
const files = $(inputElement).get(0).files;
|
||||
const fileNames = Array.from(files).map(f => f.name);
|
||||
|
|
|
@ -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;
|
|
@ -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++) {
|
||||
|
@ -142,25 +148,25 @@ fetch('v3/api-docs')
|
|||
});
|
||||
|
||||
// Specify the order of tags
|
||||
let tagOrder = ["General", "Security", "Convert", "Other", "Filter"];
|
||||
let tagOrder = ["General", "Security", "Convert", "Other", "Filter"];
|
||||
|
||||
// Create dropdown options
|
||||
tagOrder.forEach(tag => {
|
||||
if (operationsByTag[tag]) {
|
||||
let group = document.createElement('optgroup');
|
||||
group.label = tag;
|
||||
// Create dropdown options
|
||||
tagOrder.forEach(tag => {
|
||||
if (operationsByTag[tag]) {
|
||||
let group = document.createElement('optgroup');
|
||||
group.label = tag;
|
||||
|
||||
operationsByTag[tag].forEach(operationPath => {
|
||||
let option = document.createElement('option');
|
||||
let operationWithoutSlash = operationPath.replace(/\//g, ''); // Remove slashes
|
||||
option.textContent = operationWithoutSlash;
|
||||
option.value = operationPath; // Keep the value with slashes for querying
|
||||
group.appendChild(option);
|
||||
});
|
||||
operationsByTag[tag].forEach(operationPath => {
|
||||
let option = document.createElement('option');
|
||||
let operationWithoutSlash = operationPath.replace(/\//g, ''); // Remove slashes
|
||||
option.textContent = operationWithoutSlash;
|
||||
option.value = operationPath; // Keep the value with slashes for querying
|
||||
group.appendChild(option);
|
||||
});
|
||||
|
||||
operationsDropdown.appendChild(group);
|
||||
}
|
||||
});
|
||||
operationsDropdown.appendChild(group);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
@ -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,38 +249,62 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
|
|||
parameterDiv.appendChild(parameterLabel);
|
||||
|
||||
let parameterInput;
|
||||
switch (parameter.schema.type) {
|
||||
case 'string':
|
||||
case 'number':
|
||||
case 'integer':
|
||||
parameterInput = document.createElement('input');
|
||||
parameterInput.type = parameter.schema.type === 'string' ? 'text' : 'number';
|
||||
parameterInput.className = "form-control";
|
||||
break;
|
||||
case 'boolean':
|
||||
parameterInput = document.createElement('input');
|
||||
parameterInput.type = 'checkbox';
|
||||
break;
|
||||
case 'array':
|
||||
case 'object':
|
||||
parameterInput = document.createElement('textarea');
|
||||
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";
|
||||
|
||||
// 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 = 'number';
|
||||
parameterInput.className = "form-control";
|
||||
break;
|
||||
case 'boolean':
|
||||
parameterInput = document.createElement('input');
|
||||
parameterInput.type = 'checkbox';
|
||||
break;
|
||||
case 'array':
|
||||
case 'object':
|
||||
parameterInput = document.createElement('textarea');
|
||||
parameterInput.placeholder = `Enter a JSON formatted ${parameter.schema.type}`;
|
||||
parameterInput.className = "form-control";
|
||||
break;
|
||||
default:
|
||||
parameterInput = document.createElement('input');
|
||||
parameterInput.type = 'text';
|
||||
parameterInput.className = "form-control";
|
||||
}
|
||||
}
|
||||
parameterInput.id = parameter.name;
|
||||
|
||||
|
@ -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,6 +419,60 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
|
|||
document.body.removeChild(a);
|
||||
});
|
||||
|
||||
async function processPipelineConfig(configString) {
|
||||
let pipelineConfig = JSON.parse(configString);
|
||||
let pipelineList = document.getElementById('pipelineList');
|
||||
|
||||
while (pipelineList.firstChild) {
|
||||
pipelineList.removeChild(pipelineList.firstChild);
|
||||
}
|
||||
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;
|
||||
|
||||
Object.keys(operationConfig.parameters).forEach(parameterName => {
|
||||
let input = document.getElementById(parameterName);
|
||||
if (input) {
|
||||
switch (input.type) {
|
||||
case 'checkbox':
|
||||
input.checked = operationConfig.parameters[parameterName];
|
||||
break;
|
||||
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:
|
||||
input.value = JSON.stringify(operationConfig.parameters[parameterName]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('uploadPipelineBtn').addEventListener('click', function() {
|
||||
document.getElementById('uploadPipelineInput').click();
|
||||
});
|
||||
|
@ -375,45 +480,15 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
|
|||
document.getElementById('uploadPipelineInput').addEventListener('change', function(e) {
|
||||
let reader = new FileReader();
|
||||
reader.onload = function(event) {
|
||||
let pipelineConfig = JSON.parse(event.target.result);
|
||||
let pipelineList = document.getElementById('pipelineList');
|
||||
|
||||
while (pipelineList.firstChild) {
|
||||
pipelineList.removeChild(pipelineList.firstChild);
|
||||
}
|
||||
|
||||
pipelineConfig.pipeline.forEach(operationConfig => {
|
||||
let operationsDropdown = document.getElementById('operationsDropdown');
|
||||
operationsDropdown.value = operationConfig.operation;
|
||||
operationSettings[operationConfig.operation] = operationConfig.parameters;
|
||||
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) {
|
||||
switch (input.type) {
|
||||
case 'checkbox':
|
||||
input.checked = operationConfig.parameters[parameterName];
|
||||
break;
|
||||
case 'number':
|
||||
input.value = operationConfig.parameters[parameterName].toString();
|
||||
break;
|
||||
case 'text':
|
||||
case 'textarea':
|
||||
default:
|
||||
input.value = JSON.stringify(operationConfig.parameters[parameterName]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelector('#pipelineSettingsModal .btn-primary').click();
|
||||
});
|
||||
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);
|
||||
});
|
||||
|
||||
|
||||
});
|
72
src/main/resources/static/js/search.js
Normal file
72
src/main/resources/static/js/search.js
Normal 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';
|
||||
});
|
||||
|
40
src/main/resources/templates/auto-split-pdf.html
Normal file
40
src/main/resources/templates/auto-split-pdf.html
Normal 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>
|
145
src/main/resources/templates/crop.html
Normal file
145
src/main/resources/templates/crop.html
Normal 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>
|
|
@ -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">
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
154
src/main/resources/templates/other/add-page-numbers.html
Normal file
154
src/main/resources/templates/other/add-page-numbers.html
Normal 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>
|
|
@ -1,32 +1,293 @@
|
|||
<!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>
|
||||
<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="#{extractImages.header}"></h2>
|
||||
<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="#{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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
30
src/main/resources/templates/other/auto-rename.html
Normal file
30
src/main/resources/templates/other/auto-rename.html
Normal 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>
|
|
@ -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>
|
||||
<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="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
|
||||
<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;">
|
||||
</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>
|
||||
</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">×</span>
|
||||
<h2>Operation Settings</h2>
|
||||
<div id="pipelineSettingsContent">
|
||||
<!-- pipelineSettings will be dynamically populated here -->
|
||||
</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%;
|
||||
}
|
||||
|
||||
<th:block
|
||||
th:insert="~{fragments/common :: head(title=#{pipeline.title})}"></th:block>
|
||||
<style>
|
||||
.btn-margin {
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.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">
|
||||
<div class="row justify-content-center">
|
||||
|
||||
<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">×</button>
|
||||
</div>
|
||||
|
||||
<!-- Modal body -->
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label for="pipelineName" class="form-label">Pipeline
|
||||
Name</label> <input type="text" id="pipelineName"
|
||||
class="form-control" placeholder="Enter pipeline name here">
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
<h3>Pipeline:</h3>
|
||||
<ol id="pipelineList" class="list-group">
|
||||
<!-- Pipeline operations will be dynamically populated here -->
|
||||
</ol>
|
||||
<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 th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -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>
|
||||
</select>
|
||||
<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>
|
||||
|
|
53
src/main/resources/templates/security/sanitize-pdf.html
Normal file
53
src/main/resources/templates/security/sanitize-pdf.html
Normal 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>
|
|
@ -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,9 +180,9 @@
|
|||
<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>
|
||||
</select>
|
||||
<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>
|
||||
</div>
|
||||
|
@ -196,20 +207,37 @@
|
|||
DraggableUtils.createDraggableCanvasFromUrl(dataURL);
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
#font-select option {
|
||||
font-size: 30px;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
</style>
|
||||
<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;
|
||||
});
|
||||
}
|
||||
|
||||
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();
|
||||
|
|
Loading…
Reference in a new issue