Compare commits
37 Commits
v0.40.1
...
2808-featu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
835cc3c331 | ||
|
|
5774026a1d | ||
|
|
0efd37b076 | ||
|
|
6a3064f7f2 | ||
|
|
158708b696 | ||
|
|
0233086487 | ||
|
|
242aa5eae1 | ||
|
|
bf65c456d1 | ||
|
|
26720c5018 | ||
|
|
2ed07e3fcb | ||
|
|
e382d254ee | ||
|
|
507d21772d | ||
|
|
5bf050d77f | ||
|
|
976caeb79d | ||
|
|
2d3611fd00 | ||
|
|
118de1789a | ||
|
|
b56d54a35a | ||
|
|
b9bfcd59cd | ||
|
|
f8adc0f101 | ||
|
|
69d4b52b06 | ||
|
|
5e3612a9b0 | ||
|
|
b3a4597ad1 | ||
|
|
dc46172deb | ||
|
|
04696dc2aa | ||
|
|
b37457b41d | ||
|
|
46c53a9c88 | ||
|
|
5f610da671 | ||
|
|
bacc502f07 | ||
|
|
883281e4df | ||
|
|
9e8c16f313 | ||
|
|
4a7df3fd3f | ||
|
|
f725f92e1a | ||
|
|
9d2c23f612 | ||
|
|
637446fab8 | ||
|
|
196c0f4a39 | ||
|
|
f9b92eec71 | ||
|
|
3be6b0659e |
65
.devcontainer/Dockerfile.dev
Normal file
@@ -0,0 +1,65 @@
|
||||
# Main stage
|
||||
FROM alpine:edge
|
||||
|
||||
LABEL org.opencontainers.image.title="Stirling-PDF"
|
||||
LABEL org.opencontainers.image.description="A powerful locally hosted web-based PDF manipulation tool supporting 50+ operations including merging, splitting, conversion, OCR, watermarking, and more."
|
||||
LABEL org.opencontainers.image.source="https://github.com/Stirling-Tools/Stirling-PDF"
|
||||
LABEL org.opencontainers.image.licenses="MIT"
|
||||
LABEL org.opencontainers.image.vendor="Stirling-Tools"
|
||||
LABEL org.opencontainers.image.url="https://www.stirlingpdf.com"
|
||||
LABEL org.opencontainers.image.documentation="https://docs.stirlingpdf.com"
|
||||
LABEL maintainer="Stirling-Tools"
|
||||
LABEL org.opencontainers.image.authors="Stirling-Tools"
|
||||
LABEL org.opencontainers.image.keywords="PDF, manipulation, merge, split, convert, OCR, watermark"
|
||||
|
||||
# Set Environment Variables
|
||||
ENV DOCKER_ENABLE_SECURITY=false \
|
||||
JAVA_TOOL_OPTIONS="-XX:+UnlockExperimentalVMOptions \
|
||||
-XX:MaxRAMPercentage=75 \
|
||||
-XX:InitiatingHeapOccupancyPercent=20 \
|
||||
-XX:+G1PeriodicGCInvokesConcurrent \
|
||||
-XX:G1PeriodicGCInterval=10000 \
|
||||
-XX:+UseStringDeduplication \
|
||||
-XX:G1PeriodicGCSystemLoadThreshold=70" \
|
||||
HOME=/home/stirlingpdfuser \
|
||||
PUID=1000 \
|
||||
PGID=1000 \
|
||||
UMASK=022
|
||||
|
||||
|
||||
# JDK for app
|
||||
RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
|
||||
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \
|
||||
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories
|
||||
RUN apk upgrade -a
|
||||
RUN apk add ca-certificates
|
||||
RUN apk add tzdata
|
||||
RUN apk add tini
|
||||
RUN apk add bash
|
||||
RUN apk add curl
|
||||
RUN apk add git
|
||||
|
||||
RUN apk add qpdf
|
||||
RUN apk add shadow
|
||||
RUN apk add su-exec
|
||||
RUN apk add openssl
|
||||
RUN apk add openssl-dev
|
||||
RUN apk add openjdk21
|
||||
# Doc conversion
|
||||
RUN apk add libreoffice
|
||||
# pdftohtml
|
||||
RUN apk add poppler-utils
|
||||
# OCR MY PDF (unpaper for descew and other advanced features)
|
||||
RUN apk add tesseract-ocr-data-eng
|
||||
# python3/pip
|
||||
|
||||
RUN apk add python3
|
||||
RUN apk add py3-pip
|
||||
RUN apk add py3-opencv
|
||||
RUN apk add -X https://dl-cdn.alpinelinux.org/alpine/edge/testing py3-unoconv
|
||||
RUN apk add -X https://dl-cdn.alpinelinux.org/alpine/edge/testing py3-pdf2image
|
||||
RUN apk add -X https://dl-cdn.alpinelinux.org/alpine/edge/testing py3-pillow
|
||||
|
||||
RUN pip install --break-system-packages --upgrade WeasyPrint
|
||||
|
||||
EXPOSE 8080/tcp
|
||||
49
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,49 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||
// README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-dockerfile
|
||||
{
|
||||
"name": "Existing Dockerfile",
|
||||
"build": {
|
||||
// Sets the run context to one level up instead of the .devcontainer folder.
|
||||
"context": "..",
|
||||
// Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename.
|
||||
"dockerfile": "./Dockerfile.dev"
|
||||
},
|
||||
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||
// "features": {},
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
"forwardPorts": [
|
||||
8080
|
||||
],
|
||||
// Uncomment the next line to run commands after the container is created.
|
||||
// "postCreateCommand": "cat /etc/os-release",
|
||||
// Configure tool-specific properties.
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"elagil.pre-commit-helper", // Support for pre-commit hooks to enforce code quality
|
||||
"josevseb.google-java-format-for-vs-code", // Google Java code formatter to follow the Google Java Style Guide
|
||||
"ms-python.black-formatter", // Python code formatter using Black
|
||||
"ms-python.flake8", // Flake8 linter for Python to enforce code quality
|
||||
"ms-python.python", // Official Microsoft Python extension with IntelliSense, debugging, and Jupyter support
|
||||
// "ms-vscode-remote.remote-containers", // Support for remote development with containers (Docker, Dev Containers)
|
||||
// "ms-vscode-remote.vscode-remote-extensionpack", // Remote Development Pack for SSH, WSL, and Containers
|
||||
"Oracle.oracle-java", // Oracle Java extension with additional features for Java development
|
||||
"redhat.java", // Java support by Red Hat with IntelliSense, debugging, and code navigation
|
||||
"shengchen.vscode-checkstyle", // Checkstyle integration for Java code quality checks
|
||||
"streetsidesoftware.code-spell-checker", // Spell checker for code to avoid typos
|
||||
"vmware.vscode-boot-dev-pack", // Developer tools for Spring Boot by VMware
|
||||
"vmware.vscode-spring-boot", // Spring Boot tools by VMware for enhanced Spring development
|
||||
"vscjava.vscode-gradle", // Gradle extension for build and automation support
|
||||
"vscjava.vscode-java-debug", // Debugging support for Java projects
|
||||
"vscjava.vscode-java-dependency", // Java dependency management within VS Code
|
||||
"vscjava.vscode-java-pack", // Java Extension Pack with essential Java tools for VS Code
|
||||
"vscjava.vscode-java-test", // Java test framework for running and debugging tests in VS Code
|
||||
"vscjava.vscode-spring-boot-dashboard", // Spring Boot dashboard for managing and visualizing Spring Boot applications
|
||||
"vscjava.vscode-spring-initializr", // Support for Spring Initializr to create new Spring projects
|
||||
"ms-azuretools.vscode-docker" // build, manage, and deploy containerized applications from Visual Studio Code
|
||||
]
|
||||
}
|
||||
}
|
||||
// Uncomment to connect as an existing user other than the container default. More info: https://aka.ms/dev-containers-non-root.
|
||||
// "remoteUser": "devcontainer"
|
||||
}
|
||||
2
.github/workflows/PR-Demo-Comment.yml
vendored
@@ -94,7 +94,7 @@ jobs:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
||||
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||
with:
|
||||
java-version: "17"
|
||||
distribution: "temurin"
|
||||
|
||||
43
.github/workflows/build.yml
vendored
@@ -32,17 +32,11 @@ jobs:
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set up JDK ${{ matrix.jdk-version }}
|
||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
||||
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||
with:
|
||||
java-version: ${{ matrix.jdk-version }}
|
||||
distribution: "temurin"
|
||||
|
||||
- name: PR | Generate verification metadata with signatures and checksums for dependabot[bot]
|
||||
if: github.event.pull_request.user.login == 'dependabot[bot]'
|
||||
run: |
|
||||
./gradlew clean dependencies buildEnvironment spotlessApply --write-verification-metadata sha256 --refresh-dependencies help
|
||||
./gradlew clean dependencies buildEnvironment spotlessApply --write-verification-metadata sha256,pgp --refresh-keys --export-keys --refresh-dependencies help
|
||||
|
||||
- name: Build with Gradle and no spring security
|
||||
run: ./gradlew clean build
|
||||
env:
|
||||
@@ -64,6 +58,35 @@ jobs:
|
||||
build/reports/problems/
|
||||
retention-days: 3
|
||||
|
||||
check-licence:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||
with:
|
||||
java-version: "17"
|
||||
distribution: "adopt"
|
||||
|
||||
- name: check the licenses for compatibility
|
||||
run: ./gradlew clean checkLicense
|
||||
|
||||
- name: FAILED - check the licenses for compatibility
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
name: dependencies-without-allowed-license.json
|
||||
path: |
|
||||
build/reports/dependency-license/dependencies-without-allowed-license.json
|
||||
retention-days: 3
|
||||
|
||||
docker-compose-tests:
|
||||
# if: github.event_name == 'push' && github.ref == 'refs/heads/main' ||
|
||||
# (github.event_name == 'pull_request' &&
|
||||
@@ -91,7 +114,7 @@ jobs:
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set up Java 17
|
||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
||||
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||
with:
|
||||
java-version: "17"
|
||||
distribution: "adopt"
|
||||
@@ -105,7 +128,7 @@ jobs:
|
||||
sudo chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
||||
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
cache: 'pip' # caching pip dependencies
|
||||
@@ -118,4 +141,4 @@ jobs:
|
||||
run: |
|
||||
chmod +x ./testing/test_webpages.sh
|
||||
chmod +x ./testing/test.sh
|
||||
./testing/test.sh "${{ github.event.pull_request.user.login == 'dependabot[bot]' }}"
|
||||
./testing/test.sh
|
||||
|
||||
2
.github/workflows/check_properties.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
||||
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
|
||||
21
.github/workflows/licenses-update.yml
vendored
@@ -24,24 +24,33 @@ jobs:
|
||||
|
||||
- name: Generate GitHub App Token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
|
||||
uses: actions/create-github-app-token@136412a57a7081aa63c935a2cc2918f76c34f514 # v1.11.2
|
||||
with:
|
||||
app-id: ${{ secrets.GH_APP_ID }}
|
||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
|
||||
|
||||
- name: Check out code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
||||
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||
with:
|
||||
java-version: "17"
|
||||
distribution: "adopt"
|
||||
|
||||
- uses: gradle/actions/setup-gradle@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
|
||||
- uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0
|
||||
|
||||
- name: Run Gradle Command
|
||||
run: ./gradlew clean generateLicenseReport
|
||||
- name: check the licenses for compatibility
|
||||
run: ./gradlew clean checkLicense
|
||||
|
||||
- name: FAILED - check the licenses for compatibility
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
name: dependencies-without-allowed-license.json
|
||||
path: |
|
||||
build/reports/dependency-license/dependencies-without-allowed-license.json
|
||||
retention-days: 3
|
||||
|
||||
- name: Move and Rename License File
|
||||
run: |
|
||||
|
||||
2
.github/workflows/manage-label.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Run Labeler
|
||||
uses: crazy-max/ghaction-github-labeler@b54af0c25861143e7c8813d7cbbf46d2c341680c # v5.1.0
|
||||
uses: crazy-max/ghaction-github-labeler@31674a3852a9074f2086abcf1c53839d466a47e7 # v5.2.0
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
yaml-file: .github/labels.yml
|
||||
|
||||
8
.github/workflows/multiOSReleases.yml
vendored
@@ -58,12 +58,12 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
||||
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||
with:
|
||||
java-version: "21"
|
||||
distribution: "temurin"
|
||||
|
||||
- uses: gradle/actions/setup-gradle@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
|
||||
- uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0
|
||||
with:
|
||||
gradle-version: 8.12
|
||||
|
||||
@@ -146,12 +146,12 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
||||
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||
with:
|
||||
java-version: "21"
|
||||
distribution: "temurin"
|
||||
|
||||
- uses: gradle/actions/setup-gradle@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
|
||||
- uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0
|
||||
with:
|
||||
gradle-version: 8.12
|
||||
|
||||
|
||||
4
.github/workflows/pre_commit.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
|
||||
- name: Generate GitHub App Token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
|
||||
uses: actions/create-github-app-token@136412a57a7081aa63c935a2cc2918f76c34f514 # v1.11.2
|
||||
with:
|
||||
app-id: ${{ secrets.GH_APP_ID }}
|
||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
||||
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
|
||||
with:
|
||||
python-version: 3.12
|
||||
cache: 'pip' # caching pip dependencies
|
||||
|
||||
4
.github/workflows/push-docker.yml
vendored
@@ -25,12 +25,12 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
||||
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||
with:
|
||||
java-version: "17"
|
||||
distribution: "temurin"
|
||||
|
||||
- uses: gradle/actions/setup-gradle@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
|
||||
- uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0
|
||||
with:
|
||||
gradle-version: 8.12
|
||||
|
||||
|
||||
4
.github/workflows/releaseArtifacts.yml
vendored
@@ -30,12 +30,12 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
||||
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||
with:
|
||||
java-version: "17"
|
||||
distribution: "temurin"
|
||||
|
||||
- uses: gradle/actions/setup-gradle@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
|
||||
- uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0
|
||||
with:
|
||||
gradle-version: 8.12
|
||||
|
||||
|
||||
2
.github/workflows/scorecards.yml
vendored
@@ -74,6 +74,6 @@ jobs:
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@17a820bf2e43b47be2c72b39cc905417bc1ab6d0 # v3.28.6
|
||||
uses: github/codeql-action/upload-sarif@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
64
.github/workflows/sonarqube.yml
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
pull-requests: read
|
||||
actions: read
|
||||
name: Run Sonarqube
|
||||
jobs:
|
||||
sonarqube:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
|
||||
- name: Build and analyze with Gradle
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
DOCKER_ENABLE_SECURITY: true
|
||||
STIRLING_PDF_DESKTOP_UI: true
|
||||
run: |
|
||||
./gradlew clean build sonar \
|
||||
-Dsonar.projectKey=Stirling-Tools_Stirling-PDF \
|
||||
-Dsonar.organization=stirling-tools \
|
||||
-Dsonar.host.url=https://sonarcloud.io \
|
||||
-Dsonar.log.level=DEBUG \
|
||||
--info
|
||||
|
||||
- name: Upload Problems Report on Failure
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: gradle-problems-report
|
||||
path: build/reports/problems/problems-report.html
|
||||
retention-days: 7
|
||||
|
||||
- name: Upload Sonar Logs on Failure
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: sonar-logs
|
||||
path: |
|
||||
.scannerwork/report-task.txt
|
||||
build/sonar/
|
||||
retention-days: 7
|
||||
4
.github/workflows/swagger.yml
vendored
@@ -21,12 +21,12 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
||||
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||
with:
|
||||
java-version: "17"
|
||||
distribution: "temurin"
|
||||
|
||||
- uses: gradle/actions/setup-gradle@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
|
||||
- uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0
|
||||
|
||||
- name: Generate Swagger documentation
|
||||
run: ./gradlew generateOpenApiDocs
|
||||
|
||||
35
.github/workflows/sync_files.yml
vendored
@@ -8,8 +8,6 @@ on:
|
||||
paths:
|
||||
- "build.gradle"
|
||||
- "README.md"
|
||||
- "gradle/verification-keyring.keys"
|
||||
- "gradle/verification-metadata.xml"
|
||||
- "src/main/resources/messages_*.properties"
|
||||
- "src/main/resources/static/3rdPartyLicenses.json"
|
||||
- "scripts/ignore_translation.toml"
|
||||
@@ -32,7 +30,7 @@ jobs:
|
||||
|
||||
- name: Generate GitHub App Token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
|
||||
uses: actions/create-github-app-token@136412a57a7081aa63c935a2cc2918f76c34f514 # v1.11.2
|
||||
with:
|
||||
app-id: ${{ secrets.GH_APP_ID }}
|
||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
@@ -65,7 +63,7 @@ jobs:
|
||||
|
||||
- name: Generate GitHub App Token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
|
||||
uses: actions/create-github-app-token@136412a57a7081aa63c935a2cc2918f76c34f514 # v1.11.2
|
||||
with:
|
||||
app-id: ${{ vars.GH_APP_ID }}
|
||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
@@ -73,7 +71,7 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
||||
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
cache: 'pip' # caching pip dependencies
|
||||
@@ -104,22 +102,6 @@ jobs:
|
||||
git add README.md
|
||||
git diff --staged --quiet || git commit -m ":memo: Sync README.md" || echo "no changes"
|
||||
|
||||
- name: Generate verification metadata with signatures and checksums
|
||||
run: |
|
||||
set -e
|
||||
if [ -f ./gradle/verification-metadata.xml ]; then
|
||||
rm ./gradle/verification-metadata.xml
|
||||
fi
|
||||
./gradlew clean dependencies buildEnvironment spotlessApply --write-verification-metadata sha256 help
|
||||
./gradlew clean dependencies buildEnvironment spotlessApply --write-verification-metadata sha256,pgp --refresh-keys --export-keys --refresh-dependencies help
|
||||
./gradlew clean build
|
||||
|
||||
- name: Run git add
|
||||
run: |
|
||||
git add gradle/verification-keyring.keys
|
||||
git add gradle/verification-metadata.xml
|
||||
git diff --staged --quiet || git commit -m ":memo: Generate verification metadata with signatures and checksums" || echo "no changes"
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # v7.0.6
|
||||
with:
|
||||
@@ -129,11 +111,11 @@ jobs:
|
||||
author: ${{ needs.read_bot_entries.outputs.committer }}
|
||||
signoff: true
|
||||
branch: sync_readme
|
||||
title: ":globe_with_meridians: Sync Translations + Update README Progress Table + Update Verification Metadata"
|
||||
title: ":globe_with_meridians: Sync Translations + Update README Progress Table"
|
||||
body: |
|
||||
### Description of Changes
|
||||
|
||||
This Pull Request was automatically generated to synchronize updates to translation files, verification metadata, and documentation. Below are the details of the changes made:
|
||||
This Pull Request was automatically generated to synchronize updates to translation files and documentation. Below are the details of the changes made:
|
||||
|
||||
#### **1. Synchronization of Translation Files**
|
||||
- Updated translation files (`messages_*.properties`) to reflect changes in the reference file `messages_en_GB.properties`.
|
||||
@@ -145,14 +127,9 @@ jobs:
|
||||
- Added a summary of the current translation status for all supported languages.
|
||||
- Included up-to-date statistics on translation coverage.
|
||||
|
||||
#### **3. Verification Metadata Updates**
|
||||
- Generated or refreshed the `verification-keyring.keys` and `verification-metadata.xml` files.
|
||||
- Included the latest dependency signatures and checksums to enhance the build's integrity.
|
||||
|
||||
#### **Why these changes are necessary**
|
||||
- Keeps translation files aligned with the latest reference updates.
|
||||
- Ensures the documentation reflects the current translation progress.
|
||||
- Strengthens dependency verification for a more secure build process.
|
||||
|
||||
---
|
||||
|
||||
@@ -166,5 +143,3 @@ jobs:
|
||||
add-paths: |
|
||||
README.md
|
||||
src/main/resources/messages_*.properties
|
||||
gradle/verification-keyring.keys
|
||||
gradle/verification-metadata.xml
|
||||
|
||||
2
.github/workflows/testdriver.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
||||
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
|
||||
@@ -585,41 +585,3 @@ In your Thymeleaf templates, use the `#{key}` syntax to reference the new transl
|
||||
```
|
||||
|
||||
Remember, never hard-code text in your templates or Java code. Always use translation keys to ensure proper localization.
|
||||
|
||||
|
||||
## Managing Dependencies
|
||||
|
||||
When adding new dependencies or updating existing ones in Stirling-PDF, follow these steps to ensure proper verification and security:
|
||||
|
||||
1. Update the dependency in `build.gradle`:
|
||||
```groovy
|
||||
dependencies {
|
||||
// Add or update your dependency
|
||||
implementation "com.example:new-library:1.2.3"
|
||||
}
|
||||
```
|
||||
|
||||
2. Generate new verification metadata and keys:
|
||||
```bash
|
||||
# Generate verification metadata with signatures and checksums
|
||||
./gradlew clean dependencies buildEnvironment spotlessApply --write-verification-metadata sha256,pgp
|
||||
|
||||
# Export the .keys file
|
||||
./gradlew --export-keys
|
||||
```
|
||||
|
||||
3. Files to commit:
|
||||
- `build.gradle` - Your dependency changes
|
||||
- `gradle/verification-metadata.xml` - Contains verification rules and checksums
|
||||
- `gradle/verification-keyring.keys` - Contains PGP keys in text format
|
||||
|
||||
4. Verify the build works with the new verification:
|
||||
```bash
|
||||
./gradlew build
|
||||
```
|
||||
|
||||
5. Before committing, check:
|
||||
- Verify any new BOM files are properly handled in verification metadata
|
||||
- Review the changes in `verification-metadata.xml` to ensure they match your dependency updates
|
||||
|
||||
This ensures dependencies are properly verified and secure while maintaining transparency in the repository.
|
||||
|
||||
@@ -56,13 +56,15 @@ RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /et
|
||||
openssl-dev \
|
||||
openjdk21-jre \
|
||||
# Doc conversion
|
||||
gcompat \
|
||||
libc6-compat \
|
||||
libreoffice \
|
||||
# pdftohtml
|
||||
poppler-utils \
|
||||
# OCR MY PDF (unpaper for descew and other advanced features)
|
||||
tesseract-ocr-data-eng \
|
||||
# CV
|
||||
py3-opencv \
|
||||
py3-opencv \
|
||||
# python3/pip
|
||||
python3 \
|
||||
py3-pip && \
|
||||
|
||||
@@ -57,6 +57,8 @@ RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /et
|
||||
openssl-dev \
|
||||
openjdk21-jre \
|
||||
# Doc conversion
|
||||
gcompat \
|
||||
libc6-compat \
|
||||
libreoffice \
|
||||
# pdftohtml
|
||||
poppler-utils \
|
||||
@@ -65,7 +67,7 @@ RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /et
|
||||
tesseract-ocr-data-eng \
|
||||
font-terminus font-dejavu font-noto font-noto-cjk font-awesome font-noto-extra \
|
||||
# CV
|
||||
py3-opencv \
|
||||
py3-opencv \
|
||||
# python3/pip
|
||||
python3 \
|
||||
py3-pip && \
|
||||
|
||||
@@ -18,9 +18,7 @@ Any SVG flags are fine; most of the current ones were sourced from [here](https:
|
||||
For example, to add Polish, you would add:
|
||||
|
||||
```html
|
||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="pl_PL">
|
||||
<img src="images/flags/pl.svg" alt="icon" width="20" height="15"> Polski
|
||||
</a>
|
||||
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'pl_PL')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="pl_PL"> <img th:src="@{'/images/flags/pl.svg'}" alt="icon" width="20" height="15"> Polski</a>
|
||||
```
|
||||
|
||||
The `data-bs-language-code` is the code used to reference the file in the next step.
|
||||
|
||||
@@ -117,7 +117,7 @@ Stirling-PDF currently supports 39 languages!
|
||||
|
||||
| Language | Progress |
|
||||
| -------------------------------------------- | -------------------------------------- |
|
||||
| Arabic (العربية) (ar_AR) |  |
|
||||
| Arabic (العربية) (ar_AR) |  |
|
||||
| Azerbaijani (Azərbaycan Dili) (az_AZ) |  |
|
||||
| Basque (Euskara) (eu_ES) |  |
|
||||
| Bulgarian (Български) (bg_BG) |  |
|
||||
@@ -133,7 +133,7 @@ Stirling-PDF currently supports 39 languages!
|
||||
| Greek (Ελληνικά) (el_GR) |  |
|
||||
| Hindi (हिंदी) (hi_IN) |  |
|
||||
| Hungarian (Magyar) (hu_HU) |  |
|
||||
| Indonesian (Bahasa Indonesia) (id_ID) |  |
|
||||
| Indonesian (Bahasa Indonesia) (id_ID) |  |
|
||||
| Irish (Gaeilge) (ga_IE) |  |
|
||||
| Italian (Italiano) (it_IT) |  |
|
||||
| Japanese (日本語) (ja_JP) |  |
|
||||
@@ -142,7 +142,7 @@ Stirling-PDF currently supports 39 languages!
|
||||
| Persian (فارسی) (fa_IR) |  |
|
||||
| Polish (Polski) (pl_PL) |  |
|
||||
| Portuguese (Português) (pt_PT) |  |
|
||||
| Portuguese Brazilian (Português) (pt_BR) |  |
|
||||
| Portuguese Brazilian (Português) (pt_BR) |  |
|
||||
| Romanian (Română) (ro_RO) |  |
|
||||
| Russian (Русский) (ru_RU) |  |
|
||||
| Serbian Latin alphabet (Srpski) (sr_LATN_RS) |  |
|
||||
@@ -155,7 +155,7 @@ Stirling-PDF currently supports 39 languages!
|
||||
| Tibetan (བོད་ཡིག་) (zh_BO) |  |
|
||||
| Traditional Chinese (繁體中文) (zh_TW) |  |
|
||||
| Turkish (Türkçe) (tr_TR) |  |
|
||||
| Ukrainian (Українська) (uk_UA) |  |
|
||||
| Ukrainian (Українська) (uk_UA) |  |
|
||||
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
||||
|
||||
|
||||
|
||||
164
allowed-licenses.json
Normal file
@@ -0,0 +1,164 @@
|
||||
{
|
||||
"allowedLicenses": [
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "BSD License"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "The BSD License"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "BSD 2-Clause License"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "The 2-Clause BSD License"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "BSD-3-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "The BSD 3-Clause License (BSD3)"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "BSD-4 License"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "MIT"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "MIT License"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "The MIT License"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.github.jai-imageio:jai-imageio-core",
|
||||
"moduleLicense": "LICENSE.txt"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.github.jai-imageio:jai-imageio-jpeg2000",
|
||||
"moduleLicense": "LICENSE-JJ2000.txt, LICENSE-Sun.txt"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "Apache 2"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "Apache 2.0"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "Apache-2.0"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "Apache-2.0 License"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "Apache License 2.0"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "Apache License Version 2.0"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "Apache License, Version 2.0"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "The Apache License, Version 2.0"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "The Apache Software License, Version 2.0"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.nimbusds:oauth2-oidc-sdk",
|
||||
"moduleLicense": "\"Apache License, version 2.0\";link=\"https://www.apache.org/licenses/LICENSE-2.0.html\""
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "MPL 2.0"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "UnboundID SCIM2 SDK Free Use License"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "GPL2 w/ CPE"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "GPLv2+CE"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "GNU GENERAL PUBLIC LICENSE, Version 2 + Classpath Exception"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.martiansoftware:jsap",
|
||||
"moduleLicense": "LGPL"
|
||||
},
|
||||
{
|
||||
"moduleName": "org.hibernate.orm:hibernate-core",
|
||||
"moduleLicense": "GNU Library General Public License v2.1 or later"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "Eclipse Public License - v 1.0"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "Eclipse Public License v. 2.0"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "Eclipse Public License - v 2.0"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "Eclipse Public License - Version 2.0"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "Eclipse Public License, Version 2.0"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "Ubuntu Font Licence 1.0"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "Bouncy Castle Licence"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "Public Domain, per Creative Commons CC0"
|
||||
},
|
||||
{
|
||||
"moduleName": ".*",
|
||||
"moduleLicense": "The W3C License"
|
||||
}
|
||||
]
|
||||
}
|
||||
20
build.gradle
@@ -8,7 +8,8 @@ plugins {
|
||||
id "com.diffplug.spotless" version "7.0.2"
|
||||
id "com.github.jk1.dependency-license-report" version "2.9"
|
||||
//id "nebula.lint" version "19.0.3"
|
||||
id("org.panteleyev.jpackageplugin") version "1.6.0"
|
||||
id("org.panteleyev.jpackageplugin") version "1.6.1"
|
||||
id "org.sonarqube" version "6.0.1.5171"
|
||||
}
|
||||
|
||||
import com.github.jk1.license.render.*
|
||||
@@ -25,7 +26,7 @@ ext {
|
||||
}
|
||||
|
||||
group = "stirling.software"
|
||||
version = "0.40.1"
|
||||
version = "0.41.0"
|
||||
|
||||
java {
|
||||
// 17 is lowest but we support and recommend 21
|
||||
@@ -34,13 +35,13 @@ java {
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url = "https://jitpack.io" }
|
||||
maven { url = "https://build.shibboleth.net/maven/releases" }
|
||||
maven { url = "https://maven.pkg.github.com/jcefmaven/jcefmaven" }
|
||||
}
|
||||
|
||||
licenseReport {
|
||||
renderers = [new JsonReportRenderer()]
|
||||
allowedLicensesFile = new File("$projectDir/allowed-licenses.json")
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
@@ -268,6 +269,17 @@ spotless {
|
||||
}
|
||||
}
|
||||
|
||||
sonar {
|
||||
properties {
|
||||
property "sonar.projectKey", "Stirling-Tools_Stirling-PDF"
|
||||
property "sonar.organization", "stirling-tools"
|
||||
|
||||
property "sonar.exclusions", "**/build-wrapper-dump.json, src/main/java/org/apache/**, src/main/resources/static/pdfjs/**, src/main/resources/static/pdfjs-legacy/**, src/main/resources/static/js/thirdParty/**"
|
||||
property "sonar.coverage.exclusions", "src/main/java/org/apache/**, src/main/resources/static/pdfjs/**, src/main/resources/static/pdfjs-legacy/**, src/main/resources/static/js/thirdParty/**"
|
||||
property "sonar.cpd.exclusions", "src/main/java/org/apache/**, src/main/resources/static/pdfjs/**, src/main/resources/static/pdfjs-legacy/**, src/main/resources/static/js/thirdParty/**"
|
||||
}
|
||||
}
|
||||
|
||||
//gradleLint {
|
||||
// rules=['unused-dependency']
|
||||
// }
|
||||
@@ -366,7 +378,7 @@ dependencies {
|
||||
exclude group: "commons-logging", module: "commons-logging"
|
||||
}
|
||||
implementation "org.apache.pdfbox:preflight:$pdfboxVersion"
|
||||
|
||||
|
||||
|
||||
implementation ("org.apache.pdfbox:xmpbox:$pdfboxVersion") {
|
||||
exclude group: "commons-logging", module: "commons-logging"
|
||||
|
||||
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 242 KiB After Width: | Height: | Size: 169 KiB |
|
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 118 KiB |
@@ -4,6 +4,7 @@ import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -74,6 +75,11 @@ public class AppConfig {
|
||||
: "null";
|
||||
}
|
||||
|
||||
@Bean(name = "languages")
|
||||
public List<String> languages() {
|
||||
return applicationProperties.getUi().getLanguages();
|
||||
}
|
||||
|
||||
@Bean(name = "navBarText")
|
||||
public String navBarText() {
|
||||
String defaultNavBar =
|
||||
|
||||
@@ -265,9 +265,6 @@ public class EndpointConfiguration {
|
||||
// Pdftohtml dependent endpoints
|
||||
addEndpointToGroup("Pdftohtml", "pdf-to-html");
|
||||
addEndpointToGroup("Pdftohtml", "pdf-to-markdown");
|
||||
|
||||
// disabled for now while we resolve issues
|
||||
disableEndpoint("pdf-to-pdfa");
|
||||
}
|
||||
|
||||
private void processEnvironmentConfigs() {
|
||||
|
||||
@@ -2,7 +2,9 @@ package stirling.software.SPDF.controller.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -26,11 +28,14 @@ public class AdditionalLanguageJsController {
|
||||
@Hidden
|
||||
@GetMapping(value = "/additionalLanguageCode.js", produces = "application/javascript")
|
||||
public void generateAdditionalLanguageJs(HttpServletResponse response) throws IOException {
|
||||
List<String> supportedLanguages = languageService.getSupportedLanguages();
|
||||
Set<String> supportedLanguages = languageService.getSupportedLanguages();
|
||||
response.setContentType("application/javascript");
|
||||
PrintWriter writer = response.getWriter();
|
||||
// Erstelle das JavaScript dynamisch
|
||||
writer.println("const supportedLanguages = " + toJsonArray(supportedLanguages) + ";");
|
||||
writer.println(
|
||||
"const supportedLanguages = "
|
||||
+ toJsonArray(new ArrayList<>(supportedLanguages))
|
||||
+ ";");
|
||||
// Generiere die `getDetailedLanguageCode`-Funktion
|
||||
writer.println(
|
||||
"""
|
||||
|
||||
@@ -100,6 +100,8 @@ public class SplitPdfBySectionsController {
|
||||
|
||||
if (sectionNum == horiz * verti) pageNum++;
|
||||
}
|
||||
|
||||
zipOut.finish();
|
||||
data = Files.readAllBytes(zipFile);
|
||||
return WebResponseUtils.bytesToWebResponse(
|
||||
data, filename + "_split.zip", MediaType.APPLICATION_OCTET_STREAM);
|
||||
|
||||
@@ -13,8 +13,8 @@ import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import stirling.software.SPDF.model.api.converters.HTMLToPdfRequest;
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
import stirling.software.SPDF.model.api.converters.HTMLToPdfRequest;
|
||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.FileToPdf;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@@ -28,23 +28,23 @@ public class ConvertHtmlToPDF {
|
||||
|
||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||
|
||||
private final ApplicationProperties applicationProperties;
|
||||
private final ApplicationProperties applicationProperties;
|
||||
|
||||
@Autowired
|
||||
public ConvertHtmlToPDF(
|
||||
CustomPDDocumentFactory pdfDocumentFactory,
|
||||
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled,
|
||||
ApplicationProperties applicationProperties) {
|
||||
ApplicationProperties applicationProperties) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
|
||||
this.applicationProperties = applicationProperties;
|
||||
this.applicationProperties = applicationProperties;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/html/pdf")
|
||||
@Operation(
|
||||
summary = "Convert an HTML or ZIP (containing HTML and CSS) to PDF",
|
||||
description =
|
||||
"This endpoint takes an HTML or ZIP file input and converts it to a PDF format.")
|
||||
"This endpoint takes an HTML or ZIP file input and converts it to a PDF format. Input:HTML Output:PDF Type:SISO")
|
||||
public ResponseEntity<byte[]> HtmlToPdf(@ModelAttribute HTMLToPdfRequest request)
|
||||
throws Exception {
|
||||
MultipartFile fileInput = request.getFileInput();
|
||||
@@ -60,7 +60,8 @@ public class ConvertHtmlToPDF {
|
||||
throw new IllegalArgumentException("File must be either .html or .zip format.");
|
||||
}
|
||||
|
||||
boolean disableSanitize = Boolean.TRUE.equals(applicationProperties.getSystem().getDisableSanitize());
|
||||
boolean disableSanitize =
|
||||
Boolean.TRUE.equals(applicationProperties.getSystem().getDisableSanitize());
|
||||
|
||||
byte[] pdfBytes =
|
||||
FileToPdf.convertHtmlToPdf(
|
||||
@@ -68,7 +69,7 @@ public class ConvertHtmlToPDF {
|
||||
fileInput.getBytes(),
|
||||
originalFilename,
|
||||
bookAndHtmlFormatsInstalled,
|
||||
disableSanitize);
|
||||
disableSanitize);
|
||||
|
||||
pdfBytes = pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes);
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@ import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import stirling.software.SPDF.model.api.GeneralFile;
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
import stirling.software.SPDF.model.api.GeneralFile;
|
||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.FileToPdf;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@@ -38,16 +38,16 @@ public class ConvertMarkdownToPdf {
|
||||
|
||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||
|
||||
private final ApplicationProperties applicationProperties;
|
||||
private final ApplicationProperties applicationProperties;
|
||||
|
||||
@Autowired
|
||||
public ConvertMarkdownToPdf(
|
||||
CustomPDDocumentFactory pdfDocumentFactory,
|
||||
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled,
|
||||
ApplicationProperties applicationProperties) {
|
||||
ApplicationProperties applicationProperties) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
|
||||
this.applicationProperties = applicationProperties;
|
||||
this.applicationProperties = applicationProperties;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/markdown/pdf")
|
||||
@@ -81,7 +81,8 @@ public class ConvertMarkdownToPdf {
|
||||
|
||||
String htmlContent = renderer.render(document);
|
||||
|
||||
boolean disableSanitize = Boolean.TRUE.equals(applicationProperties.getSystem().getDisableSanitize());
|
||||
boolean disableSanitize =
|
||||
Boolean.TRUE.equals(applicationProperties.getSystem().getDisableSanitize());
|
||||
|
||||
byte[] pdfBytes =
|
||||
FileToPdf.convertHtmlToPdf(
|
||||
@@ -89,7 +90,7 @@ public class ConvertMarkdownToPdf {
|
||||
htmlContent.getBytes(),
|
||||
"converted.html",
|
||||
bookAndHtmlFormatsInstalled,
|
||||
disableSanitize);
|
||||
disableSanitize);
|
||||
pdfBytes = pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes);
|
||||
String outputFilename =
|
||||
originalFilename.replaceFirst("[.][^.]+$", "")
|
||||
|
||||
@@ -73,8 +73,8 @@ public class ConvertPDFToPDFA {
|
||||
// Determine PDF/A filter based on requested format
|
||||
String pdfFilter =
|
||||
"pdfa".equals(outputFormat)
|
||||
? "writer_pdf_Export:{'SelectPdfVersion':{'Value':'2'}}:writer_pdf_Export"
|
||||
: "writer_pdf_Export:{'SelectPdfVersion':{'Value':'1'}}:writer_pdf_Export";
|
||||
? "pdf:writer_pdf_Export:{\"SelectPdfVersion\":{\"type\":\"long\",\"value\":\"2\"}}"
|
||||
: "pdf:writer_pdf_Export:{\"SelectPdfVersion\":{\"type\":\"long\",\"value\":\"1\"}}";
|
||||
|
||||
// Prepare LibreOffice command
|
||||
List<String> command =
|
||||
@@ -84,7 +84,7 @@ public class ConvertPDFToPDFA {
|
||||
"--headless",
|
||||
"--nologo",
|
||||
"--convert-to",
|
||||
"pdf:" + pdfFilter,
|
||||
pdfFilter,
|
||||
"--outdir",
|
||||
tempOutputDir.toString(),
|
||||
tempInputFile.toString()));
|
||||
|
||||
@@ -8,7 +8,9 @@ import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
@@ -41,8 +43,12 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||
public class AutoSplitPdfController {
|
||||
|
||||
private static final String QR_CONTENT = "https://github.com/Stirling-Tools/Stirling-PDF";
|
||||
private static final String QR_CONTENT_OLD = "https://github.com/Frooodle/Stirling-PDF";
|
||||
private static final Set<String> VALID_QR_CONTENTS =
|
||||
new HashSet<>(
|
||||
Set.of(
|
||||
"https://github.com/Stirling-Tools/Stirling-PDF",
|
||||
"https://github.com/Frooodle/Stirling-PDF",
|
||||
"https://stirlingpdf.com"));
|
||||
|
||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@@ -120,13 +126,14 @@ public class AutoSplitPdfController {
|
||||
for (int page = 0; page < document.getNumberOfPages(); ++page) {
|
||||
BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 150);
|
||||
String result = decodeQRCode(bim);
|
||||
if ((QR_CONTENT.equals(result) || QR_CONTENT_OLD.equals(result)) && page != 0) {
|
||||
|
||||
boolean isValidQrCode = VALID_QR_CONTENTS.contains(result);
|
||||
log.debug("detected qr code {}, code is vale={}", result, isValidQrCode);
|
||||
if (isValidQrCode && page != 0) {
|
||||
splitDocuments.add(new PDDocument());
|
||||
}
|
||||
|
||||
if (!splitDocuments.isEmpty()
|
||||
&& !QR_CONTENT.equals(result)
|
||||
&& !QR_CONTENT_OLD.equals(result)) {
|
||||
if (!splitDocuments.isEmpty() && !isValidQrCode) {
|
||||
splitDocuments.get(splitDocuments.size() - 1).addPage(document.getPage(page));
|
||||
} else if (page == 0) {
|
||||
PDDocument firstDocument = new PDDocument();
|
||||
@@ -135,7 +142,7 @@ public class AutoSplitPdfController {
|
||||
}
|
||||
|
||||
// If duplexMode is true and current page is a divider, then skip next page
|
||||
if (duplexMode && (QR_CONTENT.equals(result) || QR_CONTENT_OLD.equals(result))) {
|
||||
if (duplexMode && isValidQrCode) {
|
||||
page++;
|
||||
}
|
||||
}
|
||||
@@ -168,6 +175,9 @@ public class AutoSplitPdfController {
|
||||
|
||||
return WebResponseUtils.bytesToWebResponse(
|
||||
data, filename + ".zip", MediaType.APPLICATION_OCTET_STREAM);
|
||||
} catch (Exception e) {
|
||||
log.error("Error in auto split", e);
|
||||
throw e;
|
||||
} finally {
|
||||
// Clean up resources
|
||||
if (document != null) {
|
||||
|
||||
@@ -52,7 +52,7 @@ public class ExtractImagesController {
|
||||
@Operation(
|
||||
summary = "Extract images from a PDF file",
|
||||
description =
|
||||
"This endpoint extracts images from a given PDF file and returns them in a zip file. Users can specify the output image format. Input: PDF Output: IMAGE/ZIP Type: SIMO")
|
||||
"This endpoint extracts images from a given PDF file and returns them in a zip file. Users can specify the output image format. Input:PDF Output:IMAGE/ZIP Type:SIMO")
|
||||
public ResponseEntity<byte[]> extractImages(@ModelAttribute PDFExtractImagesRequest request)
|
||||
throws IOException, InterruptedException, ExecutionException {
|
||||
MultipartFile file = request.getFileInput();
|
||||
|
||||
@@ -46,7 +46,7 @@ public class FlattenController {
|
||||
@Operation(
|
||||
summary = "Flatten PDF form fields or full page",
|
||||
description =
|
||||
"Flattening just PDF form fields or converting each page to images to make text unselectable. Input: PDF, Output: PDF. Type: SISO")
|
||||
"Flattening just PDF form fields or converting each page to images to make text unselectable. Input:PDF, Output:PDF. Type:SISO")
|
||||
public ResponseEntity<byte[]> flatten(@ModelAttribute FlattenRequest request) throws Exception {
|
||||
MultipartFile file = request.getFileInput();
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.BoundedLineReader;
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -65,6 +66,10 @@ public class OCRController {
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/ocr-pdf")
|
||||
@Operation(
|
||||
summary = "Process PDF files with OCR using Tesseract",
|
||||
description =
|
||||
"Takes a PDF file as input, performs OCR using specified languages and OCR type (skip-text/force-ocr), and returns the processed PDF. Input:PDF Output:PDF Type:SISO")
|
||||
public ResponseEntity<byte[]> processPdfWithOCR(
|
||||
@ModelAttribute ProcessPdfWithOcrRequest request)
|
||||
throws IOException, InterruptedException {
|
||||
|
||||
@@ -25,6 +25,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import stirling.software.SPDF.model.PipelineConfig;
|
||||
import stirling.software.SPDF.model.PipelineResult;
|
||||
import stirling.software.SPDF.model.api.HandleDataRequest;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@@ -58,7 +59,8 @@ public class PipelineController {
|
||||
if (inputFiles == null || inputFiles.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
List<Resource> outputFiles = processor.runPipelineAgainstFiles(inputFiles, config);
|
||||
PipelineResult result = processor.runPipelineAgainstFiles(inputFiles, config);
|
||||
List<Resource> outputFiles = result.getOutputFiles();
|
||||
if (outputFiles != null && outputFiles.size() == 1) {
|
||||
// If there is only one file, return it directly
|
||||
Resource singleFile = outputFiles.get(0);
|
||||
|
||||
@@ -27,6 +27,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import stirling.software.SPDF.config.InstallationPathConfig;
|
||||
import stirling.software.SPDF.model.PipelineConfig;
|
||||
import stirling.software.SPDF.model.PipelineOperation;
|
||||
import stirling.software.SPDF.model.PipelineResult;
|
||||
import stirling.software.SPDF.utils.FileMonitor;
|
||||
|
||||
@Service
|
||||
@@ -143,19 +144,64 @@ public class PipelineDirectoryProcessor {
|
||||
|
||||
private File[] collectFilesForProcessing(Path dir, Path jsonFile, PipelineOperation operation)
|
||||
throws IOException {
|
||||
|
||||
List<String> inputExtensions =
|
||||
apiDocService.getExtensionTypes(false, operation.getOperation());
|
||||
log.info(
|
||||
"Allowed extensions for operation {}: {}",
|
||||
operation.getOperation(),
|
||||
inputExtensions);
|
||||
|
||||
boolean allowAllFiles = inputExtensions.contains("ALL");
|
||||
|
||||
try (Stream<Path> paths = Files.list(dir)) {
|
||||
if ("automated".equals(operation.getParameters().get("fileInput"))) {
|
||||
return paths.filter(
|
||||
path ->
|
||||
!Files.isDirectory(path)
|
||||
&& !path.equals(jsonFile)
|
||||
&& fileMonitor.isFileReadyForProcessing(path))
|
||||
.map(Path::toFile)
|
||||
.toArray(File[]::new);
|
||||
} else {
|
||||
String fileInput = (String) operation.getParameters().get("fileInput");
|
||||
return new File[] {new File(fileInput)};
|
||||
}
|
||||
File[] files =
|
||||
paths.filter(
|
||||
path -> {
|
||||
if (Files.isDirectory(path)) {
|
||||
return false;
|
||||
}
|
||||
if (path.equals(jsonFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get file extension
|
||||
String filename = path.getFileName().toString();
|
||||
String extension =
|
||||
filename.contains(".")
|
||||
? filename.substring(
|
||||
filename.lastIndexOf(".")
|
||||
+ 1)
|
||||
.toLowerCase()
|
||||
: "";
|
||||
|
||||
// Check against allowed extensions
|
||||
boolean isAllowed =
|
||||
allowAllFiles
|
||||
|| inputExtensions.contains(extension);
|
||||
if (!isAllowed) {
|
||||
log.info(
|
||||
"Skipping file with unsupported extension: {} ({})",
|
||||
filename,
|
||||
extension);
|
||||
}
|
||||
return isAllowed;
|
||||
})
|
||||
.filter(
|
||||
path -> {
|
||||
boolean isReady =
|
||||
fileMonitor.isFileReadyForProcessing(path);
|
||||
if (!isReady) {
|
||||
log.info(
|
||||
"File not ready for processing (locked/created last 5s): {}",
|
||||
path);
|
||||
}
|
||||
return isReady;
|
||||
})
|
||||
.map(Path::toFile)
|
||||
.toArray(File[]::new);
|
||||
log.info("Collected {} files for processing", files.length);
|
||||
return files;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,19 +244,37 @@ public class PipelineDirectoryProcessor {
|
||||
try {
|
||||
List<Resource> inputFiles =
|
||||
processor.generateInputFiles(filesToProcess.toArray(new File[0]));
|
||||
if (inputFiles == null || inputFiles.size() == 0) {
|
||||
if (inputFiles == null || inputFiles.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<Resource> outputFiles = processor.runPipelineAgainstFiles(inputFiles, config);
|
||||
if (outputFiles == null) return;
|
||||
moveAndRenameFiles(outputFiles, config, dir);
|
||||
deleteOriginalFiles(filesToProcess, processingDir);
|
||||
PipelineResult result = processor.runPipelineAgainstFiles(inputFiles, config);
|
||||
|
||||
if (result.isHasErrors()) {
|
||||
log.error("Errors occurred during processing, retaining original files");
|
||||
moveToErrorDirectory(filesToProcess, dir);
|
||||
} else {
|
||||
moveAndRenameFiles(result.getOutputFiles(), config, dir);
|
||||
deleteOriginalFiles(filesToProcess, processingDir);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("error during processing", e);
|
||||
log.error("Error during processing", e);
|
||||
moveFilesBack(filesToProcess, processingDir);
|
||||
}
|
||||
}
|
||||
|
||||
private void moveToErrorDirectory(List<File> files, Path originalDir) throws IOException {
|
||||
Path errorDir = originalDir.resolve("error");
|
||||
if (!Files.exists(errorDir)) {
|
||||
Files.createDirectories(errorDir);
|
||||
}
|
||||
|
||||
for (File file : files) {
|
||||
Path target = errorDir.resolve(file.getName());
|
||||
Files.move(file.toPath(), target);
|
||||
log.info("Moved failed file to error directory for investigation: {}", target);
|
||||
}
|
||||
}
|
||||
|
||||
private void moveAndRenameFiles(List<Resource> resources, PipelineConfig config, Path dir)
|
||||
throws IOException {
|
||||
for (Resource resource : resources) {
|
||||
|
||||
@@ -33,6 +33,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import stirling.software.SPDF.SPDFApplication;
|
||||
import stirling.software.SPDF.model.PipelineConfig;
|
||||
import stirling.software.SPDF.model.PipelineOperation;
|
||||
import stirling.software.SPDF.model.PipelineResult;
|
||||
import stirling.software.SPDF.model.Role;
|
||||
|
||||
@Service
|
||||
@@ -84,8 +85,10 @@ public class PipelineProcessor {
|
||||
return "http://localhost:" + port + contextPath + "/";
|
||||
}
|
||||
|
||||
List<Resource> runPipelineAgainstFiles(List<Resource> outputFiles, PipelineConfig config)
|
||||
PipelineResult runPipelineAgainstFiles(List<Resource> outputFiles, PipelineConfig config)
|
||||
throws Exception {
|
||||
PipelineResult result = new PipelineResult();
|
||||
|
||||
ByteArrayOutputStream logStream = new ByteArrayOutputStream();
|
||||
PrintStream logPrintStream = new PrintStream(logStream);
|
||||
boolean hasErrors = false;
|
||||
@@ -130,7 +133,8 @@ public class PipelineProcessor {
|
||||
if (operation.startsWith("filter-")
|
||||
&& (response.getBody() == null
|
||||
|| response.getBody().length == 0)) {
|
||||
log.info("Skipping file due to failing {}", operation);
|
||||
result.setFiltersApplied(true);
|
||||
log.info("Skipping file due to filtering {}", operation);
|
||||
continue;
|
||||
}
|
||||
if (!response.getStatusCode().equals(HttpStatus.OK)) {
|
||||
@@ -208,7 +212,10 @@ public class PipelineProcessor {
|
||||
if (hasErrors) {
|
||||
log.error("Errors occurred during processing. Log: {}", logStream.toString());
|
||||
}
|
||||
return outputFiles;
|
||||
result.setHasErrors(hasErrors);
|
||||
result.setFiltersApplied(hasErrors);
|
||||
result.setOutputFiles(outputFiles);
|
||||
return result;
|
||||
}
|
||||
|
||||
private ResponseEntity<byte[]> sendWebRequest(String url, MultiValueMap<String, Object> body) {
|
||||
|
||||
@@ -40,8 +40,7 @@ public class RemoveCertSignController {
|
||||
@Operation(
|
||||
summary = "Remove digital signature from PDF",
|
||||
description =
|
||||
"This endpoint accepts a PDF file and returns the PDF file without the digital signature."
|
||||
+ " Input: PDF, Output: PDF")
|
||||
"This endpoint accepts a PDF file and returns the PDF file without the digital signature. Input:PDF, Output:PDF Type:SISO")
|
||||
public ResponseEntity<byte[]> removeCertSignPDF(@ModelAttribute PDFFile request)
|
||||
throws Exception {
|
||||
MultipartFile pdf = request.getFileInput();
|
||||
|
||||
@@ -36,8 +36,9 @@ public class DatabaseWebController {
|
||||
}
|
||||
List<FileInfo> backupList = databaseService.getBackupList();
|
||||
model.addAttribute("backupFiles", backupList);
|
||||
model.addAttribute("databaseVersion", databaseService.getH2Version());
|
||||
if ("Unknown".equalsIgnoreCase(databaseService.getH2Version())) {
|
||||
String dbVersion = databaseService.getH2Version();
|
||||
model.addAttribute("databaseVersion", dbVersion);
|
||||
if ("Unknown".equalsIgnoreCase(dbVersion)) {
|
||||
model.addAttribute("infoMessage", "notSupported");
|
||||
}
|
||||
return "database";
|
||||
|
||||
@@ -265,7 +265,8 @@ public class ApplicationProperties {
|
||||
return getKeycloak();
|
||||
default:
|
||||
throw new UnsupportedProviderException(
|
||||
"Logout from the provider is not supported? Report it at https://github.com/Stirling-Tools/Stirling-PDF/issues");
|
||||
"Logout from the provider is not supported? Report it at"
|
||||
+ " https://github.com/Stirling-Tools/Stirling-PDF/issues");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,10 +314,10 @@ public class ApplicationProperties {
|
||||
@Override
|
||||
public String toString() {
|
||||
return """
|
||||
Driver {
|
||||
driverName='%s'
|
||||
}
|
||||
"""
|
||||
Driver {
|
||||
driverName='%s'
|
||||
}
|
||||
"""
|
||||
.formatted(driverName);
|
||||
}
|
||||
}
|
||||
@@ -326,6 +327,7 @@ public class ApplicationProperties {
|
||||
private String appName;
|
||||
private String homeDescription;
|
||||
private String appNameNavbar;
|
||||
private List<String> languages;
|
||||
|
||||
public String getAppName() {
|
||||
return appName != null && appName.trim().length() > 0 ? appName : null;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package stirling.software.SPDF.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class PipelineResult {
|
||||
private List<Resource> outputFiles;
|
||||
private boolean hasErrors;
|
||||
private boolean filtersApplied;
|
||||
}
|
||||
@@ -1,41 +1,56 @@
|
||||
package stirling.software.SPDF.service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class LanguageService {
|
||||
|
||||
private final ApplicationProperties applicationProperties;
|
||||
private final PathMatchingResourcePatternResolver resourcePatternResolver =
|
||||
new PathMatchingResourcePatternResolver();
|
||||
|
||||
public List<String> getSupportedLanguages() {
|
||||
List<String> supportedLanguages = new ArrayList<>();
|
||||
public LanguageService(ApplicationProperties applicationProperties) {
|
||||
this.applicationProperties = applicationProperties;
|
||||
}
|
||||
|
||||
public Set<String> getSupportedLanguages() {
|
||||
try {
|
||||
Resource[] resources =
|
||||
resourcePatternResolver.getResources("classpath*:messages_*.properties");
|
||||
for (Resource resource : resources) {
|
||||
if (resource.exists() && resource.isReadable()) {
|
||||
String filename = resource.getFilename();
|
||||
if (filename != null
|
||||
&& filename.startsWith("messages_")
|
||||
&& filename.endsWith(".properties")) {
|
||||
String languageCode =
|
||||
filename.replace("messages_", "").replace(".properties", "");
|
||||
supportedLanguages.add(languageCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return supportedLanguages;
|
||||
return Arrays.stream(resources)
|
||||
.map(Resource::getFilename)
|
||||
.filter(
|
||||
filename ->
|
||||
filename != null
|
||||
&& filename.startsWith("messages_")
|
||||
&& filename.endsWith(".properties"))
|
||||
.map(filename -> filename.replace("messages_", "").replace(".properties", ""))
|
||||
.filter(
|
||||
languageCode -> {
|
||||
Set<String> allowedLanguages =
|
||||
new HashSet<>(applicationProperties.getUi().getLanguages());
|
||||
return allowedLanguages.isEmpty()
|
||||
|| allowedLanguages.contains(languageCode)
|
||||
|| "en_GB".equals(languageCode);
|
||||
})
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("Error retrieving supported languages", e);
|
||||
return new HashSet<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ public class FileToPdf {
|
||||
byte[] fileBytes,
|
||||
String fileName,
|
||||
boolean htmlFormatsInstalled,
|
||||
boolean disableSanitize)
|
||||
boolean disableSanitize)
|
||||
throws IOException, InterruptedException {
|
||||
|
||||
Path tempOutputFile = Files.createTempFile("output_", ".pdf");
|
||||
@@ -36,7 +36,9 @@ public class FileToPdf {
|
||||
try {
|
||||
if (fileName.endsWith(".html")) {
|
||||
tempInputFile = Files.createTempFile("input_", ".html");
|
||||
String sanitizedHtml = sanitizeHtmlContent(new String(fileBytes, StandardCharsets.UTF_8), disableSanitize);
|
||||
String sanitizedHtml =
|
||||
sanitizeHtmlContent(
|
||||
new String(fileBytes, StandardCharsets.UTF_8), disableSanitize);
|
||||
Files.write(tempInputFile, sanitizedHtml.getBytes(StandardCharsets.UTF_8));
|
||||
} else if (fileName.endsWith(".zip")) {
|
||||
tempInputFile = Files.createTempFile("input_", ".zip");
|
||||
@@ -93,7 +95,8 @@ public class FileToPdf {
|
||||
return (!disableSanitize) ? CustomHtmlSanitizer.sanitize(htmlContent) : htmlContent;
|
||||
}
|
||||
|
||||
private static void sanitizeHtmlFilesInZip(Path zipFilePath, boolean disableSanitize) throws IOException {
|
||||
private static void sanitizeHtmlFilesInZip(Path zipFilePath, boolean disableSanitize)
|
||||
throws IOException {
|
||||
Path tempUnzippedDir = Files.createTempDirectory("unzipped_");
|
||||
try (ZipInputStream zipIn =
|
||||
ZipSecurity.createHardenedInputStream(
|
||||
|
||||
@@ -587,9 +587,7 @@ public class GeneralUtils {
|
||||
for (byte b : hash) {
|
||||
fingerprint.append(String.format("%02x", b));
|
||||
}
|
||||
|
||||
return fingerprint.toString();
|
||||
|
||||
} catch (Exception e) {
|
||||
return "GenericID";
|
||||
}
|
||||
|
||||
@@ -218,6 +218,9 @@ public class ProcessExecutor {
|
||||
errorReaderThread.join();
|
||||
outputReaderThread.join();
|
||||
|
||||
boolean isQpdf =
|
||||
command != null && !command.isEmpty() && command.get(0).contains("qpdf");
|
||||
|
||||
if (outputLines.size() > 0) {
|
||||
String outputMessage = String.join("\n", outputLines);
|
||||
messages += outputMessage;
|
||||
@@ -233,20 +236,28 @@ public class ProcessExecutor {
|
||||
log.warn("Command error output:\n" + errorMessage);
|
||||
}
|
||||
if (exitCode != 0) {
|
||||
throw new IOException(
|
||||
"Command process failed with exit code "
|
||||
+ exitCode
|
||||
+ ". Error message: "
|
||||
+ errorMessage);
|
||||
if (isQpdf && exitCode == 3) {
|
||||
log.warn("qpdf succeeded with warnings: {}", messages);
|
||||
} else {
|
||||
throw new IOException(
|
||||
"Command process failed with exit code "
|
||||
+ exitCode
|
||||
+ ". Error message: "
|
||||
+ errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (exitCode != 0) {
|
||||
throw new IOException(
|
||||
"Command process failed with exit code "
|
||||
+ exitCode
|
||||
+ "\nLogs: "
|
||||
+ messages);
|
||||
if (isQpdf && exitCode == 3) {
|
||||
log.warn("qpdf succeeded with warnings: {}", messages);
|
||||
} else {
|
||||
throw new IOException(
|
||||
"Command process failed with exit code "
|
||||
+ exitCode
|
||||
+ "\nLogs: "
|
||||
+ messages);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
semaphore.release();
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=أداة متعددة PDF
|
||||
home.multiTool.desc=دمج الصفحات وتدويرها وإعادة ترتيبها وإزالتها
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=ارفع ملف PDF الممسوح ضوئيًا الك
|
||||
autoSplitPDF.selectText.4=يتم اكتشاف صفحات الفاصل تلقائيًا وإزالتها، مما يضمن مستندًا نهائيًا نظيفًا.
|
||||
autoSplitPDF.formPrompt=أرسل ملف PDF يحتوي على فواصل صفحات Stirling-PDF:
|
||||
autoSplitPDF.duplexMode=وضع الطباعة على الوجهين (المسح الضوئي للوجه الأمامي والخلفي)
|
||||
autoSplitPDF.dividerDownload1=تنزيل 'فاصل التقسيم التلقائي (الحد الأدنى).pdf'
|
||||
autoSplitPDF.dividerDownload2=تنزيل 'فاصل التقسيم التلقائي (مع التعليمات).pdf'
|
||||
autoSplitPDF.submit=إرسال
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF Multi-alət
|
||||
home.multiTool.desc=Səhifələri Birləşdir, Çevir, Yenidən Sırala, Böl və Sil
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Tək böyük skan edilmiş PDF faylını yükləyin v
|
||||
autoSplitPDF.selectText.4=Ayırıcı səhifələr avtomatik aşkarlanır və silinir, səliqəli yekun sənədə zəmanət verir.
|
||||
autoSplitPDF.formPrompt=Stirling-PDF ə Səhifə bölücüləri olan PDF-i təqdim edin:
|
||||
autoSplitPDF.duplexMode=Dupleks rejimi (Ön və arxa skanlama)
|
||||
autoSplitPDF.dividerDownload1='Auto Splitter Divider (minimal).pdf'-ı yükləyin
|
||||
autoSplitPDF.dividerDownload2='Auto Splitter Divider (with instructions).pdf'-ı yükləyin
|
||||
autoSplitPDF.submit=Təsdiq edin
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF Мулти инструмент
|
||||
home.multiTool.desc=Обединяване, завъртане, пренареждане и премахване на страници
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Качете единствения голям ска
|
||||
autoSplitPDF.selectText.4=Разделителните страници се откриват и премахват автоматично, което гарантира чист краен документ.
|
||||
autoSplitPDF.formPrompt=Изпратете PDF, съдържащ разделители на страници на Stirling-PDF:
|
||||
autoSplitPDF.duplexMode=Дуплексен режим (сканиране отпред и отзад)
|
||||
autoSplitPDF.dividerDownload1=Изтеглете 'Автоматичен сплитер разделител (минимален).pdf'
|
||||
autoSplitPDF.dividerDownload2=Изтеглете 'Автоматичен сплитер разделител (с инструкции).pdf'
|
||||
autoSplitPDF.submit=Подайте
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=Eina Multifunció de PDF
|
||||
home.multiTool.desc=Fusiona, Rota, Reorganitza i Esborra pàgines
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Puja el fitxer PDF escanejat gran i deixa que Stirling
|
||||
autoSplitPDF.selectText.4=Les pàgines divisòries es detecten i eliminen automàticament, garantint un document final ordenat.
|
||||
autoSplitPDF.formPrompt=Envia un PDF que contingui les pàgines divisòries de Stirling-PDF:
|
||||
autoSplitPDF.duplexMode=Mode Dúplex (Escaneig de davant i darrere)
|
||||
autoSplitPDF.dividerDownload1=Descarrega 'Divisor Automàtic (mínim).pdf'
|
||||
autoSplitPDF.dividerDownload2=Descarrega 'Divisor Automàtic (amb instruccions).pdf'
|
||||
autoSplitPDF.submit=Envia
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF Multi nástroj
|
||||
home.multiTool.desc=Sloučit, otočit, přeuspořádat, rozdělit a odstranit stránky
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Nahrajte jediný velký naskenovaný PDF soubor a nech
|
||||
autoSplitPDF.selectText.4=Oddělovací stránky jsou automaticky detekovány a odstraněny, což zaručuje čistý finální dokument.
|
||||
autoSplitPDF.formPrompt=Odeslat PDF obsahující Stirling-PDF oddělovače stránek:
|
||||
autoSplitPDF.duplexMode=Duplexní režim (skenování přední a zadní strany)
|
||||
autoSplitPDF.dividerDownload1=Stáhnout 'Automatický oddělovač (minimální).pdf'
|
||||
autoSplitPDF.dividerDownload2=Stáhnout 'Automatický oddělovač (s instrukcemi).pdf'
|
||||
autoSplitPDF.submit=Odeslat
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF Multi Værktøj
|
||||
home.multiTool.desc=Flet, Rotér, Omarrangér og Fjern sider
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Upload den enkelte store scannede PDF-fil og lad Stirl
|
||||
autoSplitPDF.selectText.4=Skillesider detekteres automatisk og fjernes, hvilket garanterer et pænt endeligt dokument.
|
||||
autoSplitPDF.formPrompt=Indsend PDF indeholdende Stirling-PDF Sideopdelere:
|
||||
autoSplitPDF.duplexMode=Duplex-tilstand (For- og bagside scanning)
|
||||
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
|
||||
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (med instruktioner).pdf'
|
||||
autoSplitPDF.submit=Indsend
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ analytics.settings=Sie können die Einstellungen für die Analytics in der confi
|
||||
# NAVBAR #
|
||||
#############
|
||||
navbar.favorite=Favoriten
|
||||
navbar.recent=New and recently updated
|
||||
navbar.recent=Neu und kürzlich aktualisiert
|
||||
navbar.darkmode=Dunkler Modus
|
||||
navbar.language=Sprachen
|
||||
navbar.settings=Einstellungen
|
||||
@@ -266,13 +266,14 @@ home.viewPdf.title=PDF anzeigen
|
||||
home.viewPdf.desc=Anzeigen, Kommentieren, Text oder Bilder hinzufügen
|
||||
viewPdf.tags=anzeigen,lesen,kommentieren,text,bild
|
||||
|
||||
home.setFavorites=Set Favourites
|
||||
home.hideFavorites=Hide Favourites
|
||||
home.showFavorites=Show Favourites
|
||||
home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.setFavorites=Favoriten festlegen
|
||||
home.hideFavorites=Favoriten ausblenden
|
||||
home.showFavorites=Favoriten anzeigen
|
||||
home.legacyHomepage=Alte Homepage
|
||||
home.newHomePage=Probieren Sie unsere neue Homepage aus!
|
||||
home.alphabetical=Alphabetisch
|
||||
home.globalPopularity=Beliebtheit
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF-Multitool
|
||||
home.multiTool.desc=Seiten zusammenführen, drehen, neu anordnen und entfernen
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Laden Sie die einzelne große gescannte PDF-Datei hoch
|
||||
autoSplitPDF.selectText.4=Trennseiten werden automatisch erkannt und entfernt, so dass ein sauberes Enddokument garantiert ist.
|
||||
autoSplitPDF.formPrompt=PDF mit Stirling-PDF Seitentrennern hochladen:
|
||||
autoSplitPDF.duplexMode=Duplex-Modus (Scannen von Vorder- und Rückseite)
|
||||
autoSplitPDF.dividerDownload1=Herunterladen 'Auto Splitter Divider (minimal).pdf'
|
||||
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (mit Anleitung).pdf'
|
||||
autoSplitPDF.submit=Aufteilen
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=Πολυεργαλείο PDF
|
||||
home.multiTool.desc=Συγχώνευση, Περιστροφή, Αναδιάταξη, Διαχωρισμός και Αφαίρεση σελίδων
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Μεταφορτώστε το ενιαίο μεγάλ
|
||||
autoSplitPDF.selectText.4=Οι σελίδες διαχωρισμού ανιχνεύονται και αφαιρούνται αυτόματα, εξασφαλίζοντας ένα καθαρό τελικό έγγραφο.
|
||||
autoSplitPDF.formPrompt=Υποβολή PDF που περιέχει διαχωριστές σελίδων Stirling-PDF:
|
||||
autoSplitPDF.duplexMode=Λειτουργία διπλής όψης (Σάρωση μπρος και πίσω)
|
||||
autoSplitPDF.dividerDownload1=Λήψη 'Αυτόματος διαχωριστής (ελάχιστος).pdf'
|
||||
autoSplitPDF.dividerDownload2=Λήψη 'Αυτόματος διαχωριστής (με οδηγίες).pdf'
|
||||
autoSplitPDF.submit=Υποβολή
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF Multi Tool
|
||||
home.multiTool.desc=Merge, Rotate, Rearrange, Split, and Remove pages
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirl
|
||||
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.duplexMode=Duplex Mode (Front and back scanning)
|
||||
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
|
||||
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
|
||||
autoSplitPDF.submit=Submit
|
||||
|
||||
@@ -1184,7 +1184,7 @@ changeMetadata.submit=Change
|
||||
#pdfToPDFA
|
||||
pdfToPDFA.title=PDF To PDF/A
|
||||
pdfToPDFA.header=PDF To PDF/A
|
||||
pdfToPDFA.credit=This service uses qpdf for PDF/A conversion
|
||||
pdfToPDFA.credit=This service uses libreoffice for PDF/A conversion
|
||||
pdfToPDFA.submit=Convert
|
||||
pdfToPDFA.tip=Currently does not work for multiple inputs at once
|
||||
pdfToPDFA.outputFormat=Output format
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF Multi Tool
|
||||
home.multiTool.desc=Merge, Rotate, Rearrange, Split, and Remove pages
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirl
|
||||
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.duplexMode=Duplex Mode (Front and back scanning)
|
||||
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
|
||||
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
|
||||
autoSplitPDF.submit=Submit
|
||||
|
||||
@@ -1184,7 +1184,7 @@ changeMetadata.submit=Change
|
||||
#pdfToPDFA
|
||||
pdfToPDFA.title=PDF To PDF/A
|
||||
pdfToPDFA.header=PDF To PDF/A
|
||||
pdfToPDFA.credit=This service uses qpdf for PDF/A conversion
|
||||
pdfToPDFA.credit=This service uses libreoffice for PDF/A conversion
|
||||
pdfToPDFA.submit=Convert
|
||||
pdfToPDFA.tip=Currently does not work for multiple inputs at once
|
||||
pdfToPDFA.outputFormat=Output format
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=Multi-herramienta PDF
|
||||
home.multiTool.desc=Combinar, rotar, reorganizar y eliminar páginas
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Cargue un único archivo PDF escaneado de gran tamaño
|
||||
autoSplitPDF.selectText.4=Las páginas divisorias son automáticamente detectadas y eliminadas, garantizando un buen documento final.
|
||||
autoSplitPDF.formPrompt=Entregar PDF conteniendo divisores de página de Stirling-PDF:
|
||||
autoSplitPDF.duplexMode=Modo Dúplex (Escaneado de ambas caras)
|
||||
autoSplitPDF.dividerDownload1=Descargar 'Divisor automático (mínima).pdf'
|
||||
autoSplitPDF.dividerDownload2=Descargar 'Divisor automático (con instrucciones).pdf'
|
||||
autoSplitPDF.submit=Entregar
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=Erabilera anitzeko tresna PDF
|
||||
home.multiTool.desc=Orriak konbinatu, biratu, berrantolatu eta ezabatu
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Igo eskaneatutako PDF artxibo handia, eta utzi Stirlin
|
||||
autoSplitPDF.selectText.4=Orrialde zatitzaileak automatikoki detektatu eta kentzen dira, eta azken dokumentu ordenatua bermatzen da.
|
||||
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
|
||||
autoSplitPDF.duplexMode=Duplex Mode (Front and back scanning)Duplex modua (aurreko eta atzeko azterketa)
|
||||
autoSplitPDF.dividerDownload1=Deskargatu 'Auto Splitter Divider (minimal).pdf'
|
||||
autoSplitPDF.dividerDownload2=Deskargatu 'Auto Splitter Divider (with instructions).pdf'
|
||||
autoSplitPDF.submit=Bidali
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=ابزار چندگانه PDF
|
||||
home.multiTool.desc=ترکیب، چرخش، بازآرایی، تقسیم و حذف صفحات
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=فایل PDF بزرگ اسکن شده را بارگذ
|
||||
autoSplitPDF.selectText.4=صفحات جداکننده به طور خودکار تشخیص داده و حذف میشوند، تضمینکننده یک سند نهایی منظم.
|
||||
autoSplitPDF.formPrompt=PDF حاوی جداکنندههای Stirling-PDF را ارسال کنید:
|
||||
autoSplitPDF.duplexMode=حالت دوبلکس (اسکن جلو و عقب)
|
||||
autoSplitPDF.dividerDownload1=دانلود 'Auto Splitter Divider (minimal).pdf'
|
||||
autoSplitPDF.dividerDownload2=دانلود 'Auto Splitter Divider (with instructions).pdf'
|
||||
autoSplitPDF.submit=ارسال
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=Outil multifonction PDF
|
||||
home.multiTool.desc=Fusionnez, faites pivoter, réorganisez et supprimez des pages.
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Téléchargez le fichier PDF numérisé et laissez Sti
|
||||
autoSplitPDF.selectText.4=Les feuilles de séparation sont automatiquement détectées et supprimées, garantissant un document final soigné.
|
||||
autoSplitPDF.formPrompt=PDF contenant des feuilles de séparation de Stirling PDF :
|
||||
autoSplitPDF.duplexMode=Mode recto-verso
|
||||
autoSplitPDF.dividerDownload1=Auto Splitter Divider (minimal).pdf
|
||||
autoSplitPDF.dividerDownload2=Auto Splitter Divider (with instructions).pdf
|
||||
autoSplitPDF.submit=Séparer
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=Il-uirlis PDF
|
||||
home.multiTool.desc=Cumaisc, Rothlaigh, Atheagraigh, agus Bain leathanaigh
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Uaslódáil an comhad PDF mór scanta amháin agus lig
|
||||
autoSplitPDF.selectText.4=Déantar leathanaigh roinnteoirí a bhrath agus a bhaint go huathoibríoch, rud a ráthaíonn doiciméad deiridh néata.
|
||||
autoSplitPDF.formPrompt=Cuir PDF isteach ina bhfuil roinnteoirí Leathanaigh Stirling-PDF:
|
||||
autoSplitPDF.duplexMode=Mód Duplex (scanadh tosaigh agus cúil)
|
||||
autoSplitPDF.dividerDownload1=Íoslódáil 'Auto Scoilteoir Roinnteoir (íosmhéid).pdf'
|
||||
autoSplitPDF.dividerDownload2=Íoslódáil 'Auto Splitter Divider (le treoracha).pdf'
|
||||
autoSplitPDF.submit=Cuir isteach
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF मल्टी टूल
|
||||
home.multiTool.desc=मर्ज करें, घुमाएं, पुनर्व्यवस्थित करें और पृष्ठ हटाएं
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=एक बड़ी स्कैन की गई PDF
|
||||
autoSplitPDF.selectText.4=विभाजक पृष्ठ स्वचालित रूप से पहचाने जाते हैं और हटा दिए जाते हैं, एक साफ अंतिम दस्तावेज़ सुनिश्चित करते हैं।
|
||||
autoSplitPDF.formPrompt=Stirling-PDF पृष्ठ विभाजक वाली PDF जमा करें:
|
||||
autoSplitPDF.duplexMode=डुप्लेक्स मोड (सामने और पीछे स्कैनिंग)
|
||||
autoSplitPDF.dividerDownload1='स्वतः विभाजक (न्यूनतम).pdf' डाउनलोड करें
|
||||
autoSplitPDF.dividerDownload2='स्वतः विभाजक (निर्देशों के साथ).pdf' डाउनलोड करें
|
||||
autoSplitPDF.submit=जमा करें
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF Višestruki alat
|
||||
home.multiTool.desc=Spajanje, rotiranje, preuređivanje i uklanjanje stranica
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Prenesite jednu veliku skeniranu PDF datoteku i pustit
|
||||
autoSplitPDF.selectText.4=Razdjelne stranice automatski se otkrivaju i uklanjaju, jamčeći uredan konačni dokument.
|
||||
autoSplitPDF.formPrompt=Pošaljite PDF koji sadrži naše razdjelnike stranica:
|
||||
autoSplitPDF.duplexMode=Obostrani način rada (skeniranje s prednje i stražnje strane)
|
||||
autoSplitPDF.dividerDownload1=Preuzmite 'Auto Splitter Divider (minimalan).pdf'
|
||||
autoSplitPDF.dividerDownload2=Preuzmite 'Auto Splitter Divider (s uputama).pdf'
|
||||
autoSplitPDF.submit=Potvrdi
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF többfunkciós eszköz
|
||||
home.multiTool.desc=Egyesítés, forgatás, átrendezés és oldalak eltávolítása
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Töltse fel az egyetlen nagy szkennelt PDF fájlt, és
|
||||
autoSplitPDF.selectText.4=Az elválasztólapokat automatikusan felismeri és eltávolítja, garantálva a rendezett végeredményt.
|
||||
autoSplitPDF.formPrompt=Töltse fel a Stirling-PDF oldalelválasztókat tartalmazó PDF-et:
|
||||
autoSplitPDF.duplexMode=Duplex mód (Elő- és hátoldali szkennelés)
|
||||
autoSplitPDF.dividerDownload1='Automatikus elválasztó (minimális).pdf' letöltése
|
||||
autoSplitPDF.dividerDownload2='Automatikus elválasztó (utasításokkal).pdf' letöltése
|
||||
autoSplitPDF.submit=Küldés
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=Alat Multi PDF
|
||||
home.multiTool.desc=Menggabungkan, Memutar, Mengatur Ulang, dan Menghapus halaman
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Unggah satu berkas PDF besar yang dipindai dan biarkan
|
||||
autoSplitPDF.selectText.4=Halaman pembatas secara otomatis terdeteksi dan dihapus, menjamin dokumen akhir yang rapi.
|
||||
autoSplitPDF.formPrompt=Kirimkan PDF yang berisi pembagi Halaman Stirling-PDF:
|
||||
autoSplitPDF.duplexMode=Mode Dupleks (Pemindaian depan dan belakang)
|
||||
autoSplitPDF.dividerDownload1=Unduh 'Pembagi Pembagi Otomatis (minimal).pdf'
|
||||
autoSplitPDF.dividerDownload2=Unduh 'Pembagi Pembagi Otomatis (dengan instruksi).pdf'
|
||||
autoSplitPDF.submit=Kirim
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ bored=Stanco di aspettare?
|
||||
alphabet=Alfabeto
|
||||
downloadPdf=Scarica PDF
|
||||
text=Testo
|
||||
font=Fonte
|
||||
font=Font
|
||||
selectFillter=-- Seleziona --
|
||||
pageNum=Numero pagina
|
||||
sizes.small=Piccolo
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Vecchia homepage
|
||||
home.newHomePage=Prova la nostra nuova homepage!
|
||||
home.alphabetical=Alfabetico
|
||||
home.globalPopularity=Popolarità globale
|
||||
home.sortBy=Ordina per:
|
||||
|
||||
home.multiTool.title=Multifunzione PDF
|
||||
home.multiTool.desc=Unisci, Ruota, Riordina, e Rimuovi pagine
|
||||
@@ -601,7 +602,7 @@ autoRedact.submitButton=Invia
|
||||
redact.title=Redazione manuale
|
||||
redact.header=Redazione manuale
|
||||
redact.submit=Redazione
|
||||
redact.textBasedRedaction=TRedazione basata sul testo
|
||||
redact.textBasedRedaction=Redazione basata sul testo
|
||||
redact.pageBasedRedaction=Redazione basata sulla pagina
|
||||
redact.convertPDFToImageLabel=Converti PDF in immagine PDF (utilizzato per rimuovere il testo dietro la casella)
|
||||
redact.pageRedactionNumbers.title=Pagine
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Carica il singolo file PDF scansionato di grandi dimen
|
||||
autoSplitPDF.selectText.4=Le pagine divisorie vengono rilevate e rimosse automaticamente, garantendo un documento finale ordinato.
|
||||
autoSplitPDF.formPrompt=Invia PDF contenente divisori di pagina Stirling-PDF:
|
||||
autoSplitPDF.duplexMode=Modalità duplex (scansione fronte e retro)
|
||||
autoSplitPDF.dividerDownload1=Scarica 'Divisore automatico (minimo).pdf'
|
||||
autoSplitPDF.dividerDownload2=Scarica 'Divisore automatico (con istruzioni).pdf'
|
||||
autoSplitPDF.submit=Invia
|
||||
|
||||
@@ -951,7 +951,7 @@ compress.title=Comprimi
|
||||
compress.header=Comprimi PDF
|
||||
compress.credit=Questo servizio utilizza qpdf per la compressione/ottimizzazione dei PDF.
|
||||
compress.selectText.1=Modalità manuale - Da 1 a 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.1.1=Nei livelli di ottimizzazione da 6 a 9, oltre alla compressione PDF generale, la risoluzione dell'immagine viene ridotta per ridurre ulteriormente le dimensioni del file. Livelli più alti comportano una compressione dell'immagine più forte (fino al 50% delle dimensioni originali), ottenendo una maggiore riduzione delle dimensioni ma con una potenziale perdita di qualità nelle immagini.
|
||||
compress.selectText.2=Livello di ottimizzazione:
|
||||
compress.selectText.3=4 (Terribile per le immagini di testo)
|
||||
compress.selectText.4=Modalità automatica - Regola automaticamente la qualità per ottenere le dimensioni esatte del PDF
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDFマルチツール
|
||||
home.multiTool.desc=ページの結合、回転、並べ替え、削除します。
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=スキャンしたPDFファイルをアップロード
|
||||
autoSplitPDF.selectText.4=仕切りページは自動的に検出、削除されるので、最終的な文書はきれいに仕上がります。
|
||||
autoSplitPDF.formPrompt=Stirling-PDF仕切り用紙を含むPDFを送信:
|
||||
autoSplitPDF.duplexMode=両面モード (表裏スキャン)
|
||||
autoSplitPDF.dividerDownload1=ダウンロード '自動仕切り用紙 (最小).pdf'
|
||||
autoSplitPDF.dividerDownload2=ダウンロード '自動仕切り用紙 (手順書付き).pdf'
|
||||
autoSplitPDF.submit=送信
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF 멀티 도구
|
||||
home.multiTool.desc=병합, 회전, 재배치, 분할 및 페이지 제거
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=스캔한 단일 PDF 파일을 업로드하고 나머
|
||||
autoSplitPDF.selectText.4=구분자 페이지는 자동으로 감지되고 제거되어 깔끔한 최종 문서를 보장합니다.
|
||||
autoSplitPDF.formPrompt=Stirling-PDF 페이지 구분자가 포함된 PDF 제출:
|
||||
autoSplitPDF.duplexMode=양면 모드 (앞뒷면 스캔)
|
||||
autoSplitPDF.dividerDownload1='자동 분할 구분자 (최소)' PDF 다운로드
|
||||
autoSplitPDF.dividerDownload2='자동 분할 구분자 (설명 포함)' PDF 다운로드
|
||||
autoSplitPDF.submit=제출
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF multitool
|
||||
home.multiTool.desc=Pagina's samenvoegen, draaien, herschikken en verwijderen
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Upload het enkele grote gescande PDF-bestand en laat S
|
||||
autoSplitPDF.selectText.4=Scheidingspagina's worden automatisch gedetecteerd en verwijderd, wat een net einddocument garandeert.
|
||||
autoSplitPDF.formPrompt=Dien PDF in met Stirling-PDF Pagina-scheiders:
|
||||
autoSplitPDF.duplexMode=Duplex Modus (voor- en achterkant scannen)
|
||||
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
|
||||
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
|
||||
autoSplitPDF.submit=Indienen
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF Multi Verktøy
|
||||
home.multiTool.desc=Slå sammen, roter, omorganiser og fjern sider
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Last opp den enkelte store skannede PDF-filen og la St
|
||||
autoSplitPDF.selectText.4=Delingssidene blir automatisk oppdaget og fjernet, og garanterer et pent endelig dokument.
|
||||
autoSplitPDF.formPrompt=Send inn PDF som inneholder Stirling-PDF-sideskillere:
|
||||
autoSplitPDF.duplexMode=Dupleksmodus (Front- og bakskanning)
|
||||
autoSplitPDF.dividerDownload1=Last ned 'Auto Splitter Divider (minimal).pdf'
|
||||
autoSplitPDF.dividerDownload2=Last ned 'Auto Splitter Divider (med instruksjoner).pdf'
|
||||
autoSplitPDF.submit=Send inn
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=Wielofunkcyjne Narzędzie PDF
|
||||
home.multiTool.desc=Łącz, dziel, obracaj, zmieniaj kolejność i usuwaj strony
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Wyślij pojedynczy duży plik PDF zawierający skan i
|
||||
autoSplitPDF.selectText.4=Strony separacji są automatycznie wykrywane i usuwane, gwarantując ładny finalny dokument.
|
||||
autoSplitPDF.formPrompt=Wyślij dokument PDF zawierający strony podziału z Stirling PDF.
|
||||
autoSplitPDF.duplexMode=Skanowanie dwustronne
|
||||
autoSplitPDF.dividerDownload1=Pobierz 'Auto Splitter Divider (minimal).pdf'
|
||||
autoSplitPDF.dividerDownload2=Pobierz 'Auto Splitter Divider (with instructions).pdf'
|
||||
autoSplitPDF.submit=Wyślij
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ analytics.settings=Você pode alterar as configurações de coleta de dados no a
|
||||
# NAVBAR #
|
||||
#############
|
||||
navbar.favorite=Favoritos
|
||||
navbar.recent=New and recently updated
|
||||
navbar.recent=Novos e Recentemente Atualizados
|
||||
navbar.darkmode=Modo Escuro
|
||||
navbar.language=Idiomas
|
||||
navbar.settings=Configurações
|
||||
@@ -266,13 +266,14 @@ home.viewPdf.title=Visualizar PDF
|
||||
home.viewPdf.desc=Visualizar, anotar, adicionar texto ou imagens ao PDF.
|
||||
viewPdf.tags=visualizar,ler,anotar,texto,imagem
|
||||
|
||||
home.setFavorites=Set Favourites
|
||||
home.hideFavorites=Hide Favourites
|
||||
home.showFavorites=Show Favourites
|
||||
home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.setFavorites=Adicionar Favoritos
|
||||
home.hideFavorites=Ocultar Favoritos
|
||||
home.showFavorites=Mostrar Favoritos
|
||||
home.legacyHomepage=Homepage Antiga
|
||||
home.newHomePage=Experimente nossa nova Homepage!
|
||||
home.alphabetical=Alfabética
|
||||
home.globalPopularity=Popularidade Global
|
||||
home.sortBy=Ordenar por:
|
||||
|
||||
home.multiTool.title=Multiferramentas de PDF
|
||||
home.multiTool.desc=Mesclar, girar, reorganizar, dividir, inserir e remover páginas.
|
||||
@@ -416,7 +417,7 @@ home.pageLayout.title=Layout de Múltiplas Páginas
|
||||
home.pageLayout.desc=Mesclar várias páginas de um documento PDF em uma única página.
|
||||
pageLayout.tags=mesclar,composto,vista-única,organizar
|
||||
|
||||
home.scalePages.title=Ajustar Tamanho/Escala da Página
|
||||
home.scalePages.title=Ajustar Dimensões da Página
|
||||
home.scalePages.desc=Alterar o tamanho/escala da página e/ou seu conteúdo.
|
||||
scalePages.tags=redimensionar,modificar,dimensão,adaptar
|
||||
|
||||
@@ -428,7 +429,7 @@ home.add-page-numbers.title=Adicionar Números de Página
|
||||
home.add-page-numbers.desc=Adicionar números de página no documento, em um local definido.
|
||||
add-page-numbers.tags=paginar,rotular,organizar,índice
|
||||
|
||||
home.auto-rename.title=Renomear Automaticamente o PDF
|
||||
home.auto-rename.title=Renomeação Automática do PDF
|
||||
home.auto-rename.desc=Renomeia automaticamente o PDF com base no cabeçalho detectado.
|
||||
auto-rename.tags=detecção-automática,baseado-em-cabeçalho,organizar,relabel
|
||||
|
||||
@@ -737,8 +738,8 @@ addPageNumbers.submit=Adicionar Números de Página
|
||||
|
||||
|
||||
#auto-rename
|
||||
auto-rename.title=Renomear Automaticamente o PDF
|
||||
auto-rename.header=Renomear Automaticamente o PDF
|
||||
auto-rename.title=Renomeação Automática do PDF
|
||||
auto-rename.header=Renomeação Automática do PDF
|
||||
auto-rename.submit=Renomeação Automática
|
||||
|
||||
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Faça o upload do arquivo único PDF digitalizado e de
|
||||
autoSplitPDF.selectText.4=As páginas divisórias são detectadas e removidas automaticamente, garantindo um documento final organizado.
|
||||
autoSplitPDF.formPrompt=Enviar PDF contendo folhas divisórias Stirling-PDF:
|
||||
autoSplitPDF.duplexMode=Modo Duplex (Digitalização frente e verso).
|
||||
autoSplitPDF.dividerDownload1=Baixar 'Folha Divisória Automática (mínimo).pdf'
|
||||
autoSplitPDF.dividerDownload2=Baixar 'Folha Divisória Automática (com instruções).pdf'
|
||||
autoSplitPDF.submit=Enviar
|
||||
|
||||
@@ -785,8 +785,8 @@ pageLayout.submit=Enviar
|
||||
|
||||
|
||||
#scalePages
|
||||
scalePages.title=Ajustar Tamanho/Escala da Página
|
||||
scalePages.header=Ajustar Tamanho/Escala da Página
|
||||
scalePages.title=Ajustar Dimensões da Página
|
||||
scalePages.header=Ajustar Dimensões da Página
|
||||
scalePages.pageSize=Tamanho desejado do documento:
|
||||
scalePages.keepPageSize=Tamanho Original
|
||||
scalePages.scaleFactor=Fator de zoom (corte) de uma página:
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=Multi Ferramenta PDF
|
||||
home.multiTool.desc=Juntar, Rodar, Reorganizar, Dividir e Remover páginas
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Carregue o único ficheiro PDF digitalizado grande e d
|
||||
autoSplitPDF.selectText.4=As páginas separadoras são automaticamente detetadas e removidas, garantindo um documento final organizado.
|
||||
autoSplitPDF.formPrompt=Submeter PDF contendo separadores de página Stirling-PDF:
|
||||
autoSplitPDF.duplexMode=Modo Duplex (Digitalização frente e verso)
|
||||
autoSplitPDF.dividerDownload1=Transferir 'Separador de Divisão Automática (minimal).pdf'
|
||||
autoSplitPDF.dividerDownload2=Transferir 'Separador de Divisão Automática (com instruções).pdf'
|
||||
autoSplitPDF.submit=Submeter
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=Instrument multiplu PDF
|
||||
home.multiTool.desc=Unifică, rotește, rearanjează și elimină pagini
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Încarcă fișierul PDF scanat mare și lasă Stirling
|
||||
autoSplitPDF.selectText.4=Paginile separatoare sunt detectate automat și eliminate, garantând un document final ordonat.
|
||||
autoSplitPDF.formPrompt=Trimite PDF-ul conținând separatoarele de pagini Stirling-PDF:
|
||||
autoSplitPDF.duplexMode=Mod Duplex (Scanare față-verso)
|
||||
autoSplitPDF.dividerDownload1=Descarcă 'Separator Auto Splitter (minimal).pdf'
|
||||
autoSplitPDF.dividerDownload2=Descarcă 'Separator Auto Splitter (cu instrucțiuni).pdf'
|
||||
autoSplitPDF.submit=Trimite
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=Мультиинструмент PDF
|
||||
home.multiTool.desc=Объединение, поворот, переупорядочивание и удаление страниц
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Загрузите один большой отска
|
||||
autoSplitPDF.selectText.4=Разделительные страницы автоматически обнаруживаются и удаляются, гарантируя аккуратный конечный документ.
|
||||
autoSplitPDF.formPrompt=Отправить PDF, содержащий разделители страниц Stirling-PDF:
|
||||
autoSplitPDF.duplexMode=Двусторонний режим (сканирование с двух сторон)
|
||||
autoSplitPDF.dividerDownload1=Скачать 'Автоматический разделитель (минимальный).pdf'
|
||||
autoSplitPDF.dividerDownload2=Скачать 'Автоматический разделитель (с инструкциями).pdf'
|
||||
autoSplitPDF.submit=Отправить
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF Multi Tool
|
||||
home.multiTool.desc=Zlúčiť, otočiť, preusporiadať a odstrániť stránky
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Nahrajte jeden veľký naskenovaný PDF súbor a necha
|
||||
autoSplitPDF.selectText.4=Rozdeľovacie stránky sú automaticky detekované a odstránené, čo zaručuje čistý konečný dokument.
|
||||
autoSplitPDF.formPrompt=Odoslať PDF obsahujúce Stirling-PDF rozdeľovače stránok:
|
||||
autoSplitPDF.duplexMode=Duplex režim (skanovanie prednej a zadnej strany)
|
||||
autoSplitPDF.dividerDownload1=Stiahnuť 'Auto Splitter Divider (minimálny).pdf'
|
||||
autoSplitPDF.dividerDownload2=Stiahnuť 'Auto Splitter Divider (s inštrukciami).pdf'
|
||||
autoSplitPDF.submit=Odoslať
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF Multi Tool
|
||||
home.multiTool.desc=Spoji, zavrti, prerazporedi, razdeli in odstrani strani
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Naložite eno veliko optično prebrano datoteko PDF in
|
||||
autoSplitPDF.selectText.4=Ločilne strani so samodejno zaznane in odstranjene, kar zagotavlja čist končni dokument.
|
||||
autoSplitPDF.formPrompt=Pošljite PDF, ki vsebuje razdelilnike strani Stirling-PDF:
|
||||
autoSplitPDF.duplexMode=Dupleksni način (skeniranje spredaj in zadaj)
|
||||
autoSplitPDF.dividerDownload1=Prenesi 'Auto Splitter Divider (minimal).pdf'
|
||||
autoSplitPDF.dividerDownload2=Prenesi 'Auto Splitter Divider (z navodili).pdf'
|
||||
autoSplitPDF.submit=Pošlji
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF Multi Alat
|
||||
home.multiTool.desc=Spajanje, rotacija, premeštanje i uklanjanje stranica
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Učitajte jedan veliki skenirani PDF fajl i dozvolite
|
||||
autoSplitPDF.selectText.4=Listovi razdeljivača se automatski detektuju i uklanjaju, obezbeđujući uredan konačni dokument.
|
||||
autoSplitPDF.formPrompt=Potvrdite PDF koji sadrži Stirling-PDF listove razdeljivača:
|
||||
autoSplitPDF.duplexMode=Dupleks režim (skeniranje prednje i zadnje strane)
|
||||
autoSplitPDF.dividerDownload1=Preuzmi 'Auto Splitter Divider (minimal).pdf'
|
||||
autoSplitPDF.dividerDownload2=Preuzmi 'Auto Splitter Divider (sa uputstvima).pdf'
|
||||
autoSplitPDF.submit=Potvrdi
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF Multi-verktyg
|
||||
home.multiTool.desc=Sammanfoga, rotera, ordna om och ta bort sidor
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Ladda upp den enda stora skannade PDF-filen och låt S
|
||||
autoSplitPDF.selectText.4=Avdelarsidor detekteras automatiskt och tas bort, vilket garanterar ett prydligt slutdokument.
|
||||
autoSplitPDF.formPrompt=Skicka PDF som innehåller Stirling-PDF-sidavdelare:
|
||||
autoSplitPDF.duplexMode=Duplexläge (Fram- och baksideskanning)
|
||||
autoSplitPDF.dividerDownload1=Ladda ner 'Auto-delningsavdelare (minimal).pdf'
|
||||
autoSplitPDF.dividerDownload2=Ladda ner 'Auto-delningsavdelare (med instruktioner).pdf'
|
||||
autoSplitPDF.submit=Skicka
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=เครื่องมือ PDF หลายตัว
|
||||
home.multiTool.desc=รวม หมุน จัดเรียง และลบหน้าต่างๆ
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=อัปโหลดไฟล์ PDF ที่สแ
|
||||
autoSplitPDF.selectText.4=หน้ากั้นจะถูกตรวจจับและลบโดยอัตโนมัติ รับประกันเอกสารสุดท้ายที่เรียบร้อย
|
||||
autoSplitPDF.formPrompt=ส่ง PDF ที่มีแผ่นแยก Stirling-PDF:
|
||||
autoSplitPDF.duplexMode=โหมด Duplex (การสแกนหน้าและหลัง)
|
||||
autoSplitPDF.dividerDownload1=ดาวน์โหลด 'Auto Splitter Divider (minimal).pdf'
|
||||
autoSplitPDF.dividerDownload2=ดาวน์โหลด 'Auto Splitter Divider (with instructions).pdf'
|
||||
autoSplitPDF.submit=ส่ง
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF Çoklu Araç
|
||||
home.multiTool.desc=Birleştir, Döndür, Yeniden Düzenle ve Sayfaları Kaldır
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Tek büyük taranmış PDF dosyasını yükleyin ve ge
|
||||
autoSplitPDF.selectText.4=Ayırıcı sayfalar otomatik olarak tespit edilir ve kaldırılır, düzgün bir final belgesi garantilidir.
|
||||
autoSplitPDF.formPrompt=Stirling-PDF Sayfa ayırıcıları içeren PDF'i gönderin:
|
||||
autoSplitPDF.duplexMode=Çift Taraflı Mod (Ön ve arka tarama)
|
||||
autoSplitPDF.dividerDownload1='Otomatik Ayırıcı Ayırıcı (minimal).pdf' indir
|
||||
autoSplitPDF.dividerDownload2='Otomatik Ayırıcı Ayırıcı (talimatlarla).pdf' indir
|
||||
autoSplitPDF.submit=Gönder
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=Мультіінструмент PDF
|
||||
home.multiTool.desc=Об'єднання, поворот, зміна порядку та видалення сторінок
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Завантажте один великий відс
|
||||
autoSplitPDF.selectText.4=Роздільні сторінки автоматично виявляються і видаляються, забезпечуючи акуратний кінцевий документ.
|
||||
autoSplitPDF.formPrompt=Надіслати PDF-файл, що містить роздільні сторінки Stirling-PDF:
|
||||
autoSplitPDF.duplexMode=Дуплексний режим (сканування спереду і ззаду)
|
||||
autoSplitPDF.dividerDownload1=Завантажити 'Auto Splitter Divider (minimal).pdf'
|
||||
autoSplitPDF.dividerDownload2=Завантажити 'Auto Splitter Divider (with instructions).pdf'
|
||||
autoSplitPDF.submit=Надіслати
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=Đa công cụ PDF
|
||||
home.multiTool.desc=Ghép nối, Xoay, Sắp xếp lại và Xóa trang
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=Tải lên tệp PDF quét lớn duy nhất và để
|
||||
autoSplitPDF.selectText.4=Các trang phân cách được tự động phát hiện và xóa, đảm bảo tài liệu cuối cùng gọn gàng.
|
||||
autoSplitPDF.formPrompt=Gửi PDF chứa trang phân cách Stirling-PDF:
|
||||
autoSplitPDF.duplexMode=Chế độ hai mặt (Quét mặt trước và sau)
|
||||
autoSplitPDF.dividerDownload1=Tải xuống 'Trang phân cách tự động (tối giản).pdf'
|
||||
autoSplitPDF.dividerDownload2=Tải xuống 'Trang phân cách tự động (có hướng dẫn).pdf'
|
||||
autoSplitPDF.submit=Gửi
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF ལག་ཆ་མང་པོ།
|
||||
home.multiTool.desc=སྡེབ་སྦྱོར། འཁོར་སྐྱོད། བསྐྱར་སྒྲིག ཁ་གྱེས། དང་ཤོག་ངོས་སུབ་པ།
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=བཤེར་འབེབས་བྱས་པའི
|
||||
autoSplitPDF.selectText.4=བར་མཚམས་ཤོག་ངོས་རྣམས་རང་འགུལ་གྱིས་ངོས་འཛིན་དང་སུབ་པ་བྱས་ནས་མཐའ་མའི་ཡིག་ཆ་གཙང་མ་ཞིག་ངེས་པར་དུ་ཐོབ་ཐུབ།
|
||||
autoSplitPDF.formPrompt=Stirling-PDF ཤོག་ངོས་བར་མཚམས་ཡོད་པའི་ PDF ཕུལ་བ།
|
||||
autoSplitPDF.duplexMode=ཕྱོགས་གཉིས་ཀྱི་རྣམ་པ། (མདུན་རྒྱབ་བཤེར་འབེབས།)
|
||||
autoSplitPDF.dividerDownload1='རང་འགུལ་ཁ་གྱེས་བར་མཚམས། (ཉུང་ཤོས།).pdf' ཕབ་ལེན།
|
||||
autoSplitPDF.dividerDownload2='རང་འགུལ་ཁ་གྱེས་བར་མཚམས། (བཀོལ་སྤྱོད་ལམ་སྟོན་དང་བཅས་པ།).pdf' ཕབ་ལེན།
|
||||
autoSplitPDF.submit=ཕུལ་བ།
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF 多功能工具
|
||||
home.multiTool.desc=合并、旋转、重新排列和删除 PDF 页面
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=上传单个大型扫描的 PDF 文件,让 Stirling
|
||||
autoSplitPDF.selectText.4=分隔页会自动检测和删除,确保最终文档整洁。
|
||||
autoSplitPDF.formPrompt=提交包含 Stirling-PDF 分隔页的 PDF:
|
||||
autoSplitPDF.duplexMode=双面模式(正反面扫描)
|
||||
autoSplitPDF.dividerDownload1=下载“自动拆分分隔页(最小化).pdf”
|
||||
autoSplitPDF.dividerDownload2=下载“自动拆分分隔页(带指导说明).pdf”
|
||||
autoSplitPDF.submit=提交
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
||||
home.newHomePage=Try our new homepage!
|
||||
home.alphabetical=Alphabetical
|
||||
home.globalPopularity=Global Popularity
|
||||
home.sortBy=Sort by:
|
||||
|
||||
home.multiTool.title=PDF 複合工具
|
||||
home.multiTool.desc=合併、旋轉、重新排列和移除頁面
|
||||
@@ -767,7 +768,6 @@ autoSplitPDF.selectText.3=上傳單一大的掃描 PDF 檔案,讓 Stirling PDF
|
||||
autoSplitPDF.selectText.4=自動偵測並移除分隔頁面,確保最終文件整潔。
|
||||
autoSplitPDF.formPrompt=送出包含 Stirling-PDF 頁面分隔器的 PDF:
|
||||
autoSplitPDF.duplexMode=雙面模式(正反面掃描)
|
||||
autoSplitPDF.dividerDownload1=下載 '自動分割器分隔器(最小化).pdf'
|
||||
autoSplitPDF.dividerDownload2=下載 '自動分割器分隔器(帶說明).pdf'
|
||||
autoSplitPDF.submit=送出
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ ui:
|
||||
appName: '' # application's visible name
|
||||
homeDescription: '' # short description or tagline shown on the homepage
|
||||
appNameNavbar: '' # name displayed on the navigation bar
|
||||
languages: [] # If empty, all languages are enabled. To display only German and Polish ["de_DE", "pl_PL"]. British English is always enabled.
|
||||
|
||||
endpoints:
|
||||
toRemove: [] # list endpoints to disable (e.g. ['img-to-pdf', 'remove-pages'])
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24">
|
||||
<symbol id="icon-redact-auto" viewBox="0 0 24 24"> <g id="Layer_2" data-name="Layer 2">
|
||||
<g id="Layer_1-2" data-name="Layer 1">
|
||||
<rect width="24" height="24" style="fill: none"/>
|
||||
@@ -14,4 +14,5 @@
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24">
|
||||
<symbol id="icon-redact-manual" viewBox="-2 0 24 24">
|
||||
<g id="Layer_2" data-name="Layer 2">
|
||||
<g id="Layer_1-2" data-name="Layer 1">
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<symbol id="icon-split-auto" viewBox="0 0 24 24"> <g id="Layer_2" data-name="Layer 2"> <g id="Layer_2" data-name="Layer 2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24">
|
||||
<symbol id="icon-split-auto" viewBox="0 0 24 24">
|
||||
<g id="Layer_2" data-name="Layer 2">
|
||||
<g id="Layer_1-2" data-name="Layer 1">
|
||||
<g>
|
||||
<path d="M18.42466,20.16555,12,13.74089,9.84315,15.89774a2.45776,2.45776,0,0,1,.2524.73425,4.481,4.481,0,0,1,.06883.78013A3.53515,3.53515,0,0,1,9.086,20.00493a3.53516,3.53516,0,0,1-2.59281,1.07843,3.53516,3.53516,0,0,1-2.59281-1.07843,3.6561,3.6561,0,0,1,0-5.18561,3.53516,3.53516,0,0,1,2.59281-1.07843,4.48117,4.48117,0,0,1,.78014.06884,2.45778,2.45778,0,0,1,.73424.25239l2.15685-2.15685L8.00753,9.74842a2.45752,2.45752,0,0,1-.73424.2524,4.48117,4.48117,0,0,1-.78014.06884A3.53516,3.53516,0,0,1,3.90034,8.99123,3.53515,3.53515,0,0,1,2.82192,6.39842,3.53515,3.53515,0,0,1,3.90034,3.80561,3.53515,3.53515,0,0,1,6.49315,2.72719,3.53515,3.53515,0,0,1,9.086,3.80561a3.53515,3.53515,0,0,1,1.07842,2.59281,4.48107,4.48107,0,0,1-.06883.78014,2.45786,2.45786,0,0,1-.2524.73425L21.17808,19.24774v.91781Zm-3.67123-9.17809L12.91781,9.15185,18.42466,3.645h2.75342v.91781ZM6.49315,8.234A1.841,1.841,0,0,0,8.32877,6.39842,1.841,1.841,0,0,0,6.49315,4.56281,1.841,1.841,0,0,0,4.65753,6.39842,1.841,1.841,0,0,0,6.49315,8.234ZM12,12.36418a.47051.47051,0,1,0-.32123-.13767A.44026.44026,0,0,0,12,12.36418ZM6.49315,19.24774a1.83562,1.83562,0,1,0-1.29641-3.132,1.83562,1.83562,0,0,0,1.29641,3.132Z" style="fill: currentColor"/>
|
||||
@@ -9,4 +10,5 @@
|
||||
<rect width="24" height="24" style="fill: none"/>
|
||||
</g>
|
||||
</g>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<symbol id="icon-split-chapters" viewBox="0 0 24 24"> <g id="Layer_2" data-name="Layer 2"> <g id="Layer_2" data-name="Layer 2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24">
|
||||
<symbol id="icon-split-chapters" viewBox="0 0 24 24">
|
||||
<g id="Layer_2" data-name="Layer 2">
|
||||
<g id="Layer_1-2" data-name="Layer 1">
|
||||
<g>
|
||||
<path d="M17.632,9.18527v5.44l1.94-1.16,1.94,1.16v-5.44Z" style="fill: currentColor"/>
|
||||
@@ -9,4 +10,5 @@
|
||||
<rect width="24" height="24" style="fill: none"/>
|
||||
</g>
|
||||
</g>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="padding-left: 20px; margin-right: -20px;">
|
||||
<symbol id="icon-split-size" viewBox="0 0 24 24"> <g id="Layer_2" data-name="Layer 2"> <g id="Layer_2" data-name="Layer 2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24">
|
||||
<symbol id="icon-split-size" viewBox="0 0 24 24">
|
||||
<g id="Layer_2" data-name="Layer 2">
|
||||
<g id="Layer_1-2" data-name="Layer 1">
|
||||
<g>
|
||||
<path d="M17.90313,20.16555l-6.42466-6.42466L9.32162,15.89774a2.45776,2.45776,0,0,1,.2524.73425,4.481,4.481,0,0,1,.06883.78013,3.53515,3.53515,0,0,1-1.07842,2.59281,3.53516,3.53516,0,0,1-2.59281,1.07843,3.53516,3.53516,0,0,1-2.59281-1.07843,3.6561,3.6561,0,0,1,0-5.18561,3.53516,3.53516,0,0,1,2.59281-1.07843,4.48117,4.48117,0,0,1,.78014.06884,2.45778,2.45778,0,0,1,.73424.25239l2.15685-2.15685L7.486,9.74842a2.45752,2.45752,0,0,1-.73424.2524,4.48117,4.48117,0,0,1-.78014.06884A3.53516,3.53516,0,0,1,3.37881,8.99123,3.53515,3.53515,0,0,1,2.30039,6.39842,3.53515,3.53515,0,0,1,3.37881,3.80561,3.53515,3.53515,0,0,1,5.97162,2.72719,3.53515,3.53515,0,0,1,8.56443,3.80561,3.53515,3.53515,0,0,1,9.64285,6.39842a4.48107,4.48107,0,0,1-.06883.78014,2.45786,2.45786,0,0,1-.2524.73425L20.65655,19.24774v.91781Zm-3.67124-9.17809L12.39628,9.15185,17.90313,3.645h2.75342v.91781ZM5.97162,8.234A1.841,1.841,0,0,0,7.80724,6.39842,1.841,1.841,0,0,0,5.97162,4.56281,1.841,1.841,0,0,0,4.136,6.39842,1.841,1.841,0,0,0,5.97162,8.234Zm5.50685,4.13014a.47051.47051,0,1,0-.32123-.13767A.44026.44026,0,0,0,11.47847,12.36418ZM5.97162,19.24774a1.83562,1.83562,0,1,0-1.29641-3.132,1.83562,1.83562,0,0,0,1.29641,3.132Z" style="fill: currentColor"/>
|
||||
@@ -13,4 +14,5 @@
|
||||
<rect width="24" height="24" style="fill: none"/>
|
||||
</g>
|
||||
</g>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |