refactor: normalize files

This commit is contained in:
sbplat 2024-02-11 11:47:00 -05:00
parent 3dd0471e22
commit 55d4fda01b
142 changed files with 17461 additions and 17461 deletions

View File

@ -3,7 +3,7 @@ name: Push Docker Image with VersionNumber
on: on:
workflow_dispatch: workflow_dispatch:
push: push:
branches: branches:
- master - master
- main - main
permissions: permissions:
@ -15,13 +15,13 @@ jobs:
steps: steps:
- uses: actions/checkout@v3.5.2 - uses: actions/checkout@v3.5.2
- name: Set up JDK 17 - name: Set up JDK 17
uses: actions/setup-java@v3.11.0 uses: actions/setup-java@v3.11.0
with: with:
java-version: '17' java-version: '17'
distribution: 'temurin' distribution: 'temurin'
- uses: gradle/gradle-build-action@v2.4.2 - uses: gradle/gradle-build-action@v2.4.2
env: env:
@ -32,11 +32,11 @@ jobs:
- name: Make Gradle wrapper executable - name: Make Gradle wrapper executable
run: chmod +x gradlew run: chmod +x gradlew
- name: Get version number - name: Get version number
id: versionNumber id: versionNumber
run: echo "::set-output name=versionNumber::$(./gradlew printVersion --quiet | tail -1)" run: echo "::set-output name=versionNumber::$(./gradlew printVersion --quiet | tail -1)"
- name: Login to Docker Hub - name: Login to Docker Hub
uses: docker/login-action@v2.1.0 uses: docker/login-action@v2.1.0
with: with:
@ -53,7 +53,7 @@ jobs:
- name: Convert repository owner to lowercase - name: Convert repository owner to lowercase
id: repoowner id: repoowner
run: echo "::set-output name=lowercase::$(echo ${{ github.repository_owner }} | awk '{print tolower($0)}')" run: echo "::set-output name=lowercase::$(echo ${{ github.repository_owner }} | awk '{print tolower($0)}')"
- name: Generate tags - name: Generate tags
id: meta id: meta
uses: docker/metadata-action@v4.4.0 uses: docker/metadata-action@v4.4.0
@ -82,7 +82,7 @@ jobs:
cache-to: type=gha,mode=max cache-to: type=gha,mode=max
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
build-args: build-args:
VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }} VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
platforms: linux/amd64,linux/arm64/v8 platforms: linux/amd64,linux/arm64/v8
@ -99,7 +99,7 @@ jobs:
tags: | tags: |
type=raw,value=${{ steps.versionNumber.outputs.versionNumber }}-ultra-lite,enable=${{ github.ref == 'refs/heads/master' }} type=raw,value=${{ steps.versionNumber.outputs.versionNumber }}-ultra-lite,enable=${{ github.ref == 'refs/heads/master' }}
type=raw,value=latest-ultra-lite,enable=${{ github.ref == 'refs/heads/master' }} type=raw,value=latest-ultra-lite,enable=${{ github.ref == 'refs/heads/master' }}
- name: Build and push Dockerfile-ultra-lite - name: Build and push Dockerfile-ultra-lite
uses: docker/build-push-action@v4.0.0 uses: docker/build-push-action@v4.0.0
@ -112,7 +112,7 @@ jobs:
cache-to: type=gha,mode=max cache-to: type=gha,mode=max
tags: ${{ steps.meta2.outputs.tags }} tags: ${{ steps.meta2.outputs.tags }}
labels: ${{ steps.meta2.outputs.labels }} labels: ${{ steps.meta2.outputs.labels }}
build-args: build-args:
VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }} VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
platforms: linux/amd64,linux/arm64/v8 platforms: linux/amd64,linux/arm64/v8
@ -129,7 +129,7 @@ jobs:
tags: | tags: |
type=raw,value=${{ steps.versionNumber.outputs.versionNumber }}-lite,enable=${{ github.ref == 'refs/heads/master' }} type=raw,value=${{ steps.versionNumber.outputs.versionNumber }}-lite,enable=${{ github.ref == 'refs/heads/master' }}
type=raw,value=latest-lite,enable=${{ github.ref == 'refs/heads/master' }} type=raw,value=latest-lite,enable=${{ github.ref == 'refs/heads/master' }}
- name: Build and push Dockerfile-lite - name: Build and push Dockerfile-lite
uses: docker/build-push-action@v4.0.0 uses: docker/build-push-action@v4.0.0
@ -142,7 +142,7 @@ jobs:
cache-to: type=gha,mode=max cache-to: type=gha,mode=max
tags: ${{ steps.meta3.outputs.tags }} tags: ${{ steps.meta3.outputs.tags }}
labels: ${{ steps.meta3.outputs.labels }} labels: ${{ steps.meta3.outputs.labels }}
build-args: build-args:
VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }} VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
platforms: linux/amd64,linux/arm64/v8 platforms: linux/amd64,linux/arm64/v8
- name: Build and Push Helm Chart - name: Build and Push Helm Chart

View File

@ -1,7 +1,7 @@
name: Release Artifacts name: Release Artifacts
on: on:
release: release:
types: [created] types: [created]
permissions: permissions:
contents: write contents: write
@ -19,13 +19,13 @@ jobs:
file_suffix: '' file_suffix: ''
steps: steps:
- uses: actions/checkout@v3.5.2 - uses: actions/checkout@v3.5.2
- name: Set up JDK 17 - name: Set up JDK 17
uses: actions/setup-java@v3.11.0 uses: actions/setup-java@v3.11.0
with: with:
java-version: '17' java-version: '17'
distribution: 'temurin' distribution: 'temurin'
- name: Grant execute permission for gradlew - name: Grant execute permission for gradlew
run: chmod +x gradlew run: chmod +x gradlew
@ -42,11 +42,11 @@ jobs:
asset_name: Stirling-PDF${{ matrix.file_suffix }}.exe asset_name: Stirling-PDF${{ matrix.file_suffix }}.exe
tag: ${{ github.ref }} tag: ${{ github.ref }}
overwrite: true overwrite: true
- name: Get version number - name: Get version number
id: versionNumber id: versionNumber
run: echo "::set-output name=versionNumber::$(./gradlew printVersion --quiet | tail -1)" run: echo "::set-output name=versionNumber::$(./gradlew printVersion --quiet | tail -1)"
- name: Upload jar binaries to release - name: Upload jar binaries to release
uses: svenstaro/upload-release-action@v2 uses: svenstaro/upload-release-action@v2
with: with:

View File

@ -3,7 +3,7 @@ name: Update Swagger
on: on:
workflow_dispatch: workflow_dispatch:
push: push:
branches: branches:
- master - master
jobs: jobs:
push: push:
@ -12,13 +12,13 @@ jobs:
steps: steps:
- uses: actions/checkout@v3.5.2 - uses: actions/checkout@v3.5.2
- name: Set up JDK 17 - name: Set up JDK 17
uses: actions/setup-java@v3.11.0 uses: actions/setup-java@v3.11.0
with: with:
java-version: '17' java-version: '17'
distribution: 'temurin' distribution: 'temurin'
- name: Grant execute permission for gradlew - name: Grant execute permission for gradlew
run: chmod +x gradlew run: chmod +x gradlew

View File

@ -30,7 +30,7 @@ jobs:
- name: Run Docker Compose Tests - name: Run Docker Compose Tests
run: | run: |
chmod +x ./gradlew chmod +x ./gradlew
- name: Get version number - name: Get version number
id: versionNumber id: versionNumber
run: echo "::set-output name=versionNumber::$(./gradlew printVersion --quiet | tail -1)" run: echo "::set-output name=versionNumber::$(./gradlew printVersion --quiet | tail -1)"

252
.gitignore vendored
View File

@ -1,127 +1,127 @@
### Eclipse ### ### Eclipse ###
.metadata .metadata
bin/ bin/
tmp/ tmp/
*.tmp *.tmp
*.bak *.bak
*.swp *.swp
*~.nib *~.nib
local.properties local.properties
.settings/ .settings/
.loadpath .loadpath
.recommenders .recommenders
.classpath .classpath
.project .project
version.properties version.properties
pipeline/watchedFolders/ pipeline/watchedFolders/
pipeline/finishedFolders/ pipeline/finishedFolders/
#### Stirling-PDF Files ### #### Stirling-PDF Files ###
customFiles/ customFiles/
configs/ configs/
watchedFolders/ watchedFolders/
# Gradle # Gradle
.gradle .gradle
.lock .lock
# External tool builders # External tool builders
.externalToolBuilders/ .externalToolBuilders/
# Locally stored "Eclipse launch configurations" # Locally stored "Eclipse launch configurations"
*.launch *.launch
# PyDev specific (Python IDE for Eclipse) # PyDev specific (Python IDE for Eclipse)
*.pydevproject *.pydevproject
# CDT-specific (C/C++ Development Tooling) # CDT-specific (C/C++ Development Tooling)
.cproject .cproject
# CDT- autotools # CDT- autotools
.autotools .autotools
# Java annotation processor (APT) # Java annotation processor (APT)
.factorypath .factorypath
# PDT-specific (PHP Development Tools) # PDT-specific (PHP Development Tools)
.buildpath .buildpath
# sbteclipse plugin # sbteclipse plugin
.target .target
# Tern plugin # Tern plugin
.tern-project .tern-project
# TeXlipse plugin # TeXlipse plugin
.texlipse .texlipse
# STS (Spring Tool Suite) # STS (Spring Tool Suite)
.springBeans .springBeans
# Code Recommenders # Code Recommenders
.recommenders/ .recommenders/
# Annotation Processing # Annotation Processing
.apt_generated/ .apt_generated/
.apt_generated_test/ .apt_generated_test/
# Scala IDE specific (Scala & Java development for Eclipse) # Scala IDE specific (Scala & Java development for Eclipse)
.cache-main .cache-main
.scala_dependencies .scala_dependencies
.worksheet .worksheet
# Uncomment this line if you wish to ignore the project description file. # Uncomment this line if you wish to ignore the project description file.
# Typically, this file would be tracked if it contains build/dependency configurations: # Typically, this file would be tracked if it contains build/dependency configurations:
#.project #.project
### Eclipse Patch ### ### Eclipse Patch ###
# Spring Boot Tooling # Spring Boot Tooling
.sts4-cache/ .sts4-cache/
### Git ### ### Git ###
# Created by git for backups. To disable backups in Git: # Created by git for backups. To disable backups in Git:
# $ git config --global mergetool.keepBackup false # $ git config --global mergetool.keepBackup false
*.orig *.orig
# Created by git when using merge tools for conflicts # Created by git when using merge tools for conflicts
*.BACKUP.* *.BACKUP.*
*.BASE.* *.BASE.*
*.LOCAL.* *.LOCAL.*
*.REMOTE.* *.REMOTE.*
*_BACKUP_*.txt *_BACKUP_*.txt
*_BASE_*.txt *_BASE_*.txt
*_LOCAL_*.txt *_LOCAL_*.txt
*_REMOTE_*.txt *_REMOTE_*.txt
### Java ### ### Java ###
# Compiled class file # Compiled class file
*.class *.class
# Log file # Log file
*.log *.log
# BlueJ files # BlueJ files
*.ctxt *.ctxt
# Mobile Tools for Java (J2ME) # Mobile Tools for Java (J2ME)
.mtj.tmp/ .mtj.tmp/
# Package Files # # Package Files #
*.jar *.jar
*.war *.war
*.nar *.nar
*.ear *.ear
*.zip *.zip
*.tar.gz *.tar.gz
*.rar *.rar
*.db *.db
/build /build
/.vscode /.vscode
/.idea /.idea
# Ignore Mac DS_Store files # Ignore Mac DS_Store files
.DS_Store .DS_Store
**/.DS_Store **/.DS_Store

View File

@ -1,69 +1,69 @@
# Main stage # Main stage
FROM alpine:3.19.1 FROM alpine:3.19.1
# JDK for app # JDK for app
RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \ 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/community" | tee -a /etc/apk/repositories && \
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \ echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \
apk add --no-cache \ apk add --no-cache \
ca-certificates \ ca-certificates \
tzdata \ tzdata \
tini \ tini \
bash \ bash \
curl \ curl \
openjdk17-jre \ openjdk17-jre \
# Doc conversion # Doc conversion
libreoffice@testing \ libreoffice@testing \
# OCR MY PDF (unpaper for descew and other advanced featues) # OCR MY PDF (unpaper for descew and other advanced featues)
ocrmypdf \ ocrmypdf \
tesseract-ocr-data-eng \ tesseract-ocr-data-eng \
# CV # CV
py3-opencv \ py3-opencv \
# python3/pip # python3/pip
python3 && \ python3 && \
wget https://bootstrap.pypa.io/get-pip.py -qO - | python3 - --break-system-packages --no-cache-dir --upgrade && \ wget https://bootstrap.pypa.io/get-pip.py -qO - | python3 - --break-system-packages --no-cache-dir --upgrade && \
# uno unoconv and HTML # uno unoconv and HTML
pip install --break-system-packages --no-cache-dir --upgrade unoconv WeasyPrint && \ pip install --break-system-packages --no-cache-dir --upgrade unoconv WeasyPrint && \
mv /usr/share/tessdata /usr/share/tessdata-original mv /usr/share/tessdata /usr/share/tessdata-original
ARG VERSION_TAG ARG VERSION_TAG
# Set Environment Variables # Set Environment Variables
ENV DOCKER_ENABLE_SECURITY=false \ ENV DOCKER_ENABLE_SECURITY=false \
HOME=/home/stirlingpdfuser \ HOME=/home/stirlingpdfuser \
VERSION_TAG=$VERSION_TAG \ VERSION_TAG=$VERSION_TAG \
JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -XX:MaxRAMPercentage=75" JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -XX:MaxRAMPercentage=75"
# PUID=1000 \ # PUID=1000 \
# PGID=1000 \ # PGID=1000 \
# UMASK=022 \ # UMASK=022 \
# Copy necessary files # Copy necessary files
COPY scripts /scripts COPY scripts /scripts
COPY pipeline /pipeline COPY pipeline /pipeline
COPY src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto COPY src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto
COPY src/main/resources/static/fonts/*.otf /usr/share/fonts/opentype/noto COPY src/main/resources/static/fonts/*.otf /usr/share/fonts/opentype/noto
COPY build/libs/*.jar app.jar COPY build/libs/*.jar app.jar
# Create user and group # Create user and group
##RUN groupadd -g $PGID stirlingpdfgroup && \ ##RUN groupadd -g $PGID stirlingpdfgroup && \
## useradd -u $PUID -g stirlingpdfgroup -s /bin/sh stirlingpdfuser && \ ## useradd -u $PUID -g stirlingpdfgroup -s /bin/sh stirlingpdfuser && \
## mkdir -p $HOME && chown stirlingpdfuser:stirlingpdfgroup $HOME && \ ## mkdir -p $HOME && chown stirlingpdfuser:stirlingpdfgroup $HOME && \
# Set up necessary directories and permissions # Set up necessary directories and permissions
RUN mkdir -p /configs /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders && \ RUN mkdir -p /configs /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders && \
##&& \ ##&& \
## chown -R stirlingpdfuser:stirlingpdfgroup /scripts /usr/share/fonts/opentype/noto /usr/share/tesseract-ocr /configs /customFiles && \ ## chown -R stirlingpdfuser:stirlingpdfgroup /scripts /usr/share/fonts/opentype/noto /usr/share/tesseract-ocr /configs /customFiles && \
## chown -R stirlingpdfuser:stirlingpdfgroup /usr/share/tesseract-ocr-original && \ ## chown -R stirlingpdfuser:stirlingpdfgroup /usr/share/tesseract-ocr-original && \
# Set font cache and permissions # Set font cache and permissions
fc-cache -f -v && \ fc-cache -f -v && \
chmod +x /scripts/* chmod +x /scripts/*
## chown stirlingpdfuser:stirlingpdfgroup /app.jar && \ ## chown stirlingpdfuser:stirlingpdfgroup /app.jar && \
## chmod +x /scripts/init.sh ## chmod +x /scripts/init.sh
EXPOSE 8080 EXPOSE 8080
# Set user and run command # Set user and run command
##USER stirlingpdfuser ##USER stirlingpdfuser
ENTRYPOINT ["tini", "--", "/scripts/init.sh"] ENTRYPOINT ["tini", "--", "/scripts/init.sh"]
CMD ["java", "-Dfile.encoding=UTF-8", "-jar", "/app.jar"] CMD ["java", "-Dfile.encoding=UTF-8", "-jar", "/app.jar"]

View File

@ -1,46 +1,46 @@
| Operation | PageOps | Convert | Security | Other | CLI | Python | OpenCV | LibreOffice | OCRmyPDF | Java | Javascript | | Operation | PageOps | Convert | Security | Other | CLI | Python | OpenCV | LibreOffice | OCRmyPDF | Java | Javascript |
|---------------------|---------|---------|----------|-------|------|--------|--------|-------------|----------|----------|------------| |---------------------|---------|---------|----------|-------|------|--------|--------|-------------|----------|----------|------------|
| adjust-contrast | ✔️ | | | | | | | | | | ✔️ | | adjust-contrast | ✔️ | | | | | | | | | | ✔️ |
| auto-split-pdf | ✔️ | | | | | | | | | ✔️ | | | auto-split-pdf | ✔️ | | | | | | | | | ✔️ | |
| crop | ✔️ | | | | | | | | | ✔️ | | | crop | ✔️ | | | | | | | | | ✔️ | |
| extract-page | ✔️ | | | | | | | | | ✔️ | | | extract-page | ✔️ | | | | | | | | | ✔️ | |
| merge-pdfs | ✔️ | | | | | | | | | ✔️ | | | merge-pdfs | ✔️ | | | | | | | | | ✔️ | |
| multi-page-layout | ✔️ | | | | | | | | | ✔️ | | | multi-page-layout | ✔️ | | | | | | | | | ✔️ | |
| pdf-organizer | ✔️ | | | | | | | | | ✔️ | ✔️ | | pdf-organizer | ✔️ | | | | | | | | | ✔️ | ✔️ |
| pdf-to-single-page | ✔️ | | | | | | | | | ✔️ | | | pdf-to-single-page | ✔️ | | | | | | | | | ✔️ | |
| remove-pages | ✔️ | | | | | | | | | ✔️ | | | remove-pages | ✔️ | | | | | | | | | ✔️ | |
| rotate-pdf | ✔️ | | | | | | | | | ✔️ | | | rotate-pdf | ✔️ | | | | | | | | | ✔️ | |
| scale-pages | ✔️ | | | | | | | | | ✔️ | | | scale-pages | ✔️ | | | | | | | | | ✔️ | |
| split-pdfs | ✔️ | | | | | | | | | ✔️ | | | split-pdfs | ✔️ | | | | | | | | | ✔️ | |
| file-to-pdf | | ✔️ | | | ✔️ | | | ✔️ | | | | | file-to-pdf | | ✔️ | | | ✔️ | | | ✔️ | | | |
| img-to-pdf | | ✔️ | | | | | | | | ✔️ | | | img-to-pdf | | ✔️ | | | | | | | | ✔️ | |
| pdf-to-html | | ✔️ | | | ✔️ | | | ✔️ | | | | | pdf-to-html | | ✔️ | | | ✔️ | | | ✔️ | | | |
| pdf-to-img | | ✔️ | | | | | | | | ✔️ | | | pdf-to-img | | ✔️ | | | | | | | | ✔️ | |
| pdf-to-pdfa | | ✔️ | | | ✔️ | | | | ✔️ | | | | pdf-to-pdfa | | ✔️ | | | ✔️ | | | | ✔️ | | |
| pdf-to-markdown | | ✔️ | | | | | | | | ✔️ | | | pdf-to-markdown | | ✔️ | | | | | | | | ✔️ | |
| pdf-to-presentation | | ✔️ | | | ✔️ | | | ✔️ | | | | | pdf-to-presentation | | ✔️ | | | ✔️ | | | ✔️ | | | |
| pdf-to-text | | ✔️ | | | ✔️ | | | ✔️ | | | | | pdf-to-text | | ✔️ | | | ✔️ | | | ✔️ | | | |
| pdf-to-word | | ✔️ | | | ✔️ | | | ✔️ | | | | | pdf-to-word | | ✔️ | | | ✔️ | | | ✔️ | | | |
| pdf-to-xml | | ✔️ | | | ✔️ | | | ✔️ | | | | | pdf-to-xml | | ✔️ | | | ✔️ | | | ✔️ | | | |
| xlsx-to-pdf | | ✔️ | | | ✔️ | | | ✔️ | | | | | xlsx-to-pdf | | ✔️ | | | ✔️ | | | ✔️ | | | |
| add-password | | | ✔️ | | | | | | | ✔️ | | | add-password | | | ✔️ | | | | | | | ✔️ | |
| add-watermark | | | ✔️ | | | | | | | ✔️ | | | add-watermark | | | ✔️ | | | | | | | ✔️ | |
| cert-sign | | | ✔️ | | | | | | | ✔️ | | | cert-sign | | | ✔️ | | | | | | | ✔️ | |
| change-permissions | | | ✔️ | | | | | | | ✔️ | | | change-permissions | | | ✔️ | | | | | | | ✔️ | |
| remove-password | | | ✔️ | | | | | | | ✔️ | | | remove-password | | | ✔️ | | | | | | | ✔️ | |
| sanitize-pdf | | | ✔️ | | | | | | | ✔️ | | | sanitize-pdf | | | ✔️ | | | | | | | ✔️ | |
| add-image | | | | ✔️ | | | | | | ✔️ | | | add-image | | | | ✔️ | | | | | | ✔️ | |
| add-page-numbers | | | | ✔️ | | | | | | ✔️ | | | add-page-numbers | | | | ✔️ | | | | | | ✔️ | |
| auto-rename | | | | ✔️ | | | | | | ✔️ | | | auto-rename | | | | ✔️ | | | | | | ✔️ | |
| change-metadata | | | | ✔️ | | | | | | ✔️ | | | change-metadata | | | | ✔️ | | | | | | ✔️ | |
| compare | | | | ✔️ | | | | | | | ✔️ | | compare | | | | ✔️ | | | | | | | ✔️ |
| compress-pdf | | | | ✔️ | ✔️ | | | | ✔️ | | | | compress-pdf | | | | ✔️ | ✔️ | | | | ✔️ | | |
| extract-image-scans | | | | ✔️ | ✔️ | ✔️ | ✔️ | | | | | | extract-image-scans | | | | ✔️ | ✔️ | ✔️ | ✔️ | | | | |
| extract-images | | | | ✔️ | | | | | | ✔️ | | | extract-images | | | | ✔️ | | | | | | ✔️ | |
| flatten | | | | ✔️ | | | | | | | ✔️ | | flatten | | | | ✔️ | | | | | | | ✔️ |
| get-info-on-pdf | | | | ✔️ | | | | | | ✔️ | | | get-info-on-pdf | | | | ✔️ | | | | | | ✔️ | |
| ocr-pdf | | | | ✔️ | ✔️ | | | | ✔️ | | | | ocr-pdf | | | | ✔️ | ✔️ | | | | ✔️ | | |
| remove-blanks | | | | ✔️ | ✔️ | ✔️ | ✔️ | | | | | | remove-blanks | | | | ✔️ | ✔️ | ✔️ | ✔️ | | | | |
| repair | | | | ✔️ | ✔️ | | | ✔️ | | | | | repair | | | | ✔️ | ✔️ | | | ✔️ | | | |
| show-javascript | | | | ✔️ | | | | | | | ✔️ | | show-javascript | | | | ✔️ | | | | | | | ✔️ |
| sign | | | | ✔️ | | | | | | | ✔️ | | sign | | | | ✔️ | | | | | | | ✔️ |

View File

@ -9,13 +9,13 @@ Fork Stirling-PDF and make a new branch out of Main
Then add reference to the language in the navbar by adding a new language entry to the dropdown Then add reference to the language in the navbar by adding a new language entry to the dropdown
https://github.com/Stirling-Tools/Stirling-PDF/blob/main/src/main/resources/templates/fragments/languages.html https://github.com/Stirling-Tools/Stirling-PDF/blob/main/src/main/resources/templates/fragments/languages.html
and add a flag svg file to and add a flag svg file to
https://github.com/Stirling-Tools/Stirling-PDF/tree/main/src/main/resources/static/images/flags https://github.com/Stirling-Tools/Stirling-PDF/tree/main/src/main/resources/static/images/flags
Any SVG flags are fine, i got most of mine from [here](https://flagicons.lipis.dev/) Any SVG flags are fine, i got most of mine from [here](https://flagicons.lipis.dev/)
If your language isnt represented by a flag just find whichever closely matches it, such as for Arabic i chose Saudi Arabia If your language isnt represented by a flag just find whichever closely matches it, such as for Arabic i chose Saudi Arabia
For example to add Polish you would add For example to add Polish you would add
```html ```html
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="pl_PL"> <a class="dropdown-item lang_dropdown-item" href="" data-language-code="pl_PL">
<img src="images/flags/pl.svg" alt="icon" width="20" height="15"> Polski <img src="images/flags/pl.svg" alt="icon" width="20" height="15"> Polski
@ -23,7 +23,7 @@ For example to add Polish you would add
``` ```
The data-language-code is the code used to reference the file in the next step. The data-language-code is the code used to reference the file in the next step.
Start by copying the existing english property file Start by copying the existing english property file
[https://github.com/Stirling-Tools/Stirling-PDF/blob/main/src/main/resources/messages_en_GB.properties](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/src/main/resources/messages_en_GB.properties) [https://github.com/Stirling-Tools/Stirling-PDF/blob/main/src/main/resources/messages_en_GB.properties](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/src/main/resources/messages_en_GB.properties)

View File

@ -7,7 +7,7 @@ Please update your tesseract docker volume path version from 4.00 to 5
## How does the OCR Work ## How does the OCR Work
Stirling-PDF uses [OCRmyPDF](https://github.com/ocrmypdf/OCRmyPDF) which in turn uses tesseract for its text recognition. Stirling-PDF uses [OCRmyPDF](https://github.com/ocrmypdf/OCRmyPDF) which in turn uses tesseract for its text recognition.
All credit goes to them for this awesome work! All credit goes to them for this awesome work!
## Language Packs ## Language Packs
@ -27,7 +27,7 @@ Depending on your requirements, you can choose the appropriate language pack for
#### Docker #### Docker
If you are using Docker, you need to expose the Tesseract tessdata directory as a volume in order to use the additional language packs. If you are using Docker, you need to expose the Tesseract tessdata directory as a volume in order to use the additional language packs.
#### Docker Compose #### Docker Compose
Modify your `docker-compose.yml` file to include the following volume configuration: Modify your `docker-compose.yml` file to include the following volume configuration:

88
Jenkinsfile vendored
View File

@ -1,45 +1,45 @@
pipeline { pipeline {
agent any agent any
stages { stages {
stage('Build') { stage('Build') {
steps { steps {
sh 'chmod 755 gradlew' sh 'chmod 755 gradlew'
sh './gradlew build' sh './gradlew build'
} }
} }
stage('Docker Build') { stage('Docker Build') {
steps { steps {
script { script {
def appVersion = sh(returnStdout: true, script: './gradlew printVersion -q').trim() def appVersion = sh(returnStdout: true, script: './gradlew printVersion -q').trim()
def image = "frooodle/s-pdf:$appVersion" def image = "frooodle/s-pdf:$appVersion"
sh "docker build -t $image ." sh "docker build -t $image ."
} }
} }
} }
stage('Docker Push') { stage('Docker Push') {
steps { steps {
script { script {
def appVersion = sh(returnStdout: true, script: './gradlew printVersion -q').trim() def appVersion = sh(returnStdout: true, script: './gradlew printVersion -q').trim()
def image = "frooodle/s-pdf:$appVersion" def image = "frooodle/s-pdf:$appVersion"
withCredentials([string(credentialsId: 'docker_hub_access_token', variable: 'DOCKER_HUB_ACCESS_TOKEN')]) { withCredentials([string(credentialsId: 'docker_hub_access_token', variable: 'DOCKER_HUB_ACCESS_TOKEN')]) {
sh "docker login --username frooodle --password $DOCKER_HUB_ACCESS_TOKEN" sh "docker login --username frooodle --password $DOCKER_HUB_ACCESS_TOKEN"
sh "docker push $image" sh "docker push $image"
} }
} }
} }
} }
stage('Helm Push') { stage('Helm Push') {
steps { steps {
script { script {
//TODO: Read chartVersion from Chart.yaml //TODO: Read chartVersion from Chart.yaml
def chartVersion = '1.0.0' def chartVersion = '1.0.0'
withCredentials([string(credentialsId: 'docker_hub_access_token', variable: 'DOCKER_HUB_ACCESS_TOKEN')]) { withCredentials([string(credentialsId: 'docker_hub_access_token', variable: 'DOCKER_HUB_ACCESS_TOKEN')]) {
sh "docker login --username frooodle --password $DOCKER_HUB_ACCESS_TOKEN" sh "docker login --username frooodle --password $DOCKER_HUB_ACCESS_TOKEN"
sh "helm package chart/stirling-pdf" sh "helm package chart/stirling-pdf"
sh "helm push stirling-pdf-chart-1.0.0.tgz oci://registry-1.docker.io/frooodle" sh "helm push stirling-pdf-chart-1.0.0.tgz oci://registry-1.docker.io/frooodle"
} }
} }
} }
} }
} }
} }

View File

@ -45,7 +45,7 @@ sudo apt-get update
sudo apt-get install -y git automake autoconf libtool libleptonica-dev pkg-config zlib1g-dev make g++ java-17-openjdk python3 python3-pip sudo apt-get install -y git automake autoconf libtool libleptonica-dev pkg-config zlib1g-dev make g++ java-17-openjdk python3 python3-pip
``` ```
For Fedora-based systems use this command: For Fedora-based systems use this command:
```bash ```bash
sudo dnf install -y git automake autoconf libtool leptonica-devel pkg-config zlib-devel make gcc-c++ java-17-openjdk python3 python3-pip sudo dnf install -y git automake autoconf libtool leptonica-devel pkg-config zlib-devel make gcc-c++ java-17-openjdk python3 python3-pip
@ -95,14 +95,14 @@ For Debian-based systems, you can use the following command:
```bash ```bash
sudo apt-get install -y libreoffice-writer libreoffice-calc libreoffice-impress unpaper ocrmypdf sudo apt-get install -y libreoffice-writer libreoffice-calc libreoffice-impress unpaper ocrmypdf
pip3 install uno opencv-python-headless unoconv pngquant WeasyPrint pip3 install uno opencv-python-headless unoconv pngquant WeasyPrint
``` ```
For Fedora: For Fedora:
```bash ```bash
sudo dnf install -y libreoffice-writer libreoffice-calc libreoffice-impress unpaper ocrmypdf sudo dnf install -y libreoffice-writer libreoffice-calc libreoffice-impress unpaper ocrmypdf
pip3 install uno opencv-python-headless unoconv pngquant WeasyPrint pip3 install uno opencv-python-headless unoconv pngquant WeasyPrint
``` ```
### Step 4: Clone and Build Stirling-PDF ### Step 4: Clone and Build Stirling-PDF
@ -140,7 +140,7 @@ Manual:
1. Download the desired language pack(s) by selecting the `.traineddata` file(s) for the language(s) you need. 1. Download the desired language pack(s) by selecting the `.traineddata` file(s) for the language(s) you need.
2. Place the `.traineddata` files in the Tesseract tessdata directory: `/usr/share/tessdata` 2. Place the `.traineddata` files in the Tesseract tessdata directory: `/usr/share/tessdata`
3. 3.
Please view [OCRmyPDF install guide](https://ocrmypdf.readthedocs.io/en/latest/installation.html) for more info. Please view [OCRmyPDF install guide](https://ocrmypdf.readthedocs.io/en/latest/installation.html) for more info.
**IMPORTANT:** DO NOT REMOVE EXISTING `eng.traineddata`, IT'S REQUIRED. **IMPORTANT:** DO NOT REMOVE EXISTING `eng.traineddata`, IT'S REQUIRED.
@ -269,5 +269,5 @@ You can do this in the terminal by using the `export` command or -D arguements t
```bash ```bash
export APP_HOME_NAME="Stirling PDF" export APP_HOME_NAME="Stirling PDF"
or or
-DAPP_HOME_NAME="Stirling PDF" -DAPP_HOME_NAME="Stirling PDF"
``` ```

View File

@ -1,64 +1,64 @@
|Technology | Ultra-Lite | Lite | Full | |Technology | Ultra-Lite | Lite | Full |
|----------------|:----------:|:----:|:----:| |----------------|:----------:|:----:|:----:|
| Java | ✔️ | ✔️ | ✔️ | | Java | ✔️ | ✔️ | ✔️ |
| JavaScript | ✔️ | ✔️ | ✔️ | | JavaScript | ✔️ | ✔️ | ✔️ |
| Libre | | ✔️ | ✔️ | | Libre | | ✔️ | ✔️ |
| Python | | | ✔️ | | Python | | | ✔️ |
| OpenCV | | | ✔️ | | OpenCV | | | ✔️ |
| OCRmyPDF | | | ✔️ | | OCRmyPDF | | | ✔️ |
Operation | Ultra-Lite | Lite | Full Operation | Ultra-Lite | Lite | Full
--------------------|------------|------|----- --------------------|------------|------|-----
add-page-numbers | ✔️ | ✔️ | ✔️ add-page-numbers | ✔️ | ✔️ | ✔️
add-password | ✔️ | ✔️ | ✔️ add-password | ✔️ | ✔️ | ✔️
add-image | ✔️ | ✔️ | ✔️ add-image | ✔️ | ✔️ | ✔️
add-watermark | ✔️ | ✔️ | ✔️ add-watermark | ✔️ | ✔️ | ✔️
adjust-contrast | ✔️ | ✔️ | ✔️ adjust-contrast | ✔️ | ✔️ | ✔️
auto-split-pdf | ✔️ | ✔️ | ✔️ auto-split-pdf | ✔️ | ✔️ | ✔️
auto-redact | ✔️ | ✔️ | ✔️ auto-redact | ✔️ | ✔️ | ✔️
auto-rename | ✔️ | ✔️ | ✔️ auto-rename | ✔️ | ✔️ | ✔️
cert-sign | ✔️ | ✔️ | ✔️ cert-sign | ✔️ | ✔️ | ✔️
crop | ✔️ | ✔️ | ✔️ crop | ✔️ | ✔️ | ✔️
change-metadata | ✔️ | ✔️ | ✔️ change-metadata | ✔️ | ✔️ | ✔️
change-permissions | ✔️ | ✔️ | ✔️ change-permissions | ✔️ | ✔️ | ✔️
compare | ✔️ | ✔️ | ✔️ compare | ✔️ | ✔️ | ✔️
extract-page | ✔️ | ✔️ | ✔️ extract-page | ✔️ | ✔️ | ✔️
extract-images | ✔️ | ✔️ | ✔️ extract-images | ✔️ | ✔️ | ✔️
flatten | ✔️ | ✔️ | ✔️ flatten | ✔️ | ✔️ | ✔️
get-info-on-pdf | ✔️ | ✔️ | ✔️ get-info-on-pdf | ✔️ | ✔️ | ✔️
img-to-pdf | ✔️ | ✔️ | ✔️ img-to-pdf | ✔️ | ✔️ | ✔️
markdown-to-pdf | ✔️ | ✔️ | ✔️ markdown-to-pdf | ✔️ | ✔️ | ✔️
merge-pdfs | ✔️ | ✔️ | ✔️ merge-pdfs | ✔️ | ✔️ | ✔️
multi-page-layout | ✔️ | ✔️ | ✔️ multi-page-layout | ✔️ | ✔️ | ✔️
overlay-pdf | ✔️ | ✔️ | ✔️ overlay-pdf | ✔️ | ✔️ | ✔️
pdf-organizer | ✔️ | ✔️ | ✔️ pdf-organizer | ✔️ | ✔️ | ✔️
pdf-to-csv | ✔️ | ✔️ | ✔️ pdf-to-csv | ✔️ | ✔️ | ✔️
pdf-to-img | ✔️ | ✔️ | ✔️ pdf-to-img | ✔️ | ✔️ | ✔️
pdf-to-single-page | ✔️ | ✔️ | ✔️ pdf-to-single-page | ✔️ | ✔️ | ✔️
remove-pages | ✔️ | ✔️ | ✔️ remove-pages | ✔️ | ✔️ | ✔️
remove-password | ✔️ | ✔️ | ✔️ remove-password | ✔️ | ✔️ | ✔️
rotate-pdf | ✔️ | ✔️ | ✔️ rotate-pdf | ✔️ | ✔️ | ✔️
sanitize-pdf | ✔️ | ✔️ | ✔️ sanitize-pdf | ✔️ | ✔️ | ✔️
scale-pages | ✔️ | ✔️ | ✔️ scale-pages | ✔️ | ✔️ | ✔️
sign | ✔️ | ✔️ | ✔️ sign | ✔️ | ✔️ | ✔️
show-javascript | ✔️ | ✔️ | ✔️ show-javascript | ✔️ | ✔️ | ✔️
split-by-size-or-count | ✔️ | ✔️ | ✔️ split-by-size-or-count | ✔️ | ✔️ | ✔️
split-pdf-by-sections | ✔️ | ✔️ | ✔️ split-pdf-by-sections | ✔️ | ✔️ | ✔️
split-pdfs | ✔️ | ✔️ | ✔️ split-pdfs | ✔️ | ✔️ | ✔️
file-to-pdf | | ✔️ | ✔️ file-to-pdf | | ✔️ | ✔️
pdf-to-html | | ✔️ | ✔️ pdf-to-html | | ✔️ | ✔️
pdf-to-presentation | | ✔️ | ✔️ pdf-to-presentation | | ✔️ | ✔️
pdf-to-text | | ✔️ | ✔️ pdf-to-text | | ✔️ | ✔️
pdf-to-word | | ✔️ | ✔️ pdf-to-word | | ✔️ | ✔️
pdf-to-xml | | ✔️ | ✔️ pdf-to-xml | | ✔️ | ✔️
repair | | ✔️ | ✔️ repair | | ✔️ | ✔️
xlsx-to-pdf | | ✔️ | ✔️ xlsx-to-pdf | | ✔️ | ✔️
compress-pdf | | | ✔️ compress-pdf | | | ✔️
extract-image-scans | | | ✔️ extract-image-scans | | | ✔️
ocr-pdf | | | ✔️ ocr-pdf | | | ✔️
pdf-to-pdfa | | | ✔️ pdf-to-pdfa | | | ✔️
remove-blanks | | | ✔️ remove-blanks | | | ✔️

View File

@ -92,7 +92,7 @@ dependencies {
implementation 'org.springframework:spring-webmvc:6.1.2' implementation 'org.springframework:spring-webmvc:6.1.2'
implementation("io.github.pixee:java-security-toolkit:1.1.2") implementation("io.github.pixee:java-security-toolkit:1.1.2")
implementation 'org.yaml:snakeyaml:2.2' implementation 'org.yaml:snakeyaml:2.2'
implementation 'org.springframework.boot:spring-boot-starter-web:3.2.2' implementation 'org.springframework.boot:spring-boot-starter-web:3.2.2'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf:3.2.2' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf:3.2.2'
@ -101,7 +101,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security:3.2.2' implementation 'org.springframework.boot:spring-boot-starter-security:3.2.2'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.2.RELEASE' implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.2.RELEASE'
implementation "org.springframework.boot:spring-boot-starter-data-jpa:3.2.2" implementation "org.springframework.boot:spring-boot-starter-data-jpa:3.2.2"
//2.2.x requires rebuild of DB file.. need migration path //2.2.x requires rebuild of DB file.. need migration path
implementation "com.h2database:h2:2.1.214" implementation "com.h2database:h2:2.1.214"
} }
@ -138,15 +138,15 @@ dependencies {
implementation ('com.opencsv:opencsv:5.9') { implementation ('com.opencsv:opencsv:5.9') {
exclude group: 'commons-logging', module: 'commons-logging' exclude group: 'commons-logging', module: 'commons-logging'
} }
implementation ('org.apache.pdfbox:pdfbox:3.0.1'){ implementation ('org.apache.pdfbox:pdfbox:3.0.1'){
exclude group: 'commons-logging', module: 'commons-logging' exclude group: 'commons-logging', module: 'commons-logging'
} }
implementation ('org.apache.pdfbox:xmpbox:3.0.1'){ implementation ('org.apache.pdfbox:xmpbox:3.0.1'){
exclude group: 'commons-logging', module: 'commons-logging' exclude group: 'commons-logging', module: 'commons-logging'
} }
implementation 'org.bouncycastle:bcprov-jdk18on:1.77' implementation 'org.bouncycastle:bcprov-jdk18on:1.77'
implementation 'org.bouncycastle:bcpkix-jdk18on:1.77' implementation 'org.bouncycastle:bcpkix-jdk18on:1.77'
implementation 'org.springframework.boot:spring-boot-starter-actuator:3.2.2' implementation 'org.springframework.boot:spring-boot-starter-actuator:3.2.2'

View File

@ -43,6 +43,6 @@ spec:
name: http name: http
{{- end }} {{- end }}
protocol: TCP protocol: TCP
selector: selector:
{{- include "stirlingpdf.selectorLabels" . | nindent 4 }} {{- include "stirlingpdf.selectorLabels" . | nindent 4 }}

View File

@ -19,8 +19,8 @@
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs173"> id="defs173">
<linearGradient <linearGradient
id="XMLID_5_" id="XMLID_5_"
gradientUnits="userSpaceOnUse" gradientUnits="userSpaceOnUse"
@ -37,7 +37,7 @@
style="stop-color:#C2C2C9" style="stop-color:#C2C2C9"
id="stop158" /> id="stop158" />
</linearGradient> </linearGradient>
</defs><sodipodi:namedview </defs><sodipodi:namedview
id="namedview171" id="namedview171"
pagecolor="#ffffff" pagecolor="#ffffff"

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

182
gradlew.bat vendored
View File

@ -1,91 +1,91 @@
@rem @rem
@rem Copyright 2015 the original author or authors. @rem Copyright 2015 the original author or authors.
@rem @rem
@rem Licensed under the Apache License, Version 2.0 (the "License"); @rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License. @rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at @rem You may obtain a copy of the License at
@rem @rem
@rem https://www.apache.org/licenses/LICENSE-2.0 @rem https://www.apache.org/licenses/LICENSE-2.0
@rem @rem
@rem Unless required by applicable law or agreed to in writing, software @rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS, @rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and @rem See the License for the specific language governing permissions and
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@if "%DEBUG%"=="" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@rem Gradle startup script for Windows @rem Gradle startup script for Windows
@rem @rem
@rem ########################################################################## @rem ##########################################################################
@rem Set local scope for the variables with windows NT shell @rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=. if "%DIRNAME%"=="" set DIRNAME=.
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter. @rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute if %ERRORLEVEL% equ 0 goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo. echo.
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation. echo location of your Java installation.
goto fail goto fail
:findJavaFromJavaHome :findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo. echo.
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation. echo location of your Java installation.
goto fail goto fail
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd if %ERRORLEVEL% equ 0 goto mainEnd
:fail :fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code! rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL% set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1 if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE% exit /b %EXIT_CODE%
:mainEnd :mainEnd
if "%OS%"=="Windows_NT" endlocal if "%OS%"=="Windows_NT" endlocal
:omega :omega

View File

@ -4,7 +4,7 @@ if [ "$DOCKER_ENABLE_SECURITY" = "true" ] && [ "$VERSION_TAG" != "alpha" ]; then
if [ ! -f app-security.jar ]; then if [ ! -f app-security.jar ]; then
echo "Trying to download from: https://github.com/Stirling-Tools/Stirling-PDF/releases/download/v$VERSION_TAG/Stirling-PDF-with-login.jar" echo "Trying to download from: https://github.com/Stirling-Tools/Stirling-PDF/releases/download/v$VERSION_TAG/Stirling-PDF-with-login.jar"
curl -L -o app-security.jar https://github.com/Stirling-Tools/Stirling-PDF/releases/download/v$VERSION_TAG/Stirling-PDF-with-login.jar curl -L -o app-security.jar https://github.com/Stirling-Tools/Stirling-PDF/releases/download/v$VERSION_TAG/Stirling-PDF-with-login.jar
# If the first download attempt failed, try with the 'v' prefix # If the first download attempt failed, try with the 'v' prefix
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "Trying to download from: https://github.com/Stirling-Tools/Stirling-PDF/releases/download/$VERSION_TAG/Stirling-PDF-with-login.jar" echo "Trying to download from: https://github.com/Stirling-Tools/Stirling-PDF/releases/download/$VERSION_TAG/Stirling-PDF-with-login.jar"

View File

@ -2,7 +2,7 @@ import argparse
import sys import sys
import cv2 import cv2
import numpy as np import numpy as np
import os import os
def find_photo_boundaries(image, background_color, tolerance=30, min_area=10000, min_contour_area=500): def find_photo_boundaries(image, background_color, tolerance=30, min_area=10000, min_contour_area=500):
mask = cv2.inRange(image, background_color - tolerance, background_color + tolerance) mask = cv2.inRange(image, background_color - tolerance, background_color + tolerance)
@ -49,9 +49,9 @@ def auto_rotate(image, angle_threshold=1):
angles = [] angles = []
for rho, theta in lines[:, 0]: for rho, theta in lines[:, 0]:
angles.append((theta * 180) / np.pi - 90) angles.append((theta * 180) / np.pi - 90)
angle = np.median(angles) angle = np.median(angles)
if abs(angle) < angle_threshold: if abs(angle) < angle_threshold:
return image return image
@ -65,16 +65,16 @@ def auto_rotate(image, angle_threshold=1):
def crop_borders(image, border_color, tolerance=30): def crop_borders(image, border_color, tolerance=30):
mask = cv2.inRange(image, border_color - tolerance, border_color + tolerance) mask = cv2.inRange(image, border_color - tolerance, border_color + tolerance)
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if len(contours) == 0: if len(contours) == 0:
return image return image
largest_contour = max(contours, key=cv2.contourArea) largest_contour = max(contours, key=cv2.contourArea)
x, y, w, h = cv2.boundingRect(largest_contour) x, y, w, h = cv2.boundingRect(largest_contour)
return image[y:y+h, x:x+w] return image[y:y+h, x:x+w]
def split_photos(input_file, output_directory, tolerance=30, min_area=10000, min_contour_area=500, angle_threshold=10, border_size=0): def split_photos(input_file, output_directory, tolerance=30, min_area=10000, min_contour_area=500, angle_threshold=10, border_size=0):
image = cv2.imread(input_file) image = cv2.imread(input_file)
background_color = estimate_background_color(image) background_color = estimate_background_color(image)
@ -110,7 +110,7 @@ if __name__ == "__main__":
parser.add_argument("--min_contour_area", type=int, default=500, help="Sets the minimum contour area threshold for a photo (default: 500).") parser.add_argument("--min_contour_area", type=int, default=500, help="Sets the minimum contour area threshold for a photo (default: 500).")
parser.add_argument("--angle_threshold", type=int, default=10, help="Sets the minimum absolute angle required for the image to be rotated (default: 10).") parser.add_argument("--angle_threshold", type=int, default=10, help="Sets the minimum absolute angle required for the image to be rotated (default: 10).")
parser.add_argument("--border_size", type=int, default=0, help="Sets the size of the border added and removed to prevent white borders in the output (default: 0).") parser.add_argument("--border_size", type=int, default=0, help="Sets the size of the border added and removed to prevent white borders in the output (default: 0).")
args = parser.parse_args() args = parser.parse_args()
split_photos(args.input_file, args.output_directory, tolerance=args.tolerance, min_area=args.min_area, min_contour_area=args.min_contour_area, angle_threshold=args.angle_threshold, border_size=args.border_size) split_photos(args.input_file, args.output_directory, tolerance=args.tolerance, min_area=args.min_area, min_contour_area=args.min_contour_area, angle_threshold=args.angle_threshold, border_size=args.border_size)

View File

@ -22,7 +22,7 @@ server.servlet.context-path=${SYSTEM_ROOTURIPATH:/}
spring.devtools.restart.enabled=true spring.devtools.restart.enabled=true
spring.devtools.livereload.enabled=true spring.devtools.livereload.enabled=true
spring.thymeleaf.encoding=UTF-8 spring.thymeleaf.encoding=UTF-8
server.connection-timeout=${SYSTEM_CONNECTIONTIMEOUTMINUTES:5m} server.connection-timeout=${SYSTEM_CONNECTIONTIMEOUTMINUTES:5m}
spring.mvc.async.request-timeout=${SYSTEM_CONNECTIONTIMEOUTMILLISECONDS:300000} spring.mvc.async.request-timeout=${SYSTEM_CONNECTIONTIMEOUTMILLISECONDS:300000}

View File

@ -1,6 +1,6 @@
____ _____ ___ ____ _ ___ _ _ ____ ____ ____ _____ ____ _____ ___ ____ _ ___ _ _ ____ ____ ____ _____
/ ___|_ _|_ _| _ \| | |_ _| \ | |/ ___| | _ \| _ \| ___| / ___|_ _|_ _| _ \| | |_ _| \ | |/ ___| | _ \| _ \| ___|
\___ \ | | | || |_) | | | || \| | | _ _____| |_) | | | | |_ \___ \ | | | || |_) | | | || \| | | _ _____| |_) | | | | |_
___) || | | || _ <| |___ | || |\ | |_| |_____| __/| |_| | _| ___) || | | || _ <| |___ | || |\ | |_| |_____| __/| |_| | _|
|____/ |_| |___|_| \_\_____|___|_| \_|\____| |_| |____/|_| |____/ |_| |___|_| \_\_____|___|_| \_|\____| |_| |____/|_|
Powered by Spring Boot ${spring-boot.version} Powered by Spring Boot ${spring-boot.version}

File diff suppressed because it is too large Load Diff

View File

@ -497,7 +497,7 @@ AddStampRequest.overrideY=Override Y Coordinate
AddStampRequest.customMargin=Custom Margin AddStampRequest.customMargin=Custom Margin
AddStampRequest.customColor=Custom Text Color AddStampRequest.customColor=Custom Text Color
AddStampRequest.submit=Submit AddStampRequest.submit=Submit
#sanitizePDF #sanitizePDF
sanitizePDF.title=Дезинфектирай PDF sanitizePDF.title=Дезинфектирай PDF
sanitizePDF.header=Дезинфектира PDF файл sanitizePDF.header=Дезинфектира PDF файл
@ -656,7 +656,7 @@ ScannerImageSplit.selectText.8=Задава минималния праг на
ScannerImageSplit.selectText.9=Размер на рамката: ScannerImageSplit.selectText.9=Размер на рамката:
ScannerImageSplit.selectText.10=Задава размера на добавената и премахната граница, за да предотврати бели граници към изхода (по подразбиране: 1). ScannerImageSplit.selectText.10=Задава размера на добавената и премахната граница, за да предотврати бели граници към изхода (по подразбиране: 1).
#OCR #OCR
ocr.title=OCR / Почистване на сканиране ocr.title=OCR / Почистване на сканиране
ocr.header=Почистващи сканирания / OCR (оптично разпознаване на знаци) ocr.header=Почистващи сканирания / OCR (оптично разпознаване на знаци)
@ -775,8 +775,8 @@ imageToPDF.selectText.2=Автоматично завъртане на PDF
imageToPDF.selectText.3=Файлова логика с много (Активирано само ако работите с множество изображения) imageToPDF.selectText.3=Файлова логика с много (Активирано само ако работите с множество изображения)
imageToPDF.selectText.4=Сливане към един PDF imageToPDF.selectText.4=Сливане към един PDF
imageToPDF.selectText.5=Преобразуване към отделни PDF файлове imageToPDF.selectText.5=Преобразуване към отделни PDF файлове
#pdfToImage #pdfToImage
pdfToImage.title=PDF към Изображение pdfToImage.title=PDF към Изображение
pdfToImage.header=PDF към Изображение pdfToImage.header=PDF към Изображение

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -497,7 +497,7 @@ AddStampRequest.overrideY=Override Y Coordinate
AddStampRequest.customMargin=Custom Margin AddStampRequest.customMargin=Custom Margin
AddStampRequest.customColor=Custom Text Color AddStampRequest.customColor=Custom Text Color
AddStampRequest.submit=Submit AddStampRequest.submit=Submit
#sanitizePDF #sanitizePDF
sanitizePDF.title=\u0391\u03C0\u03BF\u03BB\u03CD\u03BC\u03B1\u03BD\u03C3\u03B7 PDF sanitizePDF.title=\u0391\u03C0\u03BF\u03BB\u03CD\u03BC\u03B1\u03BD\u03C3\u03B7 PDF
sanitizePDF.header=\u0391\u03C0\u03BF\u03BB\u03CD\u03BC\u03B1\u03BD\u03C3\u03B7 \u03B5\u03BD\u03CC\u03C2 PDF \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF\u03C5 sanitizePDF.header=\u0391\u03C0\u03BF\u03BB\u03CD\u03BC\u03B1\u03BD\u03C3\u03B7 \u03B5\u03BD\u03CC\u03C2 PDF \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF\u03C5
@ -656,7 +656,7 @@ ScannerImageSplit.selectText.8=\u03A1\u03C5\u03B8\u03BC\u03AF\u03B6\u03B5\u03B9
ScannerImageSplit.selectText.9=\u039C\u03AD\u03B3\u03B5\u03B8\u03BF\u03C2 \u03C0\u03B5\u03C1\u03B9\u03B3\u03C1\u03AC\u03BC\u03BC\u03B1\u03C4\u03BF\u03C2: ScannerImageSplit.selectText.9=\u039C\u03AD\u03B3\u03B5\u03B8\u03BF\u03C2 \u03C0\u03B5\u03C1\u03B9\u03B3\u03C1\u03AC\u03BC\u03BC\u03B1\u03C4\u03BF\u03C2:
ScannerImageSplit.selectText.10=\u039F\u03C1\u03AF\u03B6\u03B5\u03B9 \u03C4\u03BF \u03BC\u03AD\u03B3\u03B5\u03B8\u03BF\u03C2 \u03C4\u03BF\u03C5 \u03C0\u03B5\u03C1\u03B9\u03B3\u03C1\u03AC\u03BC\u03BC\u03B1\u03C4\u03BF\u03C2 \u03C0\u03BF\u03C5 \u03C0\u03C1\u03BF\u03C3\u03C4\u03AF\u03B8\u03B5\u03C4\u03B1\u03B9 \u03BA\u03B1\u03B9 \u03B1\u03C6\u03B1\u03B9\u03C1\u03B5\u03AF\u03C4\u03B1\u03B9 \u03B3\u03B9\u03B1 \u03BD\u03B1 \u03B1\u03C0\u03BF\u03C4\u03C1\u03AD\u03C0\u03BF\u03BD\u03C4\u03B1\u03B9 \u03BB\u03B5\u03C5\u03BA\u03AC \u03C0\u03B5\u03C1\u03B9\u03B3\u03C1\u03AC\u03BC\u03BC\u03B1\u03C4\u03B1 \u03C3\u03C4\u03B7\u03BD \u03AD\u03BE\u03BF\u03B4\u03BF (\u03C0\u03C1\u03BF\u03B5\u03C0\u03B9\u03BB\u03BF\u03B3\u03AE: 1). ScannerImageSplit.selectText.10=\u039F\u03C1\u03AF\u03B6\u03B5\u03B9 \u03C4\u03BF \u03BC\u03AD\u03B3\u03B5\u03B8\u03BF\u03C2 \u03C4\u03BF\u03C5 \u03C0\u03B5\u03C1\u03B9\u03B3\u03C1\u03AC\u03BC\u03BC\u03B1\u03C4\u03BF\u03C2 \u03C0\u03BF\u03C5 \u03C0\u03C1\u03BF\u03C3\u03C4\u03AF\u03B8\u03B5\u03C4\u03B1\u03B9 \u03BA\u03B1\u03B9 \u03B1\u03C6\u03B1\u03B9\u03C1\u03B5\u03AF\u03C4\u03B1\u03B9 \u03B3\u03B9\u03B1 \u03BD\u03B1 \u03B1\u03C0\u03BF\u03C4\u03C1\u03AD\u03C0\u03BF\u03BD\u03C4\u03B1\u03B9 \u03BB\u03B5\u03C5\u03BA\u03AC \u03C0\u03B5\u03C1\u03B9\u03B3\u03C1\u03AC\u03BC\u03BC\u03B1\u03C4\u03B1 \u03C3\u03C4\u03B7\u03BD \u03AD\u03BE\u03BF\u03B4\u03BF (\u03C0\u03C1\u03BF\u03B5\u03C0\u03B9\u03BB\u03BF\u03B3\u03AE: 1).
#OCR #OCR
ocr.title=\u039F\u03C0\u03C4\u03B9\u03BA\u03AE \u03B1\u03BD\u03B1\u03B3\u03BD\u03CE\u03C1\u03B9\u03C3\u03B7 \u03C7\u03B1\u03C1\u03B1\u03BA\u03C4\u03AE\u03C1\u03C9\u03BD (OCR) / \u03A3\u03B1\u03C1\u03CE\u03C3\u03B5\u03B9\u03C2 Cleanup ocr.title=\u039F\u03C0\u03C4\u03B9\u03BA\u03AE \u03B1\u03BD\u03B1\u03B3\u03BD\u03CE\u03C1\u03B9\u03C3\u03B7 \u03C7\u03B1\u03C1\u03B1\u03BA\u03C4\u03AE\u03C1\u03C9\u03BD (OCR) / \u03A3\u03B1\u03C1\u03CE\u03C3\u03B5\u03B9\u03C2 Cleanup
ocr.header=\u03A3\u03B1\u03C1\u03CE\u03C3\u03B5\u03B9\u03C2 Cleanup / OCR (Optical Character Recognition - \u039F\u03C0\u03C4\u03B9\u03BA\u03AE \u03B1\u03BD\u03B1\u03B3\u03BD\u03CE\u03C1\u03B9\u03C3\u03B7 \u03C7\u03B1\u03C1\u03B1\u03BA\u03C4\u03AE\u03C1\u03C9\u03BD) ocr.header=\u03A3\u03B1\u03C1\u03CE\u03C3\u03B5\u03B9\u03C2 Cleanup / OCR (Optical Character Recognition - \u039F\u03C0\u03C4\u03B9\u03BA\u03AE \u03B1\u03BD\u03B1\u03B3\u03BD\u03CE\u03C1\u03B9\u03C3\u03B7 \u03C7\u03B1\u03C1\u03B1\u03BA\u03C4\u03AE\u03C1\u03C9\u03BD)
@ -775,8 +775,8 @@ imageToPDF.selectText.2=\u0391\u03C5\u03C4\u03CC\u03BC\u03B1\u03C4\u03B7 \u03C0\
imageToPDF.selectText.3=\u039B\u03BF\u03B3\u03B9\u03BA\u03AE \u03C0\u03BF\u03BB\u03BB\u03CE\u03BD \u03B1\u03C1\u03C7\u03B5\u03AF\u03C9\u03BD (\u0395\u03BD\u03B5\u03C1\u03B3\u03BF\u03C0\u03BF\u03B9\u03B5\u03AF\u03C4\u03B1\u03B9 \u03BC\u03CC\u03BD\u03BF \u03B5\u03AC\u03BD \u03B5\u03C1\u03B3\u03AC\u03B6\u03B5\u03C3\u03C4\u03B5 \u03BC\u03B5 \u03C0\u03BF\u03BB\u03BB\u03AD\u03C2 \u03B5\u03B9\u03BA\u03CC\u03BD\u03B5\u03C2) imageToPDF.selectText.3=\u039B\u03BF\u03B3\u03B9\u03BA\u03AE \u03C0\u03BF\u03BB\u03BB\u03CE\u03BD \u03B1\u03C1\u03C7\u03B5\u03AF\u03C9\u03BD (\u0395\u03BD\u03B5\u03C1\u03B3\u03BF\u03C0\u03BF\u03B9\u03B5\u03AF\u03C4\u03B1\u03B9 \u03BC\u03CC\u03BD\u03BF \u03B5\u03AC\u03BD \u03B5\u03C1\u03B3\u03AC\u03B6\u03B5\u03C3\u03C4\u03B5 \u03BC\u03B5 \u03C0\u03BF\u03BB\u03BB\u03AD\u03C2 \u03B5\u03B9\u03BA\u03CC\u03BD\u03B5\u03C2)
imageToPDF.selectText.4=\u03A3\u03C5\u03B3\u03C7\u03CE\u03BD\u03B5\u03C5\u03C3\u03B7 \u03C3\u03B5 \u03AD\u03BD\u03B1 PDF imageToPDF.selectText.4=\u03A3\u03C5\u03B3\u03C7\u03CE\u03BD\u03B5\u03C5\u03C3\u03B7 \u03C3\u03B5 \u03AD\u03BD\u03B1 PDF
imageToPDF.selectText.5=\u039C\u03B5\u03C4\u03B1\u03C4\u03C1\u03BF\u03C0\u03AE \u03C3\u03B5 \u03BE\u03B5\u03C7\u03C9\u03C1\u03B9\u03C3\u03C4\u03AC \u03B1\u03C1\u03C7\u03B5\u03AF\u03B1 PDF imageToPDF.selectText.5=\u039C\u03B5\u03C4\u03B1\u03C4\u03C1\u03BF\u03C0\u03AE \u03C3\u03B5 \u03BE\u03B5\u03C7\u03C9\u03C1\u03B9\u03C3\u03C4\u03AC \u03B1\u03C1\u03C7\u03B5\u03AF\u03B1 PDF
#pdfToImage #pdfToImage
pdfToImage.title=PDF \u03C3\u03B5 \u0395\u03B9\u03BA\u03CC\u03BD\u03B1 pdfToImage.title=PDF \u03C3\u03B5 \u0395\u03B9\u03BA\u03CC\u03BD\u03B1
pdfToImage.header=PDF \u03C3\u03B5 \u0395\u03B9\u03BA\u03CC\u03BD\u03B1 pdfToImage.header=PDF \u03C3\u03B5 \u0395\u03B9\u03BA\u03CC\u03BD\u03B1

View File

@ -26,7 +26,7 @@ downloadPdf=Download PDF
text=Text text=Text
font=Font font=Font
selectFillter=-- Select -- selectFillter=-- Select --
pageNum=Page Number pageNum=Page Number
sizes.small=Small sizes.small=Small
sizes.medium=Medium sizes.medium=Medium
sizes.large=Large sizes.large=Large
@ -172,7 +172,7 @@ merge.tags=merge,Page operations,Back end,server side
home.split.title=Split home.split.title=Split
home.split.desc=Split PDFs into multiple documents home.split.desc=Split PDFs into multiple documents
split.tags=Page operations,divide,Multi Page,cut,server side split.tags=Page operations,divide,Multi Page,cut,server side
home.rotate.title=Rotate home.rotate.title=Rotate
home.rotate.desc=Easily rotate your PDFs. home.rotate.desc=Easily rotate your PDFs.
@ -313,7 +313,7 @@ home.add-page-numbers.desc=Add Page numbers throughout a document in a set locat
add-page-numbers.tags=paginate,label,organize,index add-page-numbers.tags=paginate,label,organize,index
home.auto-rename.title=Auto Rename PDF File home.auto-rename.title=Auto Rename PDF File
home.auto-rename.desc=Auto renames a PDF file based on its detected header home.auto-rename.desc=Auto renames a PDF file based on its detected header
auto-rename.tags=auto-detect,header-based,organize,relabel auto-rename.tags=auto-detect,header-based,organize,relabel
home.adjust-contrast.title=Adjust Colors/Contrast home.adjust-contrast.title=Adjust Colors/Contrast
@ -498,7 +498,7 @@ AddStampRequest.overrideY=Override Y Coordinate
AddStampRequest.customMargin=Custom Margin AddStampRequest.customMargin=Custom Margin
AddStampRequest.customColor=Custom Text Color AddStampRequest.customColor=Custom Text Color
AddStampRequest.submit=Submit AddStampRequest.submit=Submit
#sanitizePDF #sanitizePDF
sanitizePDF.title=Sanitize PDF sanitizePDF.title=Sanitize PDF
sanitizePDF.header=Sanitize a PDF file sanitizePDF.header=Sanitize a PDF file
@ -584,18 +584,18 @@ scalePages.submit=Submit
#certSign #certSign
certSign.title=Certificate Signing certSign.title=Certificate Signing
certSign.header=Sign a PDF with your certificate (Work in progress) certSign.header=Sign a PDF with your certificate (Work in progress)
certSign.selectPDF=Select a PDF File for Signing: certSign.selectPDF=Select a PDF File for Signing:
certSign.jksNote=Note: If your certificate type is not listed below, please convert it to a Java Keystore (.jks) file using the keytool command line tool. Then, choose the .jks file option below. certSign.jksNote=Note: If your certificate type is not listed below, please convert it to a Java Keystore (.jks) file using the keytool command line tool. Then, choose the .jks file option below.
certSign.selectKey=Select Your Private Key File (PKCS#8 format, could be .pem or .der): certSign.selectKey=Select Your Private Key File (PKCS#8 format, could be .pem or .der):
certSign.selectCert=Select Your Certificate File (X.509 format, could be .pem or .der): certSign.selectCert=Select Your Certificate File (X.509 format, could be .pem or .der):
certSign.selectP12=Select Your PKCS#12 Keystore File (.p12 or .pfx) (Optional, If provided, it should contain your private key and certificate): certSign.selectP12=Select Your PKCS#12 Keystore File (.p12 or .pfx) (Optional, If provided, it should contain your private key and certificate):
certSign.selectJKS=Select Your Java Keystore File (.jks or .keystore): certSign.selectJKS=Select Your Java Keystore File (.jks or .keystore):
certSign.certType=Certificate Type certSign.certType=Certificate Type
certSign.password=Enter Your Keystore or Private Key Password (If Any): certSign.password=Enter Your Keystore or Private Key Password (If Any):
certSign.showSig=Show Signature certSign.showSig=Show Signature
certSign.reason=Reason certSign.reason=Reason
certSign.location=Location certSign.location=Location
certSign.name=Name certSign.name=Name
certSign.submit=Sign PDF certSign.submit=Sign PDF
@ -657,7 +657,7 @@ ScannerImageSplit.selectText.8=Sets the minimum contour area threshold for a pho
ScannerImageSplit.selectText.9=Border Size: ScannerImageSplit.selectText.9=Border Size:
ScannerImageSplit.selectText.10=Sets the size of the border added and removed to prevent white borders in the output (default: 1). ScannerImageSplit.selectText.10=Sets the size of the border added and removed to prevent white borders in the output (default: 1).
#OCR #OCR
ocr.title=OCR / Scan Cleanup ocr.title=OCR / Scan Cleanup
ocr.header=Cleanup Scans / OCR (Optical Character Recognition) ocr.header=Cleanup Scans / OCR (Optical Character Recognition)
@ -701,7 +701,7 @@ compress.selectText.1=Manual Mode - From 1 to 4
compress.selectText.2=Optimization level: compress.selectText.2=Optimization level:
compress.selectText.3=4 (Terrible for text images) compress.selectText.3=4 (Terrible for text images)
compress.selectText.4=Auto mode - Auto adjusts quality to get PDF to exact size compress.selectText.4=Auto mode - Auto adjusts quality to get PDF to exact size
compress.selectText.5=Expected PDF Size (e.g. 25MB, 10.8MB, 25KB) compress.selectText.5=Expected PDF Size (e.g. 25MB, 10.8MB, 25KB)
compress.submit=Compress compress.submit=Compress
@ -776,8 +776,8 @@ imageToPDF.selectText.2=Auto rotate PDF
imageToPDF.selectText.3=Multi file logic (Only enabled if working with multiple images) imageToPDF.selectText.3=Multi file logic (Only enabled if working with multiple images)
imageToPDF.selectText.4=Merge into single PDF imageToPDF.selectText.4=Merge into single PDF
imageToPDF.selectText.5=Convert to separate PDFs imageToPDF.selectText.5=Convert to separate PDFs
#pdfToImage #pdfToImage
pdfToImage.title=PDF to Image pdfToImage.title=PDF to Image
pdfToImage.header=PDF to Image pdfToImage.header=PDF to Image

View File

@ -497,7 +497,7 @@ AddStampRequest.overrideY=Override Y Coordinate
AddStampRequest.customMargin=Custom Margin AddStampRequest.customMargin=Custom Margin
AddStampRequest.customColor=Custom Text Color AddStampRequest.customColor=Custom Text Color
AddStampRequest.submit=Submit AddStampRequest.submit=Submit
#sanitizePDF #sanitizePDF
sanitizePDF.title=Sanitize PDF sanitizePDF.title=Sanitize PDF
sanitizePDF.header=Sanitize a PDF file sanitizePDF.header=Sanitize a PDF file
@ -656,7 +656,7 @@ ScannerImageSplit.selectText.8=Sets the minimum contour area threshold for a pho
ScannerImageSplit.selectText.9=Border Size: ScannerImageSplit.selectText.9=Border Size:
ScannerImageSplit.selectText.10=Sets the size of the border added and removed to prevent white borders in the output (default: 1). ScannerImageSplit.selectText.10=Sets the size of the border added and removed to prevent white borders in the output (default: 1).
#OCR #OCR
ocr.title=OCR / Scan Cleanup ocr.title=OCR / Scan Cleanup
ocr.header=Cleanup Scans / OCR (Optical Character Recognition) ocr.header=Cleanup Scans / OCR (Optical Character Recognition)
@ -775,8 +775,8 @@ imageToPDF.selectText.2=Auto rotate PDF
imageToPDF.selectText.3=Multi file logic (Only enabled if working with multiple images) imageToPDF.selectText.3=Multi file logic (Only enabled if working with multiple images)
imageToPDF.selectText.4=Merge into single PDF imageToPDF.selectText.4=Merge into single PDF
imageToPDF.selectText.5=Convert to separate PDFs imageToPDF.selectText.5=Convert to separate PDFs
#pdfToImage #pdfToImage
pdfToImage.title=PDF to Image pdfToImage.title=PDF to Image
pdfToImage.header=PDF to Image pdfToImage.header=PDF to Image

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -497,7 +497,7 @@ AddStampRequest.overrideY=Override Y Coordinate
AddStampRequest.customMargin=Custom Margin AddStampRequest.customMargin=Custom Margin
AddStampRequest.customColor=Custom Text Color AddStampRequest.customColor=Custom Text Color
AddStampRequest.submit=Submit AddStampRequest.submit=Submit
#sanitizePDF #sanitizePDF
sanitizePDF.title=पीडीएफ़ को सफाई करें sanitizePDF.title=पीडीएफ़ को सफाई करें
sanitizePDF.header=एक पीडीएफ़ फ़ाइल को सफाई करें sanitizePDF.header=एक पीडीएफ़ फ़ाइल को सफाई करें
@ -656,7 +656,7 @@ ScannerImageSplit.selectText.8=फोटो के लिए न्यूनत
ScannerImageSplit.selectText.9=बॉर्डर का आकार: ScannerImageSplit.selectText.9=बॉर्डर का आकार:
ScannerImageSplit.selectText.10=निकालने और जोड़ने के लिए जोड़ा जाने वाला बॉर्डर का आकार सेट करता है ताकि आउटपुट में सफेद बॉर्डर न आए (डिफ़ॉल्ट: 1)। ScannerImageSplit.selectText.10=निकालने और जोड़ने के लिए जोड़ा जाने वाला बॉर्डर का आकार सेट करता है ताकि आउटपुट में सफेद बॉर्डर न आए (डिफ़ॉल्ट: 1)।
#OCR #OCR
ocr.title=OCR / स्कैन सफाई ocr.title=OCR / स्कैन सफाई
ocr.header=स्कैन सफाई / OCR (ऑप्टिकल कैरेक्टर रिकग्निशन) ocr.header=स्कैन सफाई / OCR (ऑप्टिकल कैरेक्टर रिकग्निशन)
@ -775,8 +775,8 @@ imageToPDF.selectText.2=पीडीएफ को ऑटो रोटेट क
imageToPDF.selectText.3=मल्टी फ़ाइल तर्क (केवल यदि कई छवियों के साथ काम किया जा रहा है) imageToPDF.selectText.3=मल्टी फ़ाइल तर्क (केवल यदि कई छवियों के साथ काम किया जा रहा है)
imageToPDF.selectText.4=एक ही पीडीएफ में मर्ज करें imageToPDF.selectText.4=एक ही पीडीएफ में मर्ज करें
imageToPDF.selectText.5=अलग-अलग पीडीएफ में परिवर्तित करें imageToPDF.selectText.5=अलग-अलग पीडीएफ में परिवर्तित करें
#pdfToImage #pdfToImage
pdfToImage.title=पीडीएफ से छवि pdfToImage.title=पीडीएफ से छवि
pdfToImage.header=पीडीएफ से छवि pdfToImage.header=पीडीएफ से छवि

View File

@ -497,7 +497,7 @@ AddStampRequest.overrideY=Override Y Coordinate
AddStampRequest.customMargin=Custom Margin AddStampRequest.customMargin=Custom Margin
AddStampRequest.customColor=Custom Text Color AddStampRequest.customColor=Custom Text Color
AddStampRequest.submit=Submit AddStampRequest.submit=Submit
#sanitizePDF #sanitizePDF
sanitizePDF.title=PDF tisztítása sanitizePDF.title=PDF tisztítása
sanitizePDF.header=PDF fájl megtisztítása sanitizePDF.header=PDF fájl megtisztítása
@ -656,7 +656,7 @@ ScannerImageSplit.selectText.8=A fotók minimális kontúrterületének beállí
ScannerImageSplit.selectText.9=Keret mérete: ScannerImageSplit.selectText.9=Keret mérete:
ScannerImageSplit.selectText.10=A hozzáadott és eltávolított keret méretének beállítása a fehér keretek elkerülése érdekében a kimeneten (alapértelmezett: 1). ScannerImageSplit.selectText.10=A hozzáadott és eltávolított keret méretének beállítása a fehér keretek elkerülése érdekében a kimeneten (alapértelmezett: 1).
#OCR #OCR
ocr.title=OCR / szkennelés tisztázása ocr.title=OCR / szkennelés tisztázása
ocr.header=Szkennelés tisztázása / OCR (Optikai karakterfelismerés) ocr.header=Szkennelés tisztázása / OCR (Optikai karakterfelismerés)
@ -775,8 +775,8 @@ imageToPDF.selectText.2=Automatikus forgatás PDF
imageToPDF.selectText.3=Több fájl logika (csak akkor engedélyezett, ha több képpel dolgozik) imageToPDF.selectText.3=Több fájl logika (csak akkor engedélyezett, ha több képpel dolgozik)
imageToPDF.selectText.4=Egyesítse egyetlen PDF-fé imageToPDF.selectText.4=Egyesítse egyetlen PDF-fé
imageToPDF.selectText.5=Átalakítás különálló PDF-fé imageToPDF.selectText.5=Átalakítás különálló PDF-fé
#pdfToImage #pdfToImage
pdfToImage.title=PDF képpé alakítása pdfToImage.title=PDF képpé alakítása
pdfToImage.header=PDF képpé alakítása pdfToImage.header=PDF képpé alakítása

View File

@ -497,7 +497,7 @@ AddStampRequest.overrideY=Override Y Coordinate
AddStampRequest.customMargin=Custom Margin AddStampRequest.customMargin=Custom Margin
AddStampRequest.customColor=Custom Text Color AddStampRequest.customColor=Custom Text Color
AddStampRequest.submit=Submit AddStampRequest.submit=Submit
#sanitizePDF #sanitizePDF
sanitizePDF.title=Bersihkan PDF sanitizePDF.title=Bersihkan PDF
sanitizePDF.header=Membersihkan berkas PDF sanitizePDF.header=Membersihkan berkas PDF
@ -656,7 +656,7 @@ ScannerImageSplit.selectText.8=Menetapkan ambang batas area kontur minimum untuk
ScannerImageSplit.selectText.9=Ukuran Batas: ScannerImageSplit.selectText.9=Ukuran Batas:
ScannerImageSplit.selectText.10=Menetapkan ukuran batas yang ditambahkan dan dihapus untuk mencegah batas putih pada output (default: 1). ScannerImageSplit.selectText.10=Menetapkan ukuran batas yang ditambahkan dan dihapus untuk mencegah batas putih pada output (default: 1).
#OCR #OCR
ocr.title=OCR / Pembersihan Pindaian ocr.title=OCR / Pembersihan Pindaian
ocr.header=Pemindaian Pembersihan / OCR (Pengenalan Karakter Optik) ocr.header=Pemindaian Pembersihan / OCR (Pengenalan Karakter Optik)
@ -775,8 +775,8 @@ imageToPDF.selectText.2=Putar PDF secara otomatis
imageToPDF.selectText.3=Logika multi berkas (Hanya diaktifkan jika bekerja dengan banyak gambar) imageToPDF.selectText.3=Logika multi berkas (Hanya diaktifkan jika bekerja dengan banyak gambar)
imageToPDF.selectText.4=Gabungkan menjadi satu PDF imageToPDF.selectText.4=Gabungkan menjadi satu PDF
imageToPDF.selectText.5=Mengonversi ke PDF yang terpisah imageToPDF.selectText.5=Mengonversi ke PDF yang terpisah
#pdfToImage #pdfToImage
pdfToImage.title=PDF ke Gambar pdfToImage.title=PDF ke Gambar
pdfToImage.header=PDF ke Gambar pdfToImage.header=PDF ke Gambar

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -497,7 +497,7 @@ AddStampRequest.overrideY=Y coördinaat overschrijven
AddStampRequest.customMargin=Aangepaste marge AddStampRequest.customMargin=Aangepaste marge
AddStampRequest.customColor=Aangepaste tekstkleur AddStampRequest.customColor=Aangepaste tekstkleur
AddStampRequest.submit=Indienen AddStampRequest.submit=Indienen
#sanitizePDF #sanitizePDF
sanitizePDF.title=PDF opschonen sanitizePDF.title=PDF opschonen
sanitizePDF.header=Een PDF-bestand opschonen sanitizePDF.header=Een PDF-bestand opschonen
@ -519,7 +519,7 @@ addPageNumbers.selectText.4=Startnummer
addPageNumbers.selectText.5=Pagina's om te nummeren addPageNumbers.selectText.5=Pagina's om te nummeren
addPageNumbers.selectText.6=Aangepaste tekst addPageNumbers.selectText.6=Aangepaste tekst
addPageNumbers.customTextDesc=Aangepaste tekst addPageNumbers.customTextDesc=Aangepaste tekst
addPageNumbers.numberPagesDesc=Welke pagina's genummerd moeten worden, standaard 'all', accepteert ook 1-5 of 2,5,9 etc addPageNumbers.numberPagesDesc=Welke pagina's genummerd moeten worden, standaard 'all', accepteert ook 1-5 of 2,5,9 etc
addPageNumbers.customNumberDesc=Standaard {n}, accepteert ook 'Pagina {n} van {total}', 'Tekst-{n}', '{filename}-{n} addPageNumbers.customNumberDesc=Standaard {n}, accepteert ook 'Pagina {n} van {total}', 'Tekst-{n}', '{filename}-{n}
addPageNumbers.submit=Paginanummers toevoegen addPageNumbers.submit=Paginanummers toevoegen
@ -656,7 +656,7 @@ ScannerImageSplit.selectText.8=Stelt de minimale contour oppervlakte drempel in
ScannerImageSplit.selectText.9=Randgrootte: ScannerImageSplit.selectText.9=Randgrootte:
ScannerImageSplit.selectText.10=Stelt de grootte van de toegevoegde en verwijderde rand in om witte randen in de uitvoer te voorkomen (standaard: 1). ScannerImageSplit.selectText.10=Stelt de grootte van de toegevoegde en verwijderde rand in om witte randen in de uitvoer te voorkomen (standaard: 1).
#OCR #OCR
ocr.title=OCR / Scan opruimen ocr.title=OCR / Scan opruimen
ocr.header=Scans opruimen / OCR (Optical Character Recognition) ocr.header=Scans opruimen / OCR (Optical Character Recognition)
@ -775,8 +775,8 @@ imageToPDF.selectText.2=PDF automatisch draaien
imageToPDF.selectText.3=Meervoudige bestandslogica (Alleen ingeschakeld bij werken met meerdere afbeeldingen) imageToPDF.selectText.3=Meervoudige bestandslogica (Alleen ingeschakeld bij werken met meerdere afbeeldingen)
imageToPDF.selectText.4=Voeg samen in één PDF imageToPDF.selectText.4=Voeg samen in één PDF
imageToPDF.selectText.5=Zet om naar afzonderlijke PDF's imageToPDF.selectText.5=Zet om naar afzonderlijke PDF's
#pdfToImage #pdfToImage
pdfToImage.title=PDF naar afbeelding pdfToImage.title=PDF naar afbeelding
pdfToImage.header=PDF naar afbeelding pdfToImage.header=PDF naar afbeelding

File diff suppressed because it is too large Load Diff

View File

@ -497,7 +497,7 @@ AddStampRequest.overrideY=Override Y Coordinate
AddStampRequest.customMargin=Custom Margin AddStampRequest.customMargin=Custom Margin
AddStampRequest.customColor=Custom Text Color AddStampRequest.customColor=Custom Text Color
AddStampRequest.submit=Submit AddStampRequest.submit=Submit
#sanitizePDF #sanitizePDF
sanitizePDF.title=Sanitizar PDF sanitizePDF.title=Sanitizar PDF
sanitizePDF.header=Sanitizar um arquivo PDF sanitizePDF.header=Sanitizar um arquivo PDF
@ -656,7 +656,7 @@ ScannerImageSplit.selectText.8=Define o limite mínimo da área de contorno para
ScannerImageSplit.selectText.9=Tamanho da Borda: ScannerImageSplit.selectText.9=Tamanho da Borda:
ScannerImageSplit.selectText.10=Define o tamanho da borda adicionada e removida para evitar bordas brancas na saída (padrão: 1). ScannerImageSplit.selectText.10=Define o tamanho da borda adicionada e removida para evitar bordas brancas na saída (padrão: 1).
#OCR #OCR
ocr.title=OCR / Limpeza de Digitalização ocr.title=OCR / Limpeza de Digitalização
ocr.header=OCR / Limpeza de Digitalização (Reconhecimento Óptico de Caracteres) ocr.header=OCR / Limpeza de Digitalização (Reconhecimento Óptico de Caracteres)
@ -775,8 +775,8 @@ imageToPDF.selectText.2=Girar Automaticamente
imageToPDF.selectText.3=Lógica de Vários Arquivos (Ativada apenas ao trabalhar com várias imagens) imageToPDF.selectText.3=Lógica de Vários Arquivos (Ativada apenas ao trabalhar com várias imagens)
imageToPDF.selectText.4=Mesclar em um Único PDF imageToPDF.selectText.4=Mesclar em um Único PDF
imageToPDF.selectText.5=Converter em PDFs Separados imageToPDF.selectText.5=Converter em PDFs Separados
#pdfToImage #pdfToImage
pdfToImage.title=PDF para Imagem pdfToImage.title=PDF para Imagem
pdfToImage.header=Converter PDF para Imagem pdfToImage.header=Converter PDF para Imagem

View File

@ -497,7 +497,7 @@ AddStampRequest.overrideY=Override Y Coordinate
AddStampRequest.customMargin=Custom Margin AddStampRequest.customMargin=Custom Margin
AddStampRequest.customColor=Custom Text Color AddStampRequest.customColor=Custom Text Color
AddStampRequest.submit=Submit AddStampRequest.submit=Submit
#sanitizePDF #sanitizePDF
sanitizePDF.title=Sanitize PDF sanitizePDF.title=Sanitize PDF
sanitizePDF.header=Sanitize a PDF file sanitizePDF.header=Sanitize a PDF file
@ -656,7 +656,7 @@ ScannerImageSplit.selectText.8=Stabilește pragul minim de arie a conturului pen
ScannerImageSplit.selectText.9=Mărimea marginii: ScannerImageSplit.selectText.9=Mărimea marginii:
ScannerImageSplit.selectText.10=Stabilește mărimea marginii adăugate și eliminate pentru a evita marginile albe în rezultat (implicit: 1). ScannerImageSplit.selectText.10=Stabilește mărimea marginii adăugate și eliminate pentru a evita marginile albe în rezultat (implicit: 1).
#OCR #OCR
ocr.title=OCR / Curățare scanare ocr.title=OCR / Curățare scanare
ocr.header=Curățare scanări / OCR (Recunoaștere optică a caracterelor) ocr.header=Curățare scanări / OCR (Recunoaștere optică a caracterelor)
@ -775,8 +775,8 @@ imageToPDF.selectText.2=Rotire automată a PDF-ului
imageToPDF.selectText.3=Logica pentru mai multe fișiere (activată numai dacă se lucrează cu mai multe imagini) imageToPDF.selectText.3=Logica pentru mai multe fișiere (activată numai dacă se lucrează cu mai multe imagini)
imageToPDF.selectText.4=Unifică într-un singur PDF imageToPDF.selectText.4=Unifică într-un singur PDF
imageToPDF.selectText.5=Convertă în PDF-uri separate imageToPDF.selectText.5=Convertă în PDF-uri separate
#pdfToImage #pdfToImage
pdfToImage.title=PDF în Imagine pdfToImage.title=PDF în Imagine
pdfToImage.header=PDF în Imagine pdfToImage.header=PDF în Imagine

File diff suppressed because it is too large Load Diff

View File

@ -497,7 +497,7 @@ AddStampRequest.overrideY=Override Y Coordinate
AddStampRequest.customMargin=Custom Margin AddStampRequest.customMargin=Custom Margin
AddStampRequest.customColor=Custom Text Color AddStampRequest.customColor=Custom Text Color
AddStampRequest.submit=Submit AddStampRequest.submit=Submit
#sanitizePDF #sanitizePDF
sanitizePDF.title=Sanitizacija PDF-a sanitizePDF.title=Sanitizacija PDF-a
sanitizePDF.header=Sanitizacija PDF fajla sanitizePDF.header=Sanitizacija PDF fajla
@ -656,7 +656,7 @@ ScannerImageSplit.selectText.8=Postavlja minimalni prag površine konture za fot
ScannerImageSplit.selectText.9=Veličina ivice: ScannerImageSplit.selectText.9=Veličina ivice:
ScannerImageSplit.selectText.10=Postavlja veličinu ivice dodate i uklonjene kako bi se sprečile bele ivice u izlazu (podrazumevano: 1). ScannerImageSplit.selectText.10=Postavlja veličinu ivice dodate i uklonjene kako bi se sprečile bele ivice u izlazu (podrazumevano: 1).
#OCR #OCR
ocr.title=OCR / Čišćenje skeniranja ocr.title=OCR / Čišćenje skeniranja
ocr.header=Čišćenje skeniranja / OCR (Optičko prepoznavanje znakova) ocr.header=Čišćenje skeniranja / OCR (Optičko prepoznavanje znakova)
@ -775,8 +775,8 @@ imageToPDF.selectText.2=Automatsko rotiranje PDF-a
imageToPDF.selectText.3=Logika za više fajlova (Omogućeno samo ako radite sa više slika) imageToPDF.selectText.3=Logika za više fajlova (Omogućeno samo ako radite sa više slika)
imageToPDF.selectText.4=Spoji u jedan PDF imageToPDF.selectText.4=Spoji u jedan PDF
imageToPDF.selectText.5=Konvertuj u odvojene PDF-ove imageToPDF.selectText.5=Konvertuj u odvojene PDF-ove
#pdfToImage #pdfToImage
pdfToImage.title=PDF u sliku pdfToImage.title=PDF u sliku
pdfToImage.header=PDF u sliku pdfToImage.header=PDF u sliku

File diff suppressed because it is too large Load Diff

View File

@ -497,7 +497,7 @@ AddStampRequest.overrideY=Override Y Coordinate
AddStampRequest.customMargin=Custom Margin AddStampRequest.customMargin=Custom Margin
AddStampRequest.customColor=Custom Text Color AddStampRequest.customColor=Custom Text Color
AddStampRequest.submit=Submit AddStampRequest.submit=Submit
#sanitizePDF #sanitizePDF
sanitizePDF.title=PDF'i Temizle sanitizePDF.title=PDF'i Temizle
sanitizePDF.header=PDF dosyasını temizle sanitizePDF.header=PDF dosyasını temizle
@ -656,7 +656,7 @@ ScannerImageSplit.selectText.8=Bir fotoğraf için minimum kontur alanı eşiği
ScannerImageSplit.selectText.9=Kenar Boyutu: ScannerImageSplit.selectText.9=Kenar Boyutu:
ScannerImageSplit.selectText.10=Çıktıda beyaz kenarların önlenmesi için eklenen ve kaldırılan kenarın boyutunu ayarlar (varsayılan: 1). ScannerImageSplit.selectText.10=Çıktıda beyaz kenarların önlenmesi için eklenen ve kaldırılan kenarın boyutunu ayarlar (varsayılan: 1).
#OCR #OCR
ocr.title=OCR / Tarama Temizleme ocr.title=OCR / Tarama Temizleme
ocr.header=Taramaları Temizle / OCR (Optik Karakter Tanıma) ocr.header=Taramaları Temizle / OCR (Optik Karakter Tanıma)
@ -775,8 +775,8 @@ imageToPDF.selectText.2=PDF'yi otomatik döndür
imageToPDF.selectText.3=Çoklu dosya mantığı (Yalnızca birden fazla resimle çalışırken etkinleştirilir) imageToPDF.selectText.3=Çoklu dosya mantığı (Yalnızca birden fazla resimle çalışırken etkinleştirilir)
imageToPDF.selectText.4=Tek bir PDF'e birleştir imageToPDF.selectText.4=Tek bir PDF'e birleştir
imageToPDF.selectText.5=Ayrı PDF'lere dönüştür imageToPDF.selectText.5=Ayrı PDF'lere dönüştür
#pdfToImage #pdfToImage
pdfToImage.title=PDF'den Resme pdfToImage.title=PDF'den Resme
pdfToImage.header=PDF'den Resme pdfToImage.header=PDF'den Resme

File diff suppressed because it is too large Load Diff

View File

@ -497,7 +497,7 @@ AddStampRequest.overrideY=Override Y Coordinate
AddStampRequest.customMargin=Custom Margin AddStampRequest.customMargin=Custom Margin
AddStampRequest.customColor=Custom Text Color AddStampRequest.customColor=Custom Text Color
AddStampRequest.submit=Submit AddStampRequest.submit=Submit
#sanitizePDF #sanitizePDF
sanitizePDF.title=清理 PDF sanitizePDF.title=清理 PDF
sanitizePDF.header=清理 PDF 檔案 sanitizePDF.header=清理 PDF 檔案
@ -656,7 +656,7 @@ ScannerImageSplit.selectText.8=設定照片的最小輪廓區域閾值
ScannerImageSplit.selectText.9=邊框大小: ScannerImageSplit.selectText.9=邊框大小:
ScannerImageSplit.selectText.10=設定新增和移除的邊框大小以防止輸出中的白色邊框預設1 ScannerImageSplit.selectText.10=設定新增和移除的邊框大小以防止輸出中的白色邊框預設1
#OCR #OCR
ocr.title=OCR / 掃描清理 ocr.title=OCR / 掃描清理
ocr.header=清理掃描 / OCR光學字元識別 ocr.header=清理掃描 / OCR光學字元識別
@ -775,8 +775,8 @@ imageToPDF.selectText.2=自動旋轉 PDF
imageToPDF.selectText.3=多文件邏輯(僅在處理多個影像時啟用) imageToPDF.selectText.3=多文件邏輯(僅在處理多個影像時啟用)
imageToPDF.selectText.4=合併為單一 PDF imageToPDF.selectText.4=合併為單一 PDF
imageToPDF.selectText.5=轉換為單獨的 PDF imageToPDF.selectText.5=轉換為單獨的 PDF
#pdfToImage #pdfToImage
pdfToImage.title=PDF 轉圖片 pdfToImage.title=PDF 轉圖片
pdfToImage.header=PDF 轉圖片 pdfToImage.header=PDF 轉圖片

View File

@ -7,15 +7,15 @@ security:
csrfDisabled: true csrfDisabled: true
loginAttemptCount: 5 # lock user account after 5 tries loginAttemptCount: 5 # lock user account after 5 tries
loginResetTimeMinutes : 120 # lock account for 2 hours after x attempts loginResetTimeMinutes : 120 # lock account for 2 hours after x attempts
system: system:
defaultLocale: 'en-US' # Set the default language (e.g. 'de-DE', 'fr-FR', etc) defaultLocale: 'en-US' # Set the default language (e.g. 'de-DE', 'fr-FR', etc)
googlevisibility: false # 'true' to allow Google visibility (via robots.txt), 'false' to disallow googlevisibility: false # 'true' to allow Google visibility (via robots.txt), 'false' to disallow
enableAlphaFunctionality: false # Set to enable functionality which might need more testing before it fully goes live (This feature might make no changes) enableAlphaFunctionality: false # Set to enable functionality which might need more testing before it fully goes live (This feature might make no changes)
customApplications: customApplications:
bookAndHtmlFormatsInstalled: false # Installs Calibre for book format conversion (For non docker it must be manually downloaded but will need to be true to show in UI) bookAndHtmlFormatsInstalled: false # Installs Calibre for book format conversion (For non docker it must be manually downloaded but will need to be true to show in UI)
#ui: #ui:
# appName: exampleAppName # Application's visible name # appName: exampleAppName # Application's visible name
# homeDescription: I am a description # Short description or tagline shown on homepage. # homeDescription: I am a description # Short description or tagline shown on homepage.

View File

@ -1,135 +1,135 @@
/* Dark Mode Styles */ /* Dark Mode Styles */
body, select, textarea { body, select, textarea {
--body-background-color: 51, 51, 51; --body-background-color: 51, 51, 51;
--base-font-color: 255, 255, 255; --base-font-color: 255, 255, 255;
background-color: rgb(var(--body-background-color)) !important; background-color: rgb(var(--body-background-color)) !important;
color: rgb(var(--base-font-color)) !important; color: rgb(var(--base-font-color)) !important;
} }
.card { .card {
background-color: rgb(var(--body-background-color)) !important; background-color: rgb(var(--body-background-color)) !important;
border: 1px solid #999; border: 1px solid #999;
color: rgb(var(--base-font-color)) !important; color: rgb(var(--base-font-color)) !important;
} }
a { a {
color: #add8e6; color: #add8e6;
} }
a:hover { a:hover {
color: #87ceeb; /* Slightly brighter blue on hover for accessibility */ color: #87ceeb; /* Slightly brighter blue on hover for accessibility */
} }
.dark-card { .dark-card {
background-color: rgb(var(--body-background-color)) !important; background-color: rgb(var(--body-background-color)) !important;
color: rgb(var(--base-font-color)) !important; color: rgb(var(--base-font-color)) !important;
} }
.jumbotron { .jumbotron {
background-color: #222; /* or any other dark color */ background-color: #222; /* or any other dark color */
color: rgb(var(--base-font-color)) !important; /* or any other light color */ color: rgb(var(--base-font-color)) !important; /* or any other light color */
} }
.list-group { .list-group {
background-color: #222 !important; background-color: #222 !important;
color: rgb(var(--base-font-color)) !important; color: rgb(var(--base-font-color)) !important;
} }
.list-group-item { .list-group-item {
background-color: #222 !important; background-color: #222 !important;
color: rgb(var(--base-font-color)) !important; color: rgb(var(--base-font-color)) !important;
} }
#support-section { #support-section {
background-color: #444 !important; background-color: #444 !important;
} }
#pages-container-wrapper { #pages-container-wrapper {
--background-color: rgba(255, 255, 255, 0.046) !important; --background-color: rgba(255, 255, 255, 0.046) !important;
--scroll-bar-color: #4c4c4c !important; --scroll-bar-color: #4c4c4c !important;
--scroll-bar-thumb: #d3d3d3 !important; --scroll-bar-thumb: #d3d3d3 !important;
--scroll-bar-thumb-hover: rgb(var(--base-font-color)) !important; --scroll-bar-thumb-hover: rgb(var(--base-font-color)) !important;
} }
.favorite-icon img { .favorite-icon img {
filter: brightness(0) invert(1) !important; filter: brightness(0) invert(1) !important;
} }
table thead { table thead {
background-color: #333 !important; background-color: #333 !important;
border: 1px solid #444; border: 1px solid #444;
} }
table th, table td { table th, table td {
border: 1px solid #444 !important; border: 1px solid #444 !important;
color: white; color: white;
} }
.btn { .btn {
background-color: #444 !important; background-color: #444 !important;
border: none; border: none;
color: #fff !important; color: #fff !important;
} }
.btn-primary { .btn-primary {
background-color: #007bff !important; background-color: #007bff !important;
border: none; border: none;
color: #fff !important; color: #fff !important;
} }
.btn-secondary { .btn-secondary {
background-color: #6c757d !important; background-color: #6c757d !important;
border: none; border: none;
color: #fff !important; color: #fff !important;
} }
.btn-info { .btn-info {
background-color: #17a2b8 !important; background-color: #17a2b8 !important;
border: none; border: none;
color: #fff !important; color: #fff !important;
} }
.btn-danger { .btn-danger {
background-color: #dc3545 !important; background-color: #dc3545 !important;
border: none; border: none;
color: #fff !important; color: #fff !important;
} }
.btn-warning { .btn-warning {
background-color: #ffc107 !important; background-color: #ffc107 !important;
border: none; border: none;
color: #000 !important; color: #000 !important;
} }
.btn-outline-secondary { .btn-outline-secondary {
color: #fff !important; color: #fff !important;
border-color: #fff; border-color: #fff;
} }
.btn-outline-secondary:hover { .btn-outline-secondary:hover {
background-color: #444 !important; background-color: #444 !important;
color: #007bff !important; color: #007bff !important;
border-color: #007bff; border-color: #007bff;
} }
.blackwhite-icon { .blackwhite-icon {
filter: brightness(0) invert(1); filter: brightness(0) invert(1);
} }
hr { hr {
border-color: rgba(255, 255, 255, 0.6); /* semi-transparent white */ border-color: rgba(255, 255, 255, 0.6); /* semi-transparent white */
background-color: rgba(255, 255, 255, 0.6); /* for some browsers that might use background instead of border for <hr> */ background-color: rgba(255, 255, 255, 0.6); /* for some browsers that might use background instead of border for <hr> */
} }
.modal-content { .modal-content {
color: #fff !important; color: #fff !important;
border-color: #fff; border-color: #fff;
} }
#global-buttons-container input { #global-buttons-container input {
background-color: #323948; background-color: #323948;
caret-color: #ffffff; caret-color: #ffffff;
color: #ffffff; color: #ffffff;
} }
#global-buttons-container input::placeholder { #global-buttons-container input::placeholder {
color: #ffffff; color: #ffffff;
} }
#global-buttons-container input:disabled::-webkit-input-placeholder { /* WebKit browsers */ #global-buttons-container input:disabled::-webkit-input-placeholder { /* WebKit browsers */
color: #6E6865; color: #6E6865;
} }
#global-buttons-container input:disabled:-moz-placeholder { /* Mozilla Firefox 4 to 18 */ #global-buttons-container input:disabled:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
color: #6E6865; color: #6E6865;
} }
#global-buttons-container input:disabled::-moz-placeholder { /* Mozilla Firefox 19+ */ #global-buttons-container input:disabled::-moz-placeholder { /* Mozilla Firefox 19+ */
color: #6E6865; color: #6E6865;
} }
#global-buttons-container input:disabled:-ms-input-placeholder { /* Internet Explorer 10+ */ #global-buttons-container input:disabled:-ms-input-placeholder { /* Internet Explorer 10+ */
color: #6E6865; color: #6E6865;
} }

View File

@ -1,94 +1,94 @@
#page-container { #page-container {
min-height: 100vh; min-height: 100vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
#content-wrap { #content-wrap {
flex: 1; flex: 1;
} }
#footer { #footer {
bottom: 0; bottom: 0;
width: 100%; width: 100%;
} }
.navbar { .navbar {
height: auto; /* Adjusts height automatically based on content */ height: auto; /* Adjusts height automatically based on content */
white-space: nowrap; /* Prevents wrapping of navbar contents */ white-space: nowrap; /* Prevents wrapping of navbar contents */
} }
/* TODO enable later /* TODO enable later
.navbar .container { .navbar .container {
max-width: 100%; //Allows the container to expand up to full width max-width: 100%; //Allows the container to expand up to full width
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
}*/ }*/
html[lang-direction=ltr] * { html[lang-direction=ltr] * {
direction: ltr; direction: ltr;
} }
html[lang-direction=rtl] * { html[lang-direction=rtl] * {
direction: rtl; direction: rtl;
text-align: right; text-align: right;
} }
.ignore-rtl { .ignore-rtl {
direction: ltr !important; direction: ltr !important;
text-align: left !important; text-align: left !important;
} }
.align-top { .align-top {
position: absolute; position: absolute;
top: 0; top: 0;
} }
.align-center-right { .align-center-right {
position: absolute; position: absolute;
right: 0; right: 0;
top: 50%; top: 50%;
} }
.align-center-left { .align-center-left {
position: absolute; position: absolute;
left: 0; left: 0;
top: 50%; top: 50%;
} }
.align-bottom { .align-bottom {
position: absolute; position: absolute;
bottom: 0; bottom: 0;
} }
.btn-group > label:first-of-type { .btn-group > label:first-of-type {
border-top-left-radius: 0.25rem !important; border-top-left-radius: 0.25rem !important;
border-bottom-left-radius: 0.25rem !important; border-bottom-left-radius: 0.25rem !important;
} }
html[lang-direction="rtl"] input.form-check-input { html[lang-direction="rtl"] input.form-check-input {
position: relative; position: relative;
margin-left: 0px; margin-left: 0px;
} }
html[lang-direction="rtl"] label.form-check-label { html[lang-direction="rtl"] label.form-check-label {
display: inline; display: inline;
} }
.margin-auto-parent { .margin-auto-parent {
width: 100%; width: 100%;
display: flex; display: flex;
} }
.margin-center { .margin-center {
margin: 0 auto; margin: 0 auto;
} }
#pdf-canvas { #pdf-canvas {
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384); box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
width: 100%; width: 100%;
} }
.fixed-shadow-canvas { .fixed-shadow-canvas {
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384); box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
width: 100%; width: 100%;
} }
.shadow-canvas { .shadow-canvas {
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384); box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
} }
.hidden { .hidden {
display: none; display: none;
} }

View File

@ -1,29 +1,29 @@
.list-group-item { .list-group-item {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
} }
.filename { .filename {
flex-grow: 1; flex-grow: 1;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
margin-right: 10px; margin-right: 10px;
} }
.arrows { .arrows {
flex-shrink: 0; flex-shrink: 0;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
} }
.arrows .btn { .arrows .btn {
margin: 0 3px; margin: 0 3px;
} }
.move-up span, .move-up span,
.move-down span { .move-down span {
font-weight: bold; font-weight: bold;
font-size: 1.2em; font-size: 1.2em;
} }

View File

@ -32,7 +32,7 @@
translate: 0 -50%; translate: 0 -50%;
width: 80px; width: 80px;
height: 100%; height: 100%;
z-index: 1; z-index: 1;
opacity: 0; opacity: 0;
transition: opacity 0.2s; transition: opacity 0.2s;

View File

@ -34,4 +34,4 @@ body {
--scroll-bar-thumb: #d3d3d3 !important; --scroll-bar-thumb: #d3d3d3 !important;
--scroll-bar-thumb-hover: #ffffff !important; --scroll-bar-thumb-hover: #ffffff !important;
} }

View File

@ -16,7 +16,7 @@
background: 0 0; background: 0 0;
border: 1px solid transparent; border: 1px solid transparent;
color: rgb(var(--base-font-color)); color: rgb(var(--base-font-color));
border-top-left-radius: 0.25rem; border-top-left-radius: 0.25rem;
border-top-right-radius: 0.25rem; border-top-right-radius: 0.25rem;
} }

View File

@ -19,8 +19,8 @@
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs173"> id="defs173">
<linearGradient <linearGradient
id="XMLID_5_" id="XMLID_5_"
gradientUnits="userSpaceOnUse" gradientUnits="userSpaceOnUse"
@ -37,7 +37,7 @@
style="stop-color:#C2C2C9" style="stop-color:#C2C2C9"
id="stop158" /> id="stop158" />
</linearGradient> </linearGradient>
</defs><sodipodi:namedview </defs><sodipodi:namedview
id="namedview171" id="namedview171"
pagecolor="#ffffff" pagecolor="#ffffff"

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1235" height="650" viewBox="0 0 7410 3900"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1235" height="650" viewBox="0 0 7410 3900">
<rect width="7410" height="3900" fill="#b22234"/> <rect width="7410" height="3900" fill="#b22234"/>
<path d="M0,450H7410m0,600H0m0,600H7410m0,600H0m0,600H7410m0,600H0" stroke="#fff" stroke-width="300"/> <path d="M0,450H7410m0,600H0m0,600H7410m0,600H0m0,600H7410m0,600H0" stroke="#fff" stroke-width="300"/>
<rect width="2964" height="2100" fill="#3c3b6e"/> <rect width="2964" height="2100" fill="#3c3b6e"/>
<g fill="#fff"> <g fill="#fff">
<g id="s18"> <g id="s18">
<g id="s9"> <g id="s9">
<g id="s5"> <g id="s5">
<g id="s4"> <g id="s4">
<path id="s" d="M247,90 317.534230,307.082039 132.873218,172.917961H361.126782L176.465770,307.082039z"/> <path id="s" d="M247,90 317.534230,307.082039 132.873218,172.917961H361.126782L176.465770,307.082039z"/>
<use xlink:href="#s" y="420"/> <use xlink:href="#s" y="420"/>
<use xlink:href="#s" y="840"/> <use xlink:href="#s" y="840"/>
<use xlink:href="#s" y="1260"/> <use xlink:href="#s" y="1260"/>
</g> </g>
<use xlink:href="#s" y="1680"/> <use xlink:href="#s" y="1680"/>
</g> </g>
<use xlink:href="#s4" x="247" y="210"/> <use xlink:href="#s4" x="247" y="210"/>
</g> </g>
<use xlink:href="#s9" x="494"/> <use xlink:href="#s9" x="494"/>
</g> </g>
<use xlink:href="#s18" x="988"/> <use xlink:href="#s18" x="988"/>
<use xlink:href="#s9" x="1976"/> <use xlink:href="#s9" x="1976"/>
<use xlink:href="#s5" x="2470"/> <use xlink:href="#s5" x="2470"/>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 899 B

After

Width:  |  Height:  |  Size: 874 B

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> <!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="35px" height="35px" viewBox="0 -0.5 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <svg width="35px" height="35px" viewBox="0 -0.5 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Github-color</title> <title>Github-color</title>
<desc>Created with Sketch.</desc> <desc>Created with Sketch.</desc>
<defs> <defs>

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> <!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg version="1.1" id="Icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" <svg version="1.1" id="Icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 32 32" xml:space="preserve"> viewBox="0 0 32 32" xml:space="preserve">
<style type="text/css"> <style type="text/css">
.st0{fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;} .st0{fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}

Before

Width:  |  Height:  |  Size: 691 B

After

Width:  |  Height:  |  Size: 690 B

View File

@ -5,16 +5,16 @@ function showErrorBanner(message, stackTrace) {
document.querySelector("#errorContainer p").textContent = message; document.querySelector("#errorContainer p").textContent = message;
document.querySelector("#traceContent").textContent = stackTrace; document.querySelector("#traceContent").textContent = stackTrace;
} }
let firstErrorOccurred = false; let firstErrorOccurred = false;
$(document).ready(function() { $(document).ready(function() {
$('form').submit(async function(event) { $('form').submit(async function(event) {
event.preventDefault(); event.preventDefault();
firstErrorOccurred = false; firstErrorOccurred = false;
const url = this.action; const url = this.action;
const files = $('#fileInput-input')[0].files; const files = $('#fileInput-input')[0].files;
const formData = new FormData(this); const formData = new FormData(this);
// Remove empty file entries // Remove empty file entries
for (let [key, value] of formData.entries()) { for (let [key, value] of formData.entries()) {
if (value instanceof File && !value.name) { if (value instanceof File && !value.name) {
@ -113,7 +113,7 @@ async function handleResponse(blob, filename, considerViewOptions = false, isZip
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
window.open(url, '_blank'); window.open(url, '_blank');
return; return;
} }
} }
if(!isZip){ if(!isZip){
downloadFile(blob, filename); downloadFile(blob, filename);
@ -152,20 +152,20 @@ async function submitMultiPdfForm(url, files) {
// Show the progress bar // Show the progress bar
$('#progressBarContainer').show(); $('#progressBarContainer').show();
// Initialize the progress bar // Initialize the progress bar
let progressBar = $('#progressBar'); let progressBar = $('#progressBar');
progressBar.css('width', '0%'); progressBar.css('width', '0%');
progressBar.attr('aria-valuenow', 0); progressBar.attr('aria-valuenow', 0);
progressBar.attr('aria-valuemax', files.length); progressBar.attr('aria-valuemax', files.length);
if (zipFiles) { if (zipFiles) {
jszip = new JSZip(); jszip = new JSZip();
} }
// Get the form with the method attribute set to POST // Get the form with the method attribute set to POST
let postForm = document.querySelector('form[method="POST"]'); let postForm = document.querySelector('form[method="POST"]');
// Get existing form data // Get existing form data
let formData; let formData;
if (postForm) { if (postForm) {
@ -191,11 +191,11 @@ async function submitMultiPdfForm(url, files) {
const promises = chunk.map(async file => { const promises = chunk.map(async file => {
let fileFormData = new FormData(); let fileFormData = new FormData();
fileFormData.append('fileInput', file); fileFormData.append('fileInput', file);
console.log(fileFormData); console.log(fileFormData);
// Add other form data // Add other form data
for (let pair of formData.entries()) { for (let pair of formData.entries()) {
fileFormData.append(pair[0], pair[1]); fileFormData.append(pair[0], pair[1]);
console.log(pair[0]+ ', ' + pair[1]); console.log(pair[0]+ ', ' + pair[1]);
} }
try { try {
@ -213,7 +213,7 @@ async function submitMultiPdfForm(url, files) {
} }
}); });
await Promise.all(promises); await Promise.all(promises);
} }
if (zipFiles) { if (zipFiles) {

View File

@ -120,7 +120,7 @@ const DraggableUtils = {
newWidth = newWidth * scaleMultiplier; newWidth = newWidth * scaleMultiplier;
newHeight = newHeight * scaleMultiplier; newHeight = newHeight * scaleMultiplier;
} }
createdCanvas.style.width = newWidth+"px"; createdCanvas.style.width = newWidth+"px";
createdCanvas.style.height = newHeight+"px"; createdCanvas.style.height = newHeight+"px";
@ -147,7 +147,7 @@ const DraggableUtils = {
if (!pagesMap) { if (!pagesMap) {
pagesMap = {}; pagesMap = {};
} }
const elements = [...this.boxDragContainer.querySelectorAll(".draggable-canvas")]; const elements = [...this.boxDragContainer.querySelectorAll(".draggable-canvas")];
const draggablesData = elements.map(el => {return{element:el, offsetWidth:el.offsetWidth, offsetHeight:el.offsetHeight}}); const draggablesData = elements.map(el => {return{element:el, offsetWidth:el.offsetWidth, offsetHeight:el.offsetHeight}});
elements.forEach(el => this.boxDragContainer.removeChild(el)); elements.forEach(el => this.boxDragContainer.removeChild(el));
@ -164,7 +164,7 @@ const DraggableUtils = {
if (!pagesMap) { if (!pagesMap) {
return; return;
} }
const draggablesData = pagesMap[this.pageIndex]; const draggablesData = pagesMap[this.pageIndex];
if (draggablesData) { if (draggablesData) {
draggablesData.forEach(draggableData => this.boxDragContainer.appendChild(draggableData.element)); draggablesData.forEach(draggableData => this.boxDragContainer.appendChild(draggableData.element));
@ -177,7 +177,7 @@ const DraggableUtils = {
this.pdfDoc = pdfDocument ? pdfDocument : this.pdfDoc; this.pdfDoc = pdfDocument ? pdfDocument : this.pdfDoc;
this.pageIndex = pageIdx; this.pageIndex = pageIdx;
// persist // persist
const page = await this.pdfDoc.getPage(this.pageIndex+1); const page = await this.pdfDoc.getPage(this.pageIndex+1);
// set the canvas size to the size of the page // set the canvas size to the size of the page
@ -214,7 +214,7 @@ const DraggableUtils = {
}, },
parseTransform(element) { parseTransform(element) {
}, },
async getOverlayedPdfDocument() { async getOverlayedPdfDocument() {
const pdfBytes = await this.pdfDoc.getData(); const pdfBytes = await this.pdfDoc.getData();
@ -227,7 +227,7 @@ const DraggableUtils = {
continue; continue;
} }
console.log(typeof pageIdx); console.log(typeof pageIdx);
const page = pdfDocModified.getPage(parseInt(pageIdx)); const page = pdfDocModified.getPage(parseInt(pageIdx));
const draggablesData = pagesMap[pageIdx]; const draggablesData = pagesMap[pageIdx];
const offsetWidth = pagesMap[pageIdx+"-offsetWidth"]; const offsetWidth = pagesMap[pageIdx+"-offsetWidth"];
@ -239,7 +239,7 @@ const DraggableUtils = {
const response = await fetch(draggableElement.toDataURL()); const response = await fetch(draggableElement.toDataURL());
const draggableImgBytes = await response.arrayBuffer(); const draggableImgBytes = await response.arrayBuffer();
const pdfImageObject = await pdfDocModified.embedPng(draggableImgBytes); const pdfImageObject = await pdfDocModified.embedPng(draggableImgBytes);
// calculate the position in the pdf document // calculate the position in the pdf document
const tansform = draggableElement.style.transform.replace(/[^.,-\d]/g, ''); const tansform = draggableElement.style.transform.replace(/[^.,-\d]/g, '');
const transformComponents = tansform.split(","); const transformComponents = tansform.split(",");
@ -261,7 +261,7 @@ const DraggableUtils = {
width: draggablePositionRelative.width * page.getWidth(), width: draggablePositionRelative.width * page.getWidth(),
height: draggablePositionRelative.height * page.getHeight(), height: draggablePositionRelative.height * page.getHeight(),
} }
// draw the image // draw the image
page.drawImage(pdfImageObject, { page.drawImage(pdfImageObject, {
x: draggablePositionPdf.x, x: draggablePositionPdf.x,

View File

@ -1,6 +1,6 @@
function updateFavoritesDropdown() { function updateFavoritesDropdown() {
var dropdown = document.querySelector('#favoritesDropdown'); var dropdown = document.querySelector('#favoritesDropdown');
// Check if dropdown exists // Check if dropdown exists
if (!dropdown) { if (!dropdown) {
console.error('Dropdown element with ID "favoritesDropdown" not found!'); console.error('Dropdown element with ID "favoritesDropdown" not found!');

View File

@ -81,7 +81,7 @@ function setupFileInput(chooser) {
document.body.addEventListener('drop', dropListener); document.body.addEventListener('drop', dropListener);
$("#" + elementId).on("change", function(e) { $("#" + elementId).on("change", function(e) {
allFiles = Array.from(e.target.files); allFiles = Array.from(e.target.files);
handleFileInputChange(this); handleFileInputChange(this);
}); });

View File

@ -1,11 +1,11 @@
function initializeGame() { function initializeGame() {
const gameContainer = document.getElementById('game-container'); const gameContainer = document.getElementById('game-container');
const player = document.getElementById('player'); const player = document.getElementById('player');
let playerSize = gameContainer.clientWidth * 0.0625; // 5% of container width let playerSize = gameContainer.clientWidth * 0.0625; // 5% of container width
player.style.width = playerSize + 'px'; player.style.width = playerSize + 'px';
player.style.height = playerSize + 'px'; player.style.height = playerSize + 'px';
let playerX = gameContainer.clientWidth / 2 - playerSize / 2; let playerX = gameContainer.clientWidth / 2 - playerSize / 2;
let playerY = gameContainer.clientHeight * 0.1; let playerY = gameContainer.clientHeight * 0.1;
const scoreElement = document.getElementById('score'); const scoreElement = document.getElementById('score');
@ -18,12 +18,12 @@ function initializeGame() {
let projectileHeight = gameContainer.clientHeight * 0.01667; // 1% of container height let projectileHeight = gameContainer.clientHeight * 0.01667; // 1% of container height
let paused = false; let paused = false;
const fireRate = 200; // Time between shots in milliseconds const fireRate = 200; // Time between shots in milliseconds
let lastProjectileTime = 0; let lastProjectileTime = 0;
let lives = 3; let lives = 3;
let highScore = localStorage.getItem('highScore') ? parseInt(localStorage.getItem('highScore')) : 0; let highScore = localStorage.getItem('highScore') ? parseInt(localStorage.getItem('highScore')) : 0;
updateHighScore(); updateHighScore();
@ -195,7 +195,7 @@ function initializeGame() {
score = 0; score = 0;
level = 1; level = 1;
lives = 3; lives = 3;
gameOver = false; gameOver = false;
updateScore(); updateScore();

View File

@ -7,7 +7,7 @@ function filterCards() {
var card = cards[i]; var card = cards[i];
var title = card.querySelector('h5.card-title').innerText; var title = card.querySelector('h5.card-title').innerText;
var text = card.querySelector('p.card-text').innerText; var text = card.querySelector('p.card-text').innerText;
// Get the navbar tags associated with the card // Get the navbar tags associated with the card
var navbarItem = document.querySelector(`a.dropdown-item[href="${card.id}"]`); var navbarItem = document.querySelector(`a.dropdown-item[href="${card.id}"]`);
var navbarTags = navbarItem ? navbarItem.getAttribute('data-bs-tags') : ''; var navbarTags = navbarItem ? navbarItem.getAttribute('data-bs-tags') : '';

View File

@ -8,13 +8,13 @@ document.addEventListener('DOMContentLoaded', function() {
// Check if the dropdown contains the browser's language // Check if the dropdown contains the browser's language
const dropdownLangExists = document.querySelector(`.lang_dropdown-item[data-language-code="${browserLang}"]`); const dropdownLangExists = document.querySelector(`.lang_dropdown-item[data-language-code="${browserLang}"]`);
// Set the default language to browser's language or 'en_GB' if not found in the dropdown // Set the default language to browser's language or 'en_GB' if not found in the dropdown
const defaultLocale = dropdownLangExists ? browserLang : 'en_GB'; const defaultLocale = dropdownLangExists ? browserLang : 'en_GB';
const storedLocale = localStorage.getItem('languageCode') || defaultLocale; const storedLocale = localStorage.getItem('languageCode') || defaultLocale;
const dropdownItems = document.querySelectorAll('.lang_dropdown-item'); const dropdownItems = document.querySelectorAll('.lang_dropdown-item');
for (let i = 0; i < dropdownItems.length; i++) { for (let i = 0; i < dropdownItems.length; i++) {
@ -70,7 +70,7 @@ document.addEventListener('DOMContentLoaded', function() {
element.remove(); element.remove();
} }
}); });
//Sort languages by alphabet //Sort languages by alphabet
const list = Array.from(document.querySelector('.dropdown-menu[aria-labelledby="languageDropdown"]').children).filter(child => child.matches('a')); const list = Array.from(document.querySelector('.dropdown-menu[aria-labelledby="languageDropdown"]').children).filter(child => child.matches('a'));
list.sort(function(a, b) { list.sort(function(a, b) {

View File

@ -9,7 +9,7 @@ document.getElementById("fileInput-input").addEventListener("change", function()
}); });
/** /**
* @param {FileList} files * @param {FileList} files
*/ */
function displayFiles(files) { function displayFiles(files) {
const list = document.getElementById("selectedFiles"); const list = document.getElementById("selectedFiles");

View File

@ -73,7 +73,7 @@ class DragDropManager {
stopDraggingPage() { stopDraggingPage() {
window.removeEventListener('mousemove', this.onDragEl); window.removeEventListener('mousemove', this.onDragEl);
this.wrapper.classList.remove('drag-manager_dragging-container'); this.wrapper.classList.remove('drag-manager_dragging-container');
this.wrapper.removeChild(this.endInsertionElement); this.wrapper.removeChild(this.endInsertionElement);
window.removeEventListener('mouseup', this.stopDraggingPage) window.removeEventListener('mouseup', this.stopDraggingPage)
this.draggedImageEl = undefined; this.draggedImageEl = undefined;
this.pageDragging = false; this.pageDragging = false;

View File

@ -1,5 +1,5 @@
class PdfActionsManager { class PdfActionsManager {
pageDirection; pageDirection;
pagesContainer; pagesContainer;
constructor(id) { constructor(id) {
@ -23,7 +23,7 @@ class PdfActionsManager {
moveUpButtonCallback(e) { moveUpButtonCallback(e) {
var imgContainer = this.getPageContainer(e.target); var imgContainer = this.getPageContainer(e.target);
const sibling = imgContainer.previousSibling; const sibling = imgContainer.previousSibling;
if (sibling) { if (sibling) {
this.movePageTo(imgContainer, sibling, true); this.movePageTo(imgContainer, sibling, true);
@ -41,14 +41,14 @@ class PdfActionsManager {
rotateCCWButtonCallback(e) { rotateCCWButtonCallback(e) {
var imgContainer = this.getPageContainer(e.target); var imgContainer = this.getPageContainer(e.target);
const img = imgContainer.querySelector("img"); const img = imgContainer.querySelector("img");
this.rotateElement(img, -90) this.rotateElement(img, -90)
}; };
rotateCWButtonCallback(e) { rotateCWButtonCallback(e) {
var imgContainer = this.getPageContainer(e.target); var imgContainer = this.getPageContainer(e.target);
const img = imgContainer.querySelector("img"); const img = imgContainer.querySelector("img");
this.rotateElement(img, 90) this.rotateElement(img, 90)
}; };
@ -93,7 +93,7 @@ class PdfActionsManager {
const buttonContainer = document.createElement('div'); const buttonContainer = document.createElement('div');
buttonContainer.classList.add("pdf-actions_button-container", "hide-on-drag"); buttonContainer.classList.add("pdf-actions_button-container", "hide-on-drag");
const moveUp = document.createElement('button'); const moveUp = document.createElement('button');
moveUp.classList.add("pdf-actions_move-left-button","btn", "btn-secondary"); moveUp.classList.add("pdf-actions_move-left-button","btn", "btn-secondary");
moveUp.innerHTML = `<i class="bi bi-arrow-${leftDirection}-short"></i>`; moveUp.innerHTML = `<i class="bi bi-arrow-${leftDirection}-short"></i>`;
@ -105,7 +105,7 @@ class PdfActionsManager {
moveDown.innerHTML = `<i class="bi bi-arrow-${rightDirection}-short"></i>`; moveDown.innerHTML = `<i class="bi bi-arrow-${rightDirection}-short"></i>`;
moveDown.onclick = this.moveDownButtonCallback; moveDown.onclick = this.moveDownButtonCallback;
buttonContainer.appendChild(moveDown); buttonContainer.appendChild(moveDown);
const rotateCCW = document.createElement('button'); const rotateCCW = document.createElement('button');
rotateCCW.classList.add("btn", "btn-secondary"); rotateCCW.classList.add("btn", "btn-secondary");
rotateCCW.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16"> rotateCCW.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
@ -136,12 +136,12 @@ class PdfActionsManager {
div.appendChild(buttonContainer); div.appendChild(buttonContainer);
const insertFileButtonContainer = document.createElement('div'); const insertFileButtonContainer = document.createElement('div');
insertFileButtonContainer.classList.add( insertFileButtonContainer.classList.add(
"pdf-actions_insert-file-button-container", "pdf-actions_insert-file-button-container",
leftDirection, leftDirection,
`align-center-${leftDirection}`); `align-center-${leftDirection}`);
const insertFileButton = document.createElement('button'); const insertFileButton = document.createElement('button');
insertFileButton.classList.add("btn", "btn-primary", "pdf-actions_insert-file-button"); insertFileButton.classList.add("btn", "btn-primary", "pdf-actions_insert-file-button");
insertFileButton.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-earmark-plus" viewBox="0 0 16 16"> insertFileButton.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-earmark-plus" viewBox="0 0 16 16">
@ -150,16 +150,16 @@ class PdfActionsManager {
</svg>`; </svg>`;
insertFileButton.onclick = this.insertFileButtonCallback; insertFileButton.onclick = this.insertFileButtonCallback;
insertFileButtonContainer.appendChild(insertFileButton); insertFileButtonContainer.appendChild(insertFileButton);
div.appendChild(insertFileButtonContainer); div.appendChild(insertFileButtonContainer);
// add this button to every element, but only show it on the last one :D // add this button to every element, but only show it on the last one :D
const insertFileButtonRightContainer = document.createElement('div'); const insertFileButtonRightContainer = document.createElement('div');
insertFileButtonRightContainer.classList.add( insertFileButtonRightContainer.classList.add(
"pdf-actions_insert-file-button-container", "pdf-actions_insert-file-button-container",
rightDirection, rightDirection,
`align-center-${rightDirection}`); `align-center-${rightDirection}`);
const insertFileButtonRight = document.createElement('button'); const insertFileButtonRight = document.createElement('button');
insertFileButtonRight.classList.add("btn", "btn-primary", "pdf-actions_insert-file-button"); insertFileButtonRight.classList.add("btn", "btn-primary", "pdf-actions_insert-file-button");
insertFileButtonRight.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-earmark-plus" viewBox="0 0 16 16"> insertFileButtonRight.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-earmark-plus" viewBox="0 0 16 16">

View File

@ -1,285 +1,285 @@
class PdfContainer { class PdfContainer {
fileName; fileName;
pagesContainer; pagesContainer;
pagesContainerWrapper; pagesContainerWrapper;
pdfAdapters; pdfAdapters;
downloadLink; downloadLink;
constructor(id, wrapperId, pdfAdapters) { constructor(id, wrapperId, pdfAdapters) {
this.pagesContainer = document.getElementById(id) this.pagesContainer = document.getElementById(id)
this.pagesContainerWrapper = document.getElementById(wrapperId); this.pagesContainerWrapper = document.getElementById(wrapperId);
this.downloadLink = null; this.downloadLink = null;
this.movePageTo = this.movePageTo.bind(this); this.movePageTo = this.movePageTo.bind(this);
this.addPdfs = this.addPdfs.bind(this); this.addPdfs = this.addPdfs.bind(this);
this.addPdfsFromFiles = this.addPdfsFromFiles.bind(this); this.addPdfsFromFiles = this.addPdfsFromFiles.bind(this);
this.rotateElement = this.rotateElement.bind(this); this.rotateElement = this.rotateElement.bind(this);
this.rotateAll = this.rotateAll.bind(this); this.rotateAll = this.rotateAll.bind(this);
this.exportPdf = this.exportPdf.bind(this); this.exportPdf = this.exportPdf.bind(this);
this.updateFilename = this.updateFilename.bind(this); this.updateFilename = this.updateFilename.bind(this);
this.setDownloadAttribute = this.setDownloadAttribute.bind(this); this.setDownloadAttribute = this.setDownloadAttribute.bind(this);
this.preventIllegalChars = this.preventIllegalChars.bind(this); this.preventIllegalChars = this.preventIllegalChars.bind(this);
this.pdfAdapters = pdfAdapters; this.pdfAdapters = pdfAdapters;
this.pdfAdapters.forEach(adapter => { this.pdfAdapters.forEach(adapter => {
adapter.setActions({ adapter.setActions({
movePageTo: this.movePageTo, movePageTo: this.movePageTo,
addPdfs: this.addPdfs, addPdfs: this.addPdfs,
rotateElement: this.rotateElement, rotateElement: this.rotateElement,
updateFilename: this.updateFilename updateFilename: this.updateFilename
}) })
}) })
window.addPdfs = this.addPdfs; window.addPdfs = this.addPdfs;
window.exportPdf = this.exportPdf; window.exportPdf = this.exportPdf;
window.rotateAll = this.rotateAll; window.rotateAll = this.rotateAll;
const filenameInput = document.getElementById('filename-input'); const filenameInput = document.getElementById('filename-input');
const downloadBtn = document.getElementById('export-button'); const downloadBtn = document.getElementById('export-button');
filenameInput.onkeyup = this.updateFilename; filenameInput.onkeyup = this.updateFilename;
filenameInput.onkeydown = this.preventIllegalChars; filenameInput.onkeydown = this.preventIllegalChars;
filenameInput.disabled = false; filenameInput.disabled = false;
filenameInput.innerText = ""; filenameInput.innerText = "";
downloadBtn.disabled = true; downloadBtn.disabled = true;
} }
movePageTo(startElement, endElement, scrollTo = false) { movePageTo(startElement, endElement, scrollTo = false) {
const childArray = Array.from(this.pagesContainer.childNodes); const childArray = Array.from(this.pagesContainer.childNodes);
const startIndex = childArray.indexOf(startElement); const startIndex = childArray.indexOf(startElement);
const endIndex = childArray.indexOf(endElement); const endIndex = childArray.indexOf(endElement);
this.pagesContainer.removeChild(startElement); this.pagesContainer.removeChild(startElement);
if(!endElement) { if(!endElement) {
this.pagesContainer.append(startElement); this.pagesContainer.append(startElement);
} else { } else {
this.pagesContainer.insertBefore(startElement, endElement); this.pagesContainer.insertBefore(startElement, endElement);
} }
if(scrollTo) { if(scrollTo) {
const { width } = startElement.getBoundingClientRect(); const { width } = startElement.getBoundingClientRect();
const vector = (endIndex !== -1 && startIndex > endIndex) const vector = (endIndex !== -1 && startIndex > endIndex)
? 0-width ? 0-width
: width; : width;
this.pagesContainerWrapper.scroll({ this.pagesContainerWrapper.scroll({
left: this.pagesContainerWrapper.scrollLeft + vector, left: this.pagesContainerWrapper.scrollLeft + vector,
}) })
} }
} }
addPdfs(nextSiblingElement) { addPdfs(nextSiblingElement) {
var input = document.createElement('input'); var input = document.createElement('input');
input.type = 'file'; input.type = 'file';
input.multiple = true; input.multiple = true;
input.setAttribute("accept", "application/pdf"); input.setAttribute("accept", "application/pdf");
input.onchange = async(e) => { input.onchange = async(e) => {
const files = e.target.files; const files = e.target.files;
this.addPdfsFromFiles(files, nextSiblingElement); this.addPdfsFromFiles(files, nextSiblingElement);
this.updateFilename(files ? files[0].name : ""); this.updateFilename(files ? files[0].name : "");
} }
input.click(); input.click();
} }
async addPdfsFromFiles(files, nextSiblingElement) { async addPdfsFromFiles(files, nextSiblingElement) {
this.fileName = files[0].name; this.fileName = files[0].name;
for (var i=0; i < files.length; i++) { for (var i=0; i < files.length; i++) {
await this.addPdfFile(files[i], nextSiblingElement); await this.addPdfFile(files[i], nextSiblingElement);
} }
document.querySelectorAll(".enable-on-file").forEach(element => { document.querySelectorAll(".enable-on-file").forEach(element => {
element.disabled = false; element.disabled = false;
}); });
} }
rotateElement(element, deg) { rotateElement(element, deg) {
var lastTransform = element.style.rotate; var lastTransform = element.style.rotate;
if (!lastTransform) { if (!lastTransform) {
lastTransform = "0"; lastTransform = "0";
} }
const lastAngle = parseInt(lastTransform.replace(/[^\d-]/g, '')); const lastAngle = parseInt(lastTransform.replace(/[^\d-]/g, ''));
const newAngle = lastAngle + deg; const newAngle = lastAngle + deg;
element.style.rotate = newAngle + "deg"; element.style.rotate = newAngle + "deg";
} }
async addPdfFile(file, nextSiblingElement) { async addPdfFile(file, nextSiblingElement) {
const { renderer, pdfDocument } = await this.loadFile(file); const { renderer, pdfDocument } = await this.loadFile(file);
for (var i=0; i < renderer.pageCount; i++) { for (var i=0; i < renderer.pageCount; i++) {
const div = document.createElement('div'); const div = document.createElement('div');
div.classList.add("page-container"); div.classList.add("page-container");
var img = document.createElement('img'); var img = document.createElement('img');
img.classList.add('page-image') img.classList.add('page-image')
const imageSrc = await renderer.renderPage(i) const imageSrc = await renderer.renderPage(i)
img.src = imageSrc; img.src = imageSrc;
img.pageIdx = i; img.pageIdx = i;
img.rend = renderer; img.rend = renderer;
img.doc = pdfDocument; img.doc = pdfDocument;
div.appendChild(img); div.appendChild(img);
this.pdfAdapters.forEach((adapter) => { this.pdfAdapters.forEach((adapter) => {
adapter.adapt?.(div) adapter.adapt?.(div)
}) })
if (nextSiblingElement) { if (nextSiblingElement) {
this.pagesContainer.insertBefore(div, nextSiblingElement); this.pagesContainer.insertBefore(div, nextSiblingElement);
} else { } else {
this.pagesContainer.appendChild(div); this.pagesContainer.appendChild(div);
} }
} }
} }
async loadFile(file) { async loadFile(file) {
var objectUrl = URL.createObjectURL(file); var objectUrl = URL.createObjectURL(file);
var pdfDocument = await this.toPdfLib(objectUrl); var pdfDocument = await this.toPdfLib(objectUrl);
var renderer = await this.toRenderer(objectUrl); var renderer = await this.toRenderer(objectUrl);
return { renderer, pdfDocument }; return { renderer, pdfDocument };
} }
async toRenderer(objectUrl) { async toRenderer(objectUrl) {
pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdfjs/pdf.worker.js' pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdfjs/pdf.worker.js'
const pdf = await pdfjsLib.getDocument(objectUrl).promise; const pdf = await pdfjsLib.getDocument(objectUrl).promise;
return { return {
document: pdf, document: pdf,
pageCount: pdf.numPages, pageCount: pdf.numPages,
renderPage: async function(pageIdx) { renderPage: async function(pageIdx) {
const page = await this.document.getPage(pageIdx+1); const page = await this.document.getPage(pageIdx+1);
const canvas = document.createElement("canvas"); const canvas = document.createElement("canvas");
// set the canvas size to the size of the page // set the canvas size to the size of the page
if (page.rotate == 90 || page.rotate == 270) { if (page.rotate == 90 || page.rotate == 270) {
canvas.width = page.view[3]; canvas.width = page.view[3];
canvas.height = page.view[2]; canvas.height = page.view[2];
} else { } else {
canvas.width = page.view[2]; canvas.width = page.view[2];
canvas.height = page.view[3]; canvas.height = page.view[3];
} }
// render the page onto the canvas // render the page onto the canvas
var renderContext = { var renderContext = {
canvasContext: canvas.getContext("2d"), canvasContext: canvas.getContext("2d"),
viewport: page.getViewport({ scale: 1 }) viewport: page.getViewport({ scale: 1 })
}; };
await page.render(renderContext).promise; await page.render(renderContext).promise;
return canvas.toDataURL(); return canvas.toDataURL();
} }
}; };
} }
async toPdfLib(objectUrl) { async toPdfLib(objectUrl) {
const existingPdfBytes = await fetch(objectUrl).then(res => res.arrayBuffer()); const existingPdfBytes = await fetch(objectUrl).then(res => res.arrayBuffer());
const pdfDoc = await PDFLib.PDFDocument.load(existingPdfBytes, { ignoreEncryption: true }); const pdfDoc = await PDFLib.PDFDocument.load(existingPdfBytes, { ignoreEncryption: true });
return pdfDoc; return pdfDoc;
} }
rotateAll(deg) { rotateAll(deg) {
for (var i=0; i<this.pagesContainer.childNodes.length; i++) { for (var i=0; i<this.pagesContainer.childNodes.length; i++) {
const img = this.pagesContainer.childNodes[i].querySelector("img"); const img = this.pagesContainer.childNodes[i].querySelector("img");
if (!img) continue; if (!img) continue;
this.rotateElement(img, deg) this.rotateElement(img, deg)
} }
} }
async exportPdf() { async exportPdf() {
const pdfDoc = await PDFLib.PDFDocument.create(); const pdfDoc = await PDFLib.PDFDocument.create();
const pageContainers = this.pagesContainer.querySelectorAll('.page-container'); // Select all .page-container elements const pageContainers = this.pagesContainer.querySelectorAll('.page-container'); // Select all .page-container elements
for (var i = 0; i < pageContainers.length; i++) { for (var i = 0; i < pageContainers.length; i++) {
const img = pageContainers[i].querySelector("img"); // Find the img element within each .page-container const img = pageContainers[i].querySelector("img"); // Find the img element within each .page-container
if (!img) continue; if (!img) continue;
const pages = await pdfDoc.copyPages(img.doc, [img.pageIdx]) const pages = await pdfDoc.copyPages(img.doc, [img.pageIdx])
const page = pages[0]; const page = pages[0];
const rotation = img.style.rotate; const rotation = img.style.rotate;
if (rotation) { if (rotation) {
const rotationAngle = parseInt(rotation.replace(/[^\d-]/g, '')); const rotationAngle = parseInt(rotation.replace(/[^\d-]/g, ''));
page.setRotation(PDFLib.degrees(page.getRotation().angle + rotationAngle)) page.setRotation(PDFLib.degrees(page.getRotation().angle + rotationAngle))
} }
pdfDoc.addPage(page); pdfDoc.addPage(page);
} }
const pdfBytes = await pdfDoc.save(); const pdfBytes = await pdfDoc.save();
const pdfBlob = new Blob([pdfBytes], { type: 'application/pdf' }); const pdfBlob = new Blob([pdfBytes], { type: 'application/pdf' });
const url = URL.createObjectURL(pdfBlob); const url = URL.createObjectURL(pdfBlob);
const downloadOption = localStorage.getItem('downloadOption'); const downloadOption = localStorage.getItem('downloadOption');
const filenameInput = document.getElementById('filename-input'); const filenameInput = document.getElementById('filename-input');
let inputArr = filenameInput.value.split('.'); let inputArr = filenameInput.value.split('.');
if (inputArr !== null && inputArr !== undefined && inputArr.length > 0) { if (inputArr !== null && inputArr !== undefined && inputArr.length > 0) {
inputArr = inputArr.filter(n => n); // remove all empty strings, nulls or undefined inputArr = inputArr.filter(n => n); // remove all empty strings, nulls or undefined
if (inputArr.length > 1) { if (inputArr.length > 1) {
inputArr.pop(); // remove right part after last dot inputArr.pop(); // remove right part after last dot
} }
filenameInput.value = inputArr.join(''); filenameInput.value = inputArr.join('');
this.fileName = filenameInput.value; this.fileName = filenameInput.value;
} }
if (!filenameInput.value.includes('.pdf')) { if (!filenameInput.value.includes('.pdf')) {
filenameInput.value = filenameInput.value + '.pdf'; filenameInput.value = filenameInput.value + '.pdf';
this.fileName = filenameInput.value; this.fileName = filenameInput.value;
} }
if (downloadOption === 'sameWindow') { if (downloadOption === 'sameWindow') {
// Open the file in the same window // Open the file in the same window
window.location.href = url; window.location.href = url;
} else if (downloadOption === 'newWindow') { } else if (downloadOption === 'newWindow') {
// Open the file in a new window // Open the file in a new window
window.open(url, '_blank'); window.open(url, '_blank');
} else { } else {
// Download the file // Download the file
this.downloadLink = document.createElement('a'); this.downloadLink = document.createElement('a');
this.downloadLink.id = 'download-link'; this.downloadLink.id = 'download-link';
this.downloadLink.href = url; this.downloadLink.href = url;
// downloadLink.download = this.fileName ? this.fileName : 'managed.pdf'; // downloadLink.download = this.fileName ? this.fileName : 'managed.pdf';
// downloadLink.download = this.fileName; // downloadLink.download = this.fileName;
this.downloadLink.setAttribute('download', this.fileName ? this.fileName : 'managed.pdf'); this.downloadLink.setAttribute('download', this.fileName ? this.fileName : 'managed.pdf');
this.downloadLink.setAttribute('target', '_blank'); this.downloadLink.setAttribute('target', '_blank');
this.downloadLink.onclick = this.setDownloadAttribute; this.downloadLink.onclick = this.setDownloadAttribute;
this.downloadLink.click(); this.downloadLink.click();
} }
} }
setDownloadAttribute() { setDownloadAttribute() {
this.downloadLink.setAttribute("download", this.fileName ? this.fileName : 'managed.pdf'); this.downloadLink.setAttribute("download", this.fileName ? this.fileName : 'managed.pdf');
} }
updateFilename(fileName = "") { updateFilename(fileName = "") {
const filenameInput = document.getElementById('filename-input'); const filenameInput = document.getElementById('filename-input');
const pagesContainer = document.getElementById('pages-container'); const pagesContainer = document.getElementById('pages-container');
const downloadBtn = document.getElementById('export-button'); const downloadBtn = document.getElementById('export-button');
downloadBtn.disabled = pagesContainer.childElementCount === 0 downloadBtn.disabled = pagesContainer.childElementCount === 0
if (!this.fileName) { if (!this.fileName) {
this.fileName = fileName; this.fileName = fileName;
} }
if (!filenameInput.value) { if (!filenameInput.value) {
filenameInput.value = this.fileName; filenameInput.value = this.fileName;
} }
} }
preventIllegalChars(e) { preventIllegalChars(e) {
// const filenameInput = document.getElementById('filename-input'); // const filenameInput = document.getElementById('filename-input');
// //
// filenameInput.value = filenameInput.value.replace('.pdf', ''); // filenameInput.value = filenameInput.value.replace('.pdf', '');
// //
// // prevent . // // prevent .
// if (filenameInput.value.includes('.')) { // if (filenameInput.value.includes('.')) {
// filenameInput.value.replace('.',''); // filenameInput.value.replace('.','');
// } // }
} }
} }
export default PdfContainer; export default PdfContainer;

View File

@ -17,7 +17,7 @@ const scrollDivHorizontally = (id) => {
} }
} }
divToScrollHorizontally.addEventListener("wheel", function(e) { divToScrollHorizontally.addEventListener("wheel", function(e) {
e.preventDefault(); // prevent default mousewheel behavior e.preventDefault(); // prevent default mousewheel behavior

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -6,7 +6,7 @@ TabContainer = {
unloadedGroups.forEach(group => { unloadedGroups.forEach(group => {
const containers = group.querySelectorAll(".tab-container"); const containers = group.querySelectorAll(".tab-container");
const tabTitles = [...containers].map(c => c.getAttribute("title")); const tabTitles = [...containers].map(c => c.getAttribute("title"));
const tabList = document.createElement("div"); const tabList = document.createElement("div");
tabList.classList.add("tab-buttons"); tabList.classList.add("tab-buttons");
tabTitles.forEach(title => { tabTitles.forEach(title => {

View File

@ -15,6 +15,6 @@
], ],
"start_url": "/", "start_url": "/",
"display": "standalone", "display": "standalone",
"background_color": "#ffffff", "background_color": "#ffffff",
"theme_color": "#000000" "theme_color": "#000000"
} }

View File

@ -1,3 +1,3 @@
àRCopyright 1990-2009 Adobe Systems Incorporated. àRCopyright 1990-2009 Adobe Systems Incorporated.
All rights reserved. All rights reserved.
See ./LICENSEáCNS2-H See ./LICENSEáCNS2-H

View File

@ -1,3 +1,3 @@
àRCopyright 1990-2009 Adobe Systems Incorporated. àRCopyright 1990-2009 Adobe Systems Incorporated.
All rights reserved. All rights reserved.
See ./LICENSEá ETen-B5-H` ^ See ./LICENSEá ETen-B5-H` ^

View File

@ -13,12 +13,12 @@
%%Copyright: Redistributions in binary form must reproduce the above %%Copyright: Redistributions in binary form must reproduce the above
%%Copyright: copyright notice, this list of conditions and the following %%Copyright: copyright notice, this list of conditions and the following
%%Copyright: disclaimer in the documentation and/or other materials %%Copyright: disclaimer in the documentation and/or other materials
%%Copyright: provided with the distribution. %%Copyright: provided with the distribution.
%%Copyright: %%Copyright:
%%Copyright: Neither the name of Adobe Systems Incorporated nor the names %%Copyright: Neither the name of Adobe Systems Incorporated nor the names
%%Copyright: of its contributors may be used to endorse or promote %%Copyright: of its contributors may be used to endorse or promote
%%Copyright: products derived from this software without specific prior %%Copyright: products derived from this software without specific prior
%%Copyright: written permission. %%Copyright: written permission.
%%Copyright: %%Copyright:
%%Copyright: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND %%Copyright: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
%%Copyright: CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, %%Copyright: CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,

View File

@ -1,4 +1,4 @@
<svg width="12" height="13" viewBox="0 0 12 13" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="12" height="13" viewBox="0 0 12 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.375 7.625V11.875C5.375 12.0408 5.44085 12.1997 5.55806 12.3169C5.67527 12.4342 5.83424 12.5 6 12.5C6.16576 12.5 6.32473 12.4342 6.44194 12.3169C6.55915 12.1997 6.625 12.0408 6.625 11.875V7.625L7.125 7.125H11.375C11.5408 7.125 11.6997 7.05915 11.8169 6.94194C11.9342 6.82473 12 6.66576 12 6.5C12 6.33424 11.9342 6.17527 11.8169 6.05806C11.6997 5.94085 11.5408 5.875 11.375 5.875H7.125L6.625 5.375V1.125C6.625 0.95924 6.55915 0.800269 6.44194 0.683058C6.32473 0.565848 6.16576 0.5 6 0.5C5.83424 0.5 5.67527 0.565848 5.55806 0.683058C5.44085 0.800269 5.375 0.95924 5.375 1.125V5.375L4.875 5.875H0.625C0.45924 5.875 0.300269 5.94085 0.183058 6.05806C0.065848 6.17527 0 6.33424 0 6.5C0 6.66576 0.065848 6.82473 0.183058 6.94194C0.300269 7.05915 0.45924 7.125 0.625 7.125H4.762L5.375 7.625Z" <path d="M5.375 7.625V11.875C5.375 12.0408 5.44085 12.1997 5.55806 12.3169C5.67527 12.4342 5.83424 12.5 6 12.5C6.16576 12.5 6.32473 12.4342 6.44194 12.3169C6.55915 12.1997 6.625 12.0408 6.625 11.875V7.625L7.125 7.125H11.375C11.5408 7.125 11.6997 7.05915 11.8169 6.94194C11.9342 6.82473 12 6.66576 12 6.5C12 6.33424 11.9342 6.17527 11.8169 6.05806C11.6997 5.94085 11.5408 5.875 11.375 5.875H7.125L6.625 5.375V1.125C6.625 0.95924 6.55915 0.800269 6.44194 0.683058C6.32473 0.565848 6.16576 0.5 6 0.5C5.83424 0.5 5.67527 0.565848 5.55806 0.683058C5.44085 0.800269 5.375 0.95924 5.375 1.125V5.375L4.875 5.875H0.625C0.45924 5.875 0.300269 5.94085 0.183058 6.05806C0.065848 6.17527 0 6.33424 0 6.5C0 6.66576 0.065848 6.82473 0.183058 6.94194C0.300269 7.05915 0.45924 7.125 0.625 7.125H4.762L5.375 7.625Z"
fill="black"/> fill="black"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 931 B

After

Width:  |  Height:  |  Size: 930 B

View File

@ -1,4 +1,4 @@
<svg width="12" height="13" viewBox="0 0 12 13" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="12" height="13" viewBox="0 0 12 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 0.5C5.21207 0.5 4.43185 0.655195 3.7039 0.956723C2.97595 1.25825 2.31451 1.70021 1.75736 2.25736C1.20021 2.81451 0.758251 3.47595 0.456723 4.2039C0.155195 4.93185 0 5.71207 0 6.5C0 7.28793 0.155195 8.06815 0.456723 8.7961C0.758251 9.52405 1.20021 10.1855 1.75736 10.7426C2.31451 11.2998 2.97595 11.7417 3.7039 12.0433C4.43185 12.3448 5.21207 12.5 6 12.5C7.5913 12.5 9.11742 11.8679 10.2426 10.7426C11.3679 9.61742 12 8.0913 12 6.5C12 4.9087 11.3679 3.38258 10.2426 2.25736C9.11742 1.13214 7.5913 0.5 6 0.5ZM5.06 8.9L2.9464 6.7856C2.85273 6.69171 2.80018 6.56446 2.80033 6.43183C2.80048 6.29921 2.85331 6.17207 2.9472 6.0784C3.04109 5.98473 3.16834 5.93218 3.30097 5.93233C3.43359 5.93248 3.56073 5.98531 3.6544 6.0792L5.3112 7.7368L8.3464 4.7008C8.44109 4.6109 8.56715 4.56153 8.69771 4.56322C8.82827 4.56492 8.95301 4.61754 9.04534 4.70986C9.13766 4.80219 9.19028 4.92693 9.19198 5.05749C9.19367 5.18805 9.1443 5.31411 9.0544 5.4088L5.5624 8.9H5.06Z" <path d="M6 0.5C5.21207 0.5 4.43185 0.655195 3.7039 0.956723C2.97595 1.25825 2.31451 1.70021 1.75736 2.25736C1.20021 2.81451 0.758251 3.47595 0.456723 4.2039C0.155195 4.93185 0 5.71207 0 6.5C0 7.28793 0.155195 8.06815 0.456723 8.7961C0.758251 9.52405 1.20021 10.1855 1.75736 10.7426C2.31451 11.2998 2.97595 11.7417 3.7039 12.0433C4.43185 12.3448 5.21207 12.5 6 12.5C7.5913 12.5 9.11742 11.8679 10.2426 10.7426C11.3679 9.61742 12 8.0913 12 6.5C12 4.9087 11.3679 3.38258 10.2426 2.25736C9.11742 1.13214 7.5913 0.5 6 0.5ZM5.06 8.9L2.9464 6.7856C2.85273 6.69171 2.80018 6.56446 2.80033 6.43183C2.80048 6.29921 2.85331 6.17207 2.9472 6.0784C3.04109 5.98473 3.16834 5.93218 3.30097 5.93233C3.43359 5.93248 3.56073 5.98531 3.6544 6.0792L5.3112 7.7368L8.3464 4.7008C8.44109 4.6109 8.56715 4.56153 8.69771 4.56322C8.82827 4.56492 8.95301 4.61754 9.04534 4.70986C9.13766 4.80219 9.19028 4.92693 9.19198 5.05749C9.19367 5.18805 9.1443 5.31411 9.0544 5.4088L5.5624 8.9H5.06Z"
fill="#FBFBFE"/> fill="#FBFBFE"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -54,9 +54,9 @@ cursor_hand_tool_label=توڵامرازی دەستی
scroll_vertical.title=ناردنی ئەستوونی بەکاربێنە scroll_vertical.title=ناردنی ئەستوونی بەکاربێنە
scroll_vertical_label=ناردنی ئەستوونی scroll_vertical_label=ناردنی ئەستوونی
scroll_horizontal.title=ناردنی ئاسۆیی بەکاربێنە scroll_horizontal.title=ناردنی ئاسۆیی بەکاربێنە
scroll_horizontal_label=ناردنی ئاسۆیی scroll_horizontal_label=ناردنی ئاسۆیی
scroll_wrapped.title=ناردنی لوولکراو بەکاربێنە scroll_wrapped.title=ناردنی لوولکراو بەکاربێنە
scroll_wrapped_label=ناردنی لوولکراو scroll_wrapped_label=ناردنی لوولکراو
# Document properties dialog box # Document properties dialog box
document_properties.title=تایبەتمەندییەکانی بەڵگەنامە... document_properties.title=تایبەتمەندییەکانی بەڵگەنامە...
document_properties_label=تایبەتمەندییەکانی بەڵگەنامە... document_properties_label=تایبەتمەندییەکانی بەڵگەنامە...

View File

@ -168,7 +168,7 @@ find_next_label=Upeigua
find_highlight=Embojekuaavepa find_highlight=Embojekuaavepa
find_match_case_label=Ejesareko taiguasu/taimichĩre find_match_case_label=Ejesareko taiguasu/taimichĩre
find_match_diacritics_label=Diacrítico moñondive find_match_diacritics_label=Diacrítico moñondive
find_entire_word_label=Ñeẽ oĩmbáva find_entire_word_label=Ñeẽ oĩmbáva
find_reached_top=Ojehupyty kuatia ñepyrũ, okuejeýta kuatia paha guive find_reached_top=Ojehupyty kuatia ñepyrũ, okuejeýta kuatia paha guive
find_reached_bottom=Ojehupyty kuatia paha, okuejeýta kuatia ñepyrũ guive find_reached_bottom=Ojehupyty kuatia paha, okuejeýta kuatia ñepyrũ guive
# LOCALIZATION NOTE (find_match_count): The supported plural forms are # LOCALIZATION NOTE (find_match_count): The supported plural forms are

View File

@ -25,7 +25,7 @@ of_pages=nu {{pagesCount}}
# will be replaced by a number representing the currently visible page, # will be replaced by a number representing the currently visible page,
# respectively a number representing the total number of pages in the document. # respectively a number representing the total number of pages in the document.
page_of_pages=({{pageNumber}} nu {{pagesCount}}) page_of_pages=({{pageNumber}} nu {{pagesCount}})
zoom_out.title=Attuolynuot zoom_out.title=Attuolynuot
zoom_out_label=Attuolynuot zoom_out_label=Attuolynuot
zoom_in.title=Pītuvynuot zoom_in.title=Pītuvynuot
zoom_in_label=Pītuvynuot zoom_in_label=Pītuvynuot

View File

@ -204,7 +204,7 @@ page_scale_percent={{scale}}%
# Loading indicator messages # Loading indicator messages
loading_error=Er is een fout opgetreden bij het laden van de PDF. loading_error=Er is een fout opgetreden bij het laden van de PDF.
invalid_file_error=Ongeldig of beschadigd PDF-bestand. invalid_file_error=Ongeldig of beschadigd PDF-bestand.
missing_file_error=PDF-bestand ontbreekt. missing_file_error=PDF-bestand ontbreekt.
unexpected_response_error=Onverwacht serverantwoord. unexpected_response_error=Onverwacht serverantwoord.
rendering_error=Er is een fout opgetreden bij het weergeven van de pagina. rendering_error=Er is een fout opgetreden bij het weergeven van de pagina.
# LOCALIZATION NOTE (annotation_date_string): "{{date}}" and "{{time}}" will be # LOCALIZATION NOTE (annotation_date_string): "{{date}}" and "{{time}}" will be

View File

@ -35,7 +35,7 @@ presentation_mode_label=پریزنٹیشن موڈ
open_file.title=فائل کھولو open_file.title=فائل کھولو
open_file_label=کھولو open_file_label=کھولو
print.title=چھاپو print.title=چھاپو
print_label=چھاپو print_label=چھاپو
save.title=ہتھیکڑا کرو save.title=ہتھیکڑا کرو
save_label=ہتھیکڑا کرو save_label=ہتھیکڑا کرو
# LOCALIZATION NOTE (download_button.title): used in Firefox for Android as a tooltip for the download button (“download” is a verb). # LOCALIZATION NOTE (download_button.title): used in Firefox for Android as a tooltip for the download button (“download” is a verb).

View File

@ -129,7 +129,7 @@ findbar_label=Narì'
find_input.title=Narì' find_input.title=Narì'
find_previous_label=Sa gachîn find_previous_label=Sa gachîn
find_next_label=Ne' ñaan find_next_label=Ne' ñaan
find_highlight=Daran' sa ña'an find_highlight=Daran' sa ña'an
find_match_case_label=Match case find_match_case_label=Match case
# LOCALIZATION NOTE (find_match_count): The supported plural forms are # LOCALIZATION NOTE (find_match_count): The supported plural forms are
# [one|two|few|many|other], with [other] as the default value. # [one|two|few|many|other], with [other] as the default value.

View File

@ -26,7 +26,7 @@ however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply to requirement for fonts to remain under this license does not apply to
any document created using the fonts or their derivatives. any document created using the fonts or their derivatives.
DEFINITIONS DEFINITIONS
"Font Software" refers to the set of files released by the Copyright "Font Software" refers to the set of files released by the Copyright
@ -83,11 +83,11 @@ Software, subject to the following conditions:
Software. Software.
TERMINATION TERMINATION
This license becomes null and void if any of the above conditions are not met. This license becomes null and void if any of the above conditions are not met.
DISCLAIMER DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,

View File

@ -11,7 +11,7 @@
<div class="container"> <div class="container">
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="col-md-6"> <div class="col-md-6">
</div> </div>
</div> </div>
</div> </div>

View File

@ -28,12 +28,12 @@
<div th:if="${param.messageType != null and param.messageType.size() > 0 and param.messageType[0] == 'usernameExists'}" class="alert alert-danger"> <div th:if="${param.messageType != null and param.messageType.size() > 0 and param.messageType[0] == 'usernameExists'}" class="alert alert-danger">
<span th:text="#{usernameExistsMessage}">Default message if not found</span> <span th:text="#{usernameExistsMessage}">Default message if not found</span>
</div> </div>
<!-- At the top of the user settings --> <!-- At the top of the user settings -->
<h3 class="text-center"><span th:text="#{welcome} + ' ' + ${username}">User</span>!</h3> <h3 class="text-center"><span th:text="#{welcome} + ' ' + ${username}">User</span>!</h3>
@ -55,7 +55,7 @@
<button type="submit" class="btn btn-primary" th:text="#{account.changeUsername}">Change Username</button> <button type="submit" class="btn btn-primary" th:text="#{account.changeUsername}">Change Username</button>
</div> </div>
</form> </form>
<hr> <!-- Separator Line --> <hr> <!-- Separator Line -->
<!-- Change Password Form --> <!-- Change Password Form -->
@ -79,16 +79,16 @@
</form> </form>
<hr> <hr>
<div class="card"> <div class="card">
<div class="card-header" th:text="#{account.yourApiKey}"> <div class="card-header" th:text="#{account.yourApiKey}">
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="input-group mb-3"> <div class="input-group mb-3">
<input type="password" class="form-control" id="apiKey" th:placeholder="#{account.yourApiKey}" readonly> <input type="password" class="form-control" id="apiKey" th:placeholder="#{account.yourApiKey}" readonly>
<div class="input-group-append"> <div class="input-group-append">
<button class="btn btn-outline-secondary" id="copyBtn" type="button" onclick="copyToClipboard()"> <button class="btn btn-outline-secondary" id="copyBtn" type="button" onclick="copyToClipboard()">
<img class="blackwhite-icon" src="images/clipboard.svg" alt="Copy" style="height:20px;"> <img class="blackwhite-icon" src="images/clipboard.svg" alt="Copy" style="height:20px;">
</button> </button>
<button class="btn btn-outline-secondary" id="showBtn" type="button" onclick="showApiKey()"> <button class="btn btn-outline-secondary" id="showBtn" type="button" onclick="showApiKey()">
@ -97,13 +97,13 @@
<button class="btn btn-outline-secondary" id="refreshBtn" type="button" onclick="refreshApiKey()"> <button class="btn btn-outline-secondary" id="refreshBtn" type="button" onclick="refreshApiKey()">
<img class="blackwhite-icon" id="eyeIcon" src="images/arrow-clockwise.svg" alt="Refresh API-Key" style="height:20px;"> <img class="blackwhite-icon" id="eyeIcon" src="images/arrow-clockwise.svg" alt="Refresh API-Key" style="height:20px;">
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<script> <script>
function copyToClipboard() { function copyToClipboard() {
const apiKeyElement = document.getElementById("apiKey"); const apiKeyElement = document.getElementById("apiKey");
@ -111,7 +111,7 @@
document.execCommand("copy"); document.execCommand("copy");
} }
function showApiKey() { function showApiKey() {
const apiKeyElement = document.getElementById("apiKey"); const apiKeyElement = document.getElementById("apiKey");
const copyBtn = document.getElementById("copyBtn"); const copyBtn = document.getElementById("copyBtn");
@ -156,7 +156,7 @@
console.error('There was an error:', error); console.error('There was an error:', error);
} }
} }
function manageUIState(apiKey) { function manageUIState(apiKey) {
const apiKeyElement = document.getElementById("apiKey"); const apiKeyElement = document.getElementById("apiKey");
const showBtn = document.getElementById("showBtn"); const showBtn = document.getElementById("showBtn");
@ -165,7 +165,7 @@
if (apiKey && apiKey.trim().length > 0) { if (apiKey && apiKey.trim().length > 0) {
apiKeyElement.value = apiKey; apiKeyElement.value = apiKey;
showBtn.disabled = false; showBtn.disabled = false;
copyBtn.disabled = true; copyBtn.disabled = true;
} else { } else {
apiKeyElement.value = ""; apiKeyElement.value = "";
showBtn.disabled = true; showBtn.disabled = true;
@ -173,10 +173,10 @@
} }
} }
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function() {
const form = document.querySelector('form[action="api/v1/user/change-password"]'); const form = document.querySelector('form[action="api/v1/user/change-password"]');
form.addEventListener('submit', function(event) { form.addEventListener('submit', function(event) {
const newPassword = document.getElementById('newPassword').value; const newPassword = document.getElementById('newPassword').value;
const confirmNewPassword = document.getElementById('confirmNewPassword').value; const confirmNewPassword = document.getElementById('confirmNewPassword').value;
@ -188,10 +188,10 @@
}); });
}); });
</script> </script>
<hr> <!-- Separator Line --> <hr> <!-- Separator Line -->
<h4 th:text="#{account.syncTitle}">Sync browser settings with Account</h4> <h4 th:text="#{account.syncTitle}">Sync browser settings with Account</h4>
<div class="container mt-4"> <div class="container mt-4">
<h3 th:text="#{account.settingsCompare}">Settings Comparison:</h3> <h3 th:text="#{account.settingsCompare}">Settings Comparison:</h3>
@ -226,10 +226,10 @@
text-align: center; text-align: center;
} }
</style> </style>
<script th:inline="javascript"> <script th:inline="javascript">
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function() {
@ -299,12 +299,12 @@
</script> </script>
<div class="mb-3 mt-4"> <div class="mb-3 mt-4">
<a href="logout"> <a href="logout">
<button type="button" class="btn btn-danger" th:text="#{account.signOut}">Sign Out</button> <button type="button" class="btn btn-danger" th:text="#{account.signOut}">Sign Out</button>

View File

@ -12,13 +12,13 @@
<div class="container"> <div class="container">
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="col-md-8"> <div class="col-md-8">
<!-- User Settings Title --> <!-- User Settings Title -->
<h2 class="text-center" th:text="#{adminUserSettings.header}">Admin User Control Settings</h2> <h2 class="text-center" th:text="#{adminUserSettings.header}">Admin User Control Settings</h2>
<table class="table"> <table class="table">
<thead> <thead>
<tr> <tr>
@ -40,7 +40,7 @@
</tbody> </tbody>
</table> </table>
<h2 th:text="#{adminUserSettings.addUser}">Add New User</h2> <h2 th:text="#{adminUserSettings.addUser}">Add New User</h2>
<div th:if="${param.messageType != null and param.messageType.size() > 0 and param.messageType[0] == 'usernameExists'}" class="alert alert-danger"> <div th:if="${param.messageType != null and param.messageType.size() > 0 and param.messageType[0] == 'usernameExists'}" class="alert alert-danger">
@ -69,7 +69,7 @@
<input type="checkbox" class="form-check-input" id="forceChange" name="forceChange"> <input type="checkbox" class="form-check-input" id="forceChange" name="forceChange">
<label class="form-check-label" for="forceChange" th:text="#{adminUserSettings.forceChange}">Force user to change username/password on login</label> <label class="form-check-label" for="forceChange" th:text="#{adminUserSettings.forceChange}">Force user to change username/password on login</label>
</div> </div>
<!-- Add other fields as required --> <!-- Add other fields as required -->
<button type="submit" class="btn btn-primary" th:text="#{adminUserSettings.submit}">Save User</button> <button type="submit" class="btn btn-primary" th:text="#{adminUserSettings.submit}">Save User</button>
</form> </form>

View File

@ -26,7 +26,7 @@
<p th:text="#{autoSplitPDF.formPrompt}"></p> <p th:text="#{autoSplitPDF.formPrompt}"></p>
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div> <div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
<div class="form-check"> <div class="form-check">
<input type="checkbox" class="form-check-input" name="duplexMode" id="duplexMode"> <input type="checkbox" class="form-check-input" name="duplexMode" id="duplexMode">
<label class="ms-3" for="duplexMode" th:text=#{autoSplitPDF.duplexMode}></label> <label class="ms-3" for="duplexMode" th:text=#{autoSplitPDF.duplexMode}></label>
</div> </div>
<p><a th:href="@{files/Auto Splitter Divider (minimal).pdf}" download th:text="#{autoSplitPDF.dividerDownload1}"></a></p> <p><a th:href="@{files/Auto Splitter Divider (minimal).pdf}" download th:text="#{autoSplitPDF.dividerDownload1}"></a></p>

View File

@ -33,7 +33,7 @@
<!-- At the top of the user settings --> <!-- At the top of the user settings -->
<h3 class="text-center"><span th:text="#{welcome} + ' ' + ${username}">User</span>!</h3> <h3 class="text-center"><span th:text="#{welcome} + ' ' + ${username}">User</span>!</h3>
<!-- Change Username Form --> <!-- Change Username Form -->
<h4></h4> <h4></h4>
<h4 th:text="#{changeCreds.changeUserAndPassword}">Change Username and password</h4> <h4 th:text="#{changeCreds.changeUserAndPassword}">Change Username and password</h4>
@ -58,11 +58,11 @@
<button type="submit" class="btn btn-primary" th:text="#{changeCreds.submit}">Change credentials!</button> <button type="submit" class="btn btn-primary" th:text="#{changeCreds.submit}">Change credentials!</button>
</div> </div>
</form> </form>
<script> <script>
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function() {
const form = document.querySelector('form[action="api/v1/user/change-username-and-password"]'); const form = document.querySelector('form[action="api/v1/user/change-username-and-password"]');
form.addEventListener('submit', function(event) { form.addEventListener('submit', function(event) {
const newPassword = document.getElementById('newPassword').value; const newPassword = document.getElementById('newPassword').value;
const confirmNewPassword = document.getElementById('confirmNewPassword').value; const confirmNewPassword = document.getElementById('confirmNewPassword').value;

View File

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

View File

@ -25,7 +25,7 @@
<p class="mt-3" th:text="#{fileToPDF.supportedFileTypes}"></p> <p class="mt-3" th:text="#{fileToPDF.supportedFileTypes}"></p>
<p th:utext="#{fileToPDF.fileTypesList}"></p> <p th:utext="#{fileToPDF.fileTypesList}"></p>
<a href="https://help.libreoffice.org/latest/en-US/text/shared/guide/supported_formats.html">https://help.libreoffice.org/latest/en-US/text/shared/guide/supported_formats.html</a> <a href="https://help.libreoffice.org/latest/en-US/text/shared/guide/supported_formats.html">https://help.libreoffice.org/latest/en-US/text/shared/guide/supported_formats.html</a>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,36 +1,36 @@
<!DOCTYPE html> <!DOCTYPE html>
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org"> <html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
<th:block th:insert="~{fragments/common :: head(title=#{HTMLToPDF.title}, header=#{HTMLToPDF.header})}"></th:block> <th:block th:insert="~{fragments/common :: head(title=#{HTMLToPDF.title}, header=#{HTMLToPDF.header})}"></th:block>
<body> <body>
<th:block th:insert="~{fragments/common :: game}"></th:block> <th:block th:insert="~{fragments/common :: game}"></th:block>
<div id="page-container"> <div id="page-container">
<div id="content-wrap"> <div id="content-wrap">
<div th:insert="~{fragments/navbar.html :: navbar}"></div> <div th:insert="~{fragments/navbar.html :: navbar}"></div>
<br> <br> <br> <br>
<div class="container"> <div class="container">
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="mb-3"> <div class="mb-3">
<h2 th:text="#{HTMLToPDF.header}"></h2> <h2 th:text="#{HTMLToPDF.header}"></h2>
<form method="post" enctype="multipart/form-data" th:action="@{api/v1/convert/html/pdf}"> <form method="post" enctype="multipart/form-data" th:action="@{api/v1/convert/html/pdf}">
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='text/html,application/zip' )}"></div> <div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='text/html,application/zip' )}"></div>
<div class="mb-3"> <div class="mb-3">
<label for="zoom" th:text="#{HTMLToPDF.zoom}" class="form-label"></label> <label for="zoom" th:text="#{HTMLToPDF.zoom}" class="form-label"></label>
<input type="number" step="0.1" class="form-control" id="zoom" name="zoom" value="1" /> <input type="number" step="0.1" class="form-control" id="zoom" name="zoom" value="1" />
</div> </div>
<br> <br>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{HTMLToPDF.submit}"></button> <button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{HTMLToPDF.submit}"></button>
</form> </form>
<p class="mt-3" th:text="#{HTMLToPDF.help}"></p> <p class="mt-3" th:text="#{HTMLToPDF.help}"></p>
<p class="mt-3" th:text="#{HTMLToPDF.credit}"></p> <p class="mt-3" th:text="#{HTMLToPDF.credit}"></p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div th:insert="~{fragments/footer.html :: footer}"></div> <div th:insert="~{fragments/footer.html :: footer}"></div>
</div> </div>
</body> </body>
</html> </html>

View File

@ -1,92 +1,92 @@
<!DOCTYPE html> <!DOCTYPE html>
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org"> <html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
<th:block th:insert="~{fragments/common :: head(title=#{imageToPDF.title}, header=#{imageToPDF.header})}"></th:block> <th:block th:insert="~{fragments/common :: head(title=#{imageToPDF.title}, header=#{imageToPDF.header})}"></th:block>
<body> <body>
<th:block th:insert="~{fragments/common :: game}"></th:block> <th:block th:insert="~{fragments/common :: game}"></th:block>
<div id="page-container"> <div id="page-container">
<div id="content-wrap"> <div id="content-wrap">
<div th:insert="~{fragments/navbar.html :: navbar}"></div> <div th:insert="~{fragments/navbar.html :: navbar}"></div>
<br> <br> <br> <br>
<div class="container"> <div class="container">
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="col-md-6"> <div class="col-md-6">
<h2 th:text="#{imageToPDF.header}"></h2> <h2 th:text="#{imageToPDF.header}"></h2>
<form method="post" enctype="multipart/form-data" th:action="@{api/v1/convert/img/pdf}"> <form method="post" enctype="multipart/form-data" th:action="@{api/v1/convert/img/pdf}">
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='image/*', inputText=#{imgPrompt})}"></div> <div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='image/*', inputText=#{imgPrompt})}"></div>
<div class="mb-3"> <div class="mb-3">
<label for="fitOption" th:text="#{imageToPDF.selectLabel}">Fit Options</label> <label for="fitOption" th:text="#{imageToPDF.selectLabel}">Fit Options</label>
<select class="form-control" id="fitOption" name="fitOption"> <select class="form-control" id="fitOption" name="fitOption">
<option value="fillPage" th:text="#{imageToPDF.fillPage}">Fill Page</option> <option value="fillPage" th:text="#{imageToPDF.fillPage}">Fill Page</option>
<option value="fitDocumentToImage" th:text="#{imageToPDF.fitDocumentToImage}">Fit Document to Image</option> <option value="fitDocumentToImage" th:text="#{imageToPDF.fitDocumentToImage}">Fit Document to Image</option>
<option value="maintainAspectRatio" th:text="#{imageToPDF.maintainAspectRatio}">Maintain Aspect Ratio</option> <option value="maintainAspectRatio" th:text="#{imageToPDF.maintainAspectRatio}">Maintain Aspect Ratio</option>
</select> </select>
</div> </div>
<div class="form-check"> <div class="form-check">
<input type="checkbox" class="form-check-input" name="autoRotate" id="autoRotate"> <input type="checkbox" class="form-check-input" name="autoRotate" id="autoRotate">
<label class="ms-3" for="autoRotate" th:text=#{imageToPDF.selectText.2}></label> <label class="ms-3" for="autoRotate" th:text=#{imageToPDF.selectText.2}></label>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label th:text="#{pdfToImage.colorType}"></label> <label th:text="#{pdfToImage.colorType}"></label>
<select class="form-control" id="colorType" name="colorType"> <select class="form-control" id="colorType" name="colorType">
<option value="color" th:text="#{pdfToImage.color}"></option> <option value="color" th:text="#{pdfToImage.color}"></option>
<option value="greyscale" th:text="#{pdfToImage.grey}"></option> <option value="greyscale" th:text="#{pdfToImage.grey}"></option>
<option value="blackwhite" th:text="#{pdfToImage.blackwhite}"></option> <option value="blackwhite" th:text="#{pdfToImage.blackwhite}"></option>
</select> </select>
</div> </div>
<br> <br>
<input type="hidden" id="override" name="override" value="multi"> <input type="hidden" id="override" name="override" value="multi">
<div class="mb-3"> <div class="mb-3">
<label th:text=#{imageToPDF.selectText.3}></label> <label th:text=#{imageToPDF.selectText.3}></label>
<select class="form-control" id="conversionType" name="conversionType" disabled> <select class="form-control" id="conversionType" name="conversionType" disabled>
<option value="merge" th:text=#{imageToPDF.selectText.4}></option> <option value="merge" th:text=#{imageToPDF.selectText.4}></option>
<option value="convert" th:text=#{imageToPDF.selectText.5} selected></option> <option value="convert" th:text=#{imageToPDF.selectText.5} selected></option>
</select> </select>
</div> </div>
<br> <br> <br> <br>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{imageToPDF.submit}"></button> <button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{imageToPDF.submit}"></button>
<script> <script>
$('#fileInput-input').on('change', function() { $('#fileInput-input').on('change', function() {
var files = document.getElementById("fileInput-input").files; var files = document.getElementById("fileInput-input").files;
var conversionType = document.getElementById("conversionType"); var conversionType = document.getElementById("conversionType");
console.log("files.length=" + files.length) console.log("files.length=" + files.length)
if (files.length > 1) { if (files.length > 1) {
conversionType.disabled = false; conversionType.disabled = false;
} else { } else {
conversionType.disabled = true; conversionType.disabled = true;
} }
}); });
$('#conversionType').change(function() { $('#conversionType').change(function() {
var selectedValue = $(this).val(); var selectedValue = $(this).val();
var override = document.getElementById("override"); var override = document.getElementById("override");
console.log("selectedValue=" + selectedValue) console.log("selectedValue=" + selectedValue)
if (selectedValue === 'merge') { if (selectedValue === 'merge') {
override.value = "single"; override.value = "single";
} else if (selectedValue === 'convert') { } else if (selectedValue === 'convert') {
override.value = "multi"; override.value = "multi";
} }
}); });
</script> </script>
</form> </form>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div th:insert="~{fragments/footer.html :: footer}"></div> <div th:insert="~{fragments/footer.html :: footer}"></div>
</div> </div>
</body> </body>
</html> </html>

View File

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

View File

@ -1,61 +1,61 @@
<!DOCTYPE html> <!DOCTYPE html>
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org"> <html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
<th:block th:insert="~{fragments/common :: head(title=#{pdfToImage.title}, header=#{pdfToImage.header})}"></th:block> <th:block th:insert="~{fragments/common :: head(title=#{pdfToImage.title}, header=#{pdfToImage.header})}"></th:block>
<body> <body>
<th:block th:insert="~{fragments/common :: game}"></th:block> <th:block th:insert="~{fragments/common :: game}"></th:block>
<div id="page-container"> <div id="page-container">
<div id="content-wrap"> <div id="content-wrap">
<div th:insert="~{fragments/navbar.html :: navbar}"></div> <div th:insert="~{fragments/navbar.html :: navbar}"></div>
<br> <br> <br> <br>
<div class="container"> <div class="container">
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="col-md-6"> <div class="col-md-6">
<h2 th:text="#{pdfToImage.header}"></h2> <h2 th:text="#{pdfToImage.header}"></h2>
<p th:text="#{processTimeWarning}"></p> <p th:text="#{processTimeWarning}"></p>
<form method="post" enctype="multipart/form-data" th:action="@{api/v1/convert/pdf/img}"> <form method="post" enctype="multipart/form-data" th:action="@{api/v1/convert/pdf/img}">
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div> <div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
<div class="mb-3"> <div class="mb-3">
<label th:text="#{pdfToImage.selectText}"></label> <label th:text="#{pdfToImage.selectText}"></label>
<select class="form-control" name="imageFormat"> <select class="form-control" name="imageFormat">
<option value="png">PNG</option> <option value="png">PNG</option>
<option value="jpg">JPG</option> <option value="jpg">JPG</option>
<option value="gif">GIF</option> <option value="gif">GIF</option>
<option value="tiff">TIFF</option> <option value="tiff">TIFF</option>
<option value="bmp">BMP</option> <option value="bmp">BMP</option>
</select> </select>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label th:text="#{pdfToImage.singleOrMultiple}"></label> <label th:text="#{pdfToImage.singleOrMultiple}"></label>
<select class="form-control" name="singleOrMultiple"> <select class="form-control" name="singleOrMultiple">
<option value="multiple" th:text="#{pdfToImage.multi}"></option> <option value="multiple" th:text="#{pdfToImage.multi}"></option>
<option value="single" th:text="#{pdfToImage.single}"></option> <option value="single" th:text="#{pdfToImage.single}"></option>
</select> </select>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label th:text="#{pdfToImage.colorType}"></label> <label th:text="#{pdfToImage.colorType}"></label>
<select class="form-control" name="colorType"> <select class="form-control" name="colorType">
<option value="color" th:text="#{pdfToImage.color}"></option> <option value="color" th:text="#{pdfToImage.color}"></option>
<option value="greyscale" th:text="#{pdfToImage.grey}"></option> <option value="greyscale" th:text="#{pdfToImage.grey}"></option>
<option value="blackwhite" th:text="#{pdfToImage.blackwhite}"></option> <option value="blackwhite" th:text="#{pdfToImage.blackwhite}"></option>
</select> </select>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="dpi">DPI:</label> <label for="dpi">DPI:</label>
<input type="number" name="dpi" class="form-control" id="dpi" min="1" step="1" value="300" required> <input type="number" name="dpi" class="form-control" id="dpi" min="1" step="1" value="300" required>
</div> </div>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{pdfToImage.submit}"></button> <button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{pdfToImage.submit}"></button>
</form> </form>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div th:insert="~{fragments/footer.html :: footer}"></div> <div th:insert="~{fragments/footer.html :: footer}"></div>
</div> </div>
</body> </body>
</html> </html>

View File

@ -14,9 +14,9 @@
<h2 th:text="#{PDFToPresentation.header}"></h2> <h2 th:text="#{PDFToPresentation.header}"></h2>
<form method="post" enctype="multipart/form-data" th:action="@{api/v1/convert/pdf/presentation}"> <form method="post" enctype="multipart/form-data" th:action="@{api/v1/convert/pdf/presentation}">
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div> <div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
<div class="mb-3"> <div class="mb-3">
<label th:text="#{PDFToPresentation.selectText.1}"></label> <label th:text="#{PDFToPresentation.selectText.1}"></label>
<select class="form-control" name="outputFormat"> <select class="form-control" name="outputFormat">
<option value="ppt">PPT</option> <option value="ppt">PPT</option>
<option value="pptx">PPTX</option> <option value="pptx">PPTX</option>

View File

@ -1,35 +1,35 @@
<!DOCTYPE html> <!DOCTYPE html>
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org"> <html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
<th:block th:insert="~{fragments/common :: head(title=#{PDFToText.title}, header=#{PDFToText.header})}"></th:block> <th:block th:insert="~{fragments/common :: head(title=#{PDFToText.title}, header=#{PDFToText.header})}"></th:block>
<body> <body>
<th:block th:insert="~{fragments/common :: game}"></th:block> <th:block th:insert="~{fragments/common :: game}"></th:block>
<div id="page-container"> <div id="page-container">
<div id="content-wrap"> <div id="content-wrap">
<div th:insert="~{fragments/navbar.html :: navbar}"></div> <div th:insert="~{fragments/navbar.html :: navbar}"></div>
<br> <br> <br> <br>
<div class="container"> <div class="container">
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="col-md-6"> <div class="col-md-6">
<h2 th:text="#{PDFToText.header}"></h2> <h2 th:text="#{PDFToText.header}"></h2>
<form method="post" enctype="multipart/form-data" th:action="@{api/v1/convert/pdf/text}"> <form method="post" enctype="multipart/form-data" th:action="@{api/v1/convert/pdf/text}">
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div> <div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
<div class="mb-3"> <div class="mb-3">
<label th:text="#{PDFToText.selectText.1}"></label> <label th:text="#{PDFToText.selectText.1}"></label>
<select class="form-control" name="outputFormat"> <select class="form-control" name="outputFormat">
<option value="rtf">RTF</option> <option value="rtf">RTF</option>
<option value="txt">TXT</option> <option value="txt">TXT</option>
</select> </select>
</div> </div>
<br> <br>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{PDFToText.submit}"></button> <button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{PDFToText.submit}"></button>
</form> </form>
<p class="mt-3" th:text="#{PDFToText.credit}"></p> <p class="mt-3" th:text="#{PDFToText.credit}"></p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div th:insert="~{fragments/footer.html :: footer}"></div> <div th:insert="~{fragments/footer.html :: footer}"></div>
</div> </div>

View File

@ -14,9 +14,9 @@
<h2 th:text="#{PDFToWord.header}"></h2> <h2 th:text="#{PDFToWord.header}"></h2>
<form method="post" enctype="multipart/form-data" th:action="@{api/v1/convert/pdf/word}"> <form method="post" enctype="multipart/form-data" th:action="@{api/v1/convert/pdf/word}">
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div> <div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
<div class="mb-3"> <div class="mb-3">
<label th:text="#{PDFToWord.selectText.1}"></label> <label th:text="#{PDFToWord.selectText.1}"></label>
<select class="form-control" name="outputFormat"> <select class="form-control" name="outputFormat">
<option value="doc">Doc</option> <option value="doc">Doc</option>
<option value="docx">DocX</option> <option value="docx">DocX</option>

View File

@ -1,29 +1,29 @@
<!DOCTYPE html> <!DOCTYPE html>
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org"> <html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
<th:block th:insert="~{fragments/common :: head(title=#{URLToPDF.title}, header=#{URLToPDF.header})}"></th:block> <th:block th:insert="~{fragments/common :: head(title=#{URLToPDF.title}, header=#{URLToPDF.header})}"></th:block>
<body> <body>
<th:block th:insert="~{fragments/common :: game}"></th:block> <th:block th:insert="~{fragments/common :: game}"></th:block>
<div id="page-container"> <div id="page-container">
<div id="content-wrap"> <div id="content-wrap">
<div th:insert="~{fragments/navbar.html :: navbar}"></div> <div th:insert="~{fragments/navbar.html :: navbar}"></div>
<br> <br> <br> <br>
<div class="container"> <div class="container">
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="col-md-6"> <div class="col-md-6">
<h2 th:text="#{URLToPDF.header}"></h2> <h2 th:text="#{URLToPDF.header}"></h2>
<form method="post" enctype="multipart/form-data" th:action="@{api/v1/convert/url/pdf}"> <form method="post" enctype="multipart/form-data" th:action="@{api/v1/convert/url/pdf}">
<input type="text" class="form-control" id="urlInput" name="urlInput"> <input type="text" class="form-control" id="urlInput" name="urlInput">
<br> <br>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{URLToPDF.submit}"></button> <button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{URLToPDF.submit}"></button>
</form> </form>
<p class="mt-3" th:text="#{URLToPDF.credit}"></p> <p class="mt-3" th:text="#{URLToPDF.credit}"></p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div th:insert="~{fragments/footer.html :: footer}"></div> <div th:insert="~{fragments/footer.html :: footer}"></div>
</div> </div>
</body> </body>
</html> </html>

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