Compare commits
96 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a67fd82c42 | ||
|
|
e2dd8a3d91 | ||
|
|
554c112a94 | ||
|
|
d7e6cae313 | ||
|
|
a3affe63f9 | ||
|
|
d34c44ed7b | ||
|
|
68e8a0174c | ||
|
|
4b40a0460e | ||
|
|
27fc5e9a9e | ||
|
|
3d7eb040ab | ||
|
|
82b1ab4263 | ||
|
|
c1d7217242 | ||
|
|
708ede5e26 | ||
|
|
af74f9d6c6 | ||
|
|
27ec4d5a8f | ||
|
|
779191c02b | ||
|
|
2742e0b051 | ||
|
|
ea46204c6e | ||
|
|
41b41996c5 | ||
|
|
2abf48a57b | ||
|
|
5f81ff88e8 | ||
|
|
bc3340f3ba | ||
|
|
f9963a2316 | ||
|
|
0aeb22e7c8 | ||
|
|
dbb9009cf6 | ||
|
|
21839d07e8 | ||
|
|
8004251460 | ||
|
|
1ced941bee | ||
|
|
cb4a5778ec | ||
|
|
46c6a2b599 | ||
|
|
e5627af63d | ||
|
|
6a3064f7f2 | ||
|
|
158708b696 | ||
|
|
0233086487 | ||
|
|
242aa5eae1 | ||
|
|
bf65c456d1 | ||
|
|
26720c5018 | ||
|
|
2ed07e3fcb | ||
|
|
e382d254ee | ||
|
|
507d21772d | ||
|
|
5bf050d77f | ||
|
|
976caeb79d | ||
|
|
2d3611fd00 | ||
|
|
118de1789a | ||
|
|
b56d54a35a | ||
|
|
b9bfcd59cd | ||
|
|
f8adc0f101 | ||
|
|
69d4b52b06 | ||
|
|
5e3612a9b0 | ||
|
|
b3a4597ad1 | ||
|
|
dc46172deb | ||
|
|
04696dc2aa | ||
|
|
b37457b41d | ||
|
|
46c53a9c88 | ||
|
|
5f610da671 | ||
|
|
bacc502f07 | ||
|
|
883281e4df | ||
|
|
9e8c16f313 | ||
|
|
4a7df3fd3f | ||
|
|
f725f92e1a | ||
|
|
9d2c23f612 | ||
|
|
637446fab8 | ||
|
|
196c0f4a39 | ||
|
|
f9b92eec71 | ||
|
|
3be6b0659e | ||
|
|
00e1f74f48 | ||
|
|
6ae2fddd48 | ||
|
|
c5cffdcacb | ||
|
|
d9eda14521 | ||
|
|
b865f4379f | ||
|
|
4294dc54b1 | ||
|
|
e3adb38a06 | ||
|
|
1eb40be3b6 | ||
|
|
906bfa7ab1 | ||
|
|
382f5603a8 | ||
|
|
3dd8b53f85 | ||
|
|
6a874be8e3 | ||
|
|
ff08cf41b5 | ||
|
|
107112e728 | ||
|
|
60cc613c63 | ||
|
|
67569a8f6a | ||
|
|
7130143809 | ||
|
|
16233595d8 | ||
|
|
f59e024802 | ||
|
|
a97a27afd3 | ||
|
|
94ea723326 | ||
|
|
8348caf3f0 | ||
|
|
b2dfb4f863 | ||
|
|
565208edbf | ||
|
|
8e743e2d67 | ||
|
|
3220ad2045 | ||
|
|
e690b09ed2 | ||
|
|
595da7acd9 | ||
|
|
78f1d2b843 | ||
|
|
d2fe4364c2 | ||
|
|
cb114c29de |
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -1,2 +1,2 @@
|
|||||||
# All PRs to V1 must be approved by Frooodle
|
# All PRs to V1 must be approved by Frooodle
|
||||||
* @Frooodle @reecebrowne @Ludy87 @DarioGii
|
* @Frooodle @reecebrowne @Ludy87 @DarioGii @ConnorYoh
|
||||||
|
|||||||
6
.github/release.yml
vendored
6
.github/release.yml
vendored
@@ -1,10 +1,4 @@
|
|||||||
changelog:
|
changelog:
|
||||||
exclude:
|
|
||||||
labels:
|
|
||||||
- Documentation
|
|
||||||
- Test
|
|
||||||
- Github
|
|
||||||
|
|
||||||
categories:
|
categories:
|
||||||
- title: Bug Fixes
|
- title: Bug Fixes
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
14
.github/workflows/PR-Demo-Comment.yml
vendored
14
.github/workflows/PR-Demo-Comment.yml
vendored
@@ -27,7 +27,8 @@ jobs:
|
|||||||
github.event.comment.user.login == 'LaserKaspar' ||
|
github.event.comment.user.login == 'LaserKaspar' ||
|
||||||
github.event.comment.user.login == 'sbplat' ||
|
github.event.comment.user.login == 'sbplat' ||
|
||||||
github.event.comment.user.login == 'reecebrowne' ||
|
github.event.comment.user.login == 'reecebrowne' ||
|
||||||
github.event.comment.user.login == 'DarioGii'
|
github.event.comment.user.login == 'DarioGii' ||
|
||||||
|
github.event.comment.user.login == 'ConnorYoh'
|
||||||
)
|
)
|
||||||
outputs:
|
outputs:
|
||||||
pr_number: ${{ steps.get-pr.outputs.pr_number }}
|
pr_number: ${{ steps.get-pr.outputs.pr_number }}
|
||||||
@@ -36,7 +37,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
@@ -81,7 +82,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
@@ -93,7 +94,7 @@ jobs:
|
|||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Set up JDK
|
- name: Set up JDK
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: "17"
|
java-version: "17"
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
@@ -102,9 +103,10 @@ jobs:
|
|||||||
run: ./gradlew clean build
|
run: ./gradlew clean build
|
||||||
env:
|
env:
|
||||||
DOCKER_ENABLE_SECURITY: false
|
DOCKER_ENABLE_SECURITY: false
|
||||||
|
STIRLING_PDF_DESKTOP_UI: false
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
|
uses: docker/setup-buildx-action@f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca # v3.9.0
|
||||||
|
|
||||||
- name: Get version number
|
- name: Get version number
|
||||||
id: versionNumber
|
id: versionNumber
|
||||||
@@ -119,7 +121,7 @@ jobs:
|
|||||||
password: ${{ secrets.DOCKER_HUB_API }}
|
password: ${{ secrets.DOCKER_HUB_API }}
|
||||||
|
|
||||||
- name: Build and push PR-specific image
|
- name: Build and push PR-specific image
|
||||||
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0
|
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
|
|||||||
30
.github/workflows/PR-Demo-cleanup.yml
vendored
30
.github/workflows/PR-Demo-cleanup.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ jobs:
|
|||||||
- name: Cleanup PR deployment
|
- name: Cleanup PR deployment
|
||||||
id: cleanup
|
id: cleanup
|
||||||
run: |
|
run: |
|
||||||
CLEANUP_STATUS=$(ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << 'ENDSSH'
|
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << 'ENDSSH'
|
||||||
if [ -d "/stirling/PR-${{ github.event.pull_request.number }}" ]; then
|
if [ -d "/stirling/PR-${{ github.event.pull_request.number }}" ]; then
|
||||||
echo "Found PR directory, proceeding with cleanup..."
|
echo "Found PR directory, proceeding with cleanup..."
|
||||||
|
|
||||||
@@ -57,29 +57,3 @@ jobs:
|
|||||||
echo "NO_CLEANUP_NEEDED"
|
echo "NO_CLEANUP_NEEDED"
|
||||||
fi
|
fi
|
||||||
ENDSSH
|
ENDSSH
|
||||||
)
|
|
||||||
|
|
||||||
if [[ $CLEANUP_STATUS == *"PERFORMED_CLEANUP"* ]]; then
|
|
||||||
echo "cleanup_performed=true" >> $GITHUB_OUTPUT
|
|
||||||
else
|
|
||||||
echo "cleanup_performed=false" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Post cleanup notice to PR
|
|
||||||
if: steps.cleanup.outputs.cleanup_performed == 'true'
|
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const { GITHUB_REPOSITORY } = process.env;
|
|
||||||
const [repoOwner, repoName] = GITHUB_REPOSITORY.split('/');
|
|
||||||
const prNumber = context.issue.number;
|
|
||||||
|
|
||||||
const commentBody = `## 🧹 Deployment Cleanup\n\n` +
|
|
||||||
`The test deployment for this PR has been cleaned up.`;
|
|
||||||
|
|
||||||
await github.rest.issues.createComment({
|
|
||||||
owner: repoOwner,
|
|
||||||
repo: repoName,
|
|
||||||
issue_number: prNumber,
|
|
||||||
body: commentBody
|
|
||||||
});
|
|
||||||
|
|||||||
2
.github/workflows/auto-labeler.yml
vendored
2
.github/workflows/auto-labeler.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
|
|||||||
49
.github/workflows/build.yml
vendored
49
.github/workflows/build.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
@@ -32,17 +32,11 @@ jobs:
|
|||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up JDK ${{ matrix.jdk-version }}
|
- name: Set up JDK ${{ matrix.jdk-version }}
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: ${{ matrix.jdk-version }}
|
java-version: ${{ matrix.jdk-version }}
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
|
|
||||||
- name: PR | Generate verification metadata with signatures and checksums for dependabot[bot]
|
|
||||||
if: github.event.pull_request.user.login == 'dependabot[bot]'
|
|
||||||
run: |
|
|
||||||
./gradlew clean dependencies buildEnvironment spotlessApply --write-verification-metadata sha256 --refresh-dependencies help
|
|
||||||
./gradlew clean dependencies buildEnvironment spotlessApply --write-verification-metadata sha256,pgp --refresh-keys --export-keys --refresh-dependencies help
|
|
||||||
|
|
||||||
- name: Build with Gradle and no spring security
|
- name: Build with Gradle and no spring security
|
||||||
run: ./gradlew clean build
|
run: ./gradlew clean build
|
||||||
env:
|
env:
|
||||||
@@ -64,6 +58,35 @@ jobs:
|
|||||||
build/reports/problems/
|
build/reports/problems/
|
||||||
retention-days: 3
|
retention-days: 3
|
||||||
|
|
||||||
|
check-licence:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Harden Runner
|
||||||
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
|
with:
|
||||||
|
egress-policy: audit
|
||||||
|
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
|
- name: Set up JDK 17
|
||||||
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
|
with:
|
||||||
|
java-version: "17"
|
||||||
|
distribution: "adopt"
|
||||||
|
|
||||||
|
- name: check the licenses for compatibility
|
||||||
|
run: ./gradlew clean checkLicense
|
||||||
|
|
||||||
|
- name: FAILED - check the licenses for compatibility
|
||||||
|
if: failure()
|
||||||
|
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||||
|
with:
|
||||||
|
name: dependencies-without-allowed-license.json
|
||||||
|
path: |
|
||||||
|
build/reports/dependency-license/dependencies-without-allowed-license.json
|
||||||
|
retention-days: 3
|
||||||
|
|
||||||
docker-compose-tests:
|
docker-compose-tests:
|
||||||
# if: github.event_name == 'push' && github.ref == 'refs/heads/main' ||
|
# if: github.event_name == 'push' && github.ref == 'refs/heads/main' ||
|
||||||
# (github.event_name == 'pull_request' &&
|
# (github.event_name == 'pull_request' &&
|
||||||
@@ -83,7 +106,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
@@ -91,13 +114,13 @@ jobs:
|
|||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up Java 17
|
- name: Set up Java 17
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: "17"
|
java-version: "17"
|
||||||
distribution: "adopt"
|
distribution: "adopt"
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
|
uses: docker/setup-buildx-action@f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca # v3.9.0
|
||||||
|
|
||||||
- name: Install Docker Compose
|
- name: Install Docker Compose
|
||||||
run: |
|
run: |
|
||||||
@@ -105,7 +128,7 @@ jobs:
|
|||||||
sudo chmod +x /usr/local/bin/docker-compose
|
sudo chmod +x /usr/local/bin/docker-compose
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
cache: 'pip' # caching pip dependencies
|
cache: 'pip' # caching pip dependencies
|
||||||
@@ -118,4 +141,4 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
chmod +x ./testing/test_webpages.sh
|
chmod +x ./testing/test_webpages.sh
|
||||||
chmod +x ./testing/test.sh
|
chmod +x ./testing/test.sh
|
||||||
./testing/test.sh "${{ github.event.pull_request.user.login == 'dependabot[bot]' }}"
|
./testing/test.sh
|
||||||
|
|||||||
4
.github/workflows/check_properties.yml
vendored
4
.github/workflows/check_properties.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/dependency-review.yml
vendored
2
.github/workflows/dependency-review.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
|
|||||||
21
.github/workflows/licenses-update.yml
vendored
21
.github/workflows/licenses-update.yml
vendored
@@ -18,13 +18,13 @@ jobs:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Generate GitHub App Token
|
- name: Generate GitHub App Token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
|
uses: actions/create-github-app-token@136412a57a7081aa63c935a2cc2918f76c34f514 # v1.11.2
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.GH_APP_ID }}
|
app-id: ${{ secrets.GH_APP_ID }}
|
||||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||||
@@ -33,15 +33,24 @@ jobs:
|
|||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: "17"
|
java-version: "17"
|
||||||
distribution: "adopt"
|
distribution: "adopt"
|
||||||
|
|
||||||
- uses: gradle/actions/setup-gradle@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
|
- uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0
|
||||||
|
|
||||||
- name: Run Gradle Command
|
- name: check the licenses for compatibility
|
||||||
run: ./gradlew clean generateLicenseReport
|
run: ./gradlew clean checkLicense
|
||||||
|
|
||||||
|
- name: FAILED - check the licenses for compatibility
|
||||||
|
if: failure()
|
||||||
|
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||||
|
with:
|
||||||
|
name: dependencies-without-allowed-license.json
|
||||||
|
path: |
|
||||||
|
build/reports/dependency-license/dependencies-without-allowed-license.json
|
||||||
|
retention-days: 3
|
||||||
|
|
||||||
- name: Move and Rename License File
|
- name: Move and Rename License File
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
4
.github/workflows/manage-label.yml
vendored
4
.github/workflows/manage-label.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
|||||||
issues: write
|
issues: write
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ jobs:
|
|||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Run Labeler
|
- name: Run Labeler
|
||||||
uses: crazy-max/ghaction-github-labeler@b54af0c25861143e7c8813d7cbbf46d2c341680c # v5.1.0
|
uses: crazy-max/ghaction-github-labeler@31674a3852a9074f2086abcf1c53839d466a47e7 # v5.2.0
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
yaml-file: .github/labels.yml
|
yaml-file: .github/labels.yml
|
||||||
|
|||||||
22
.github/workflows/multiOSReleases.yml
vendored
22
.github/workflows/multiOSReleases.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
|||||||
versionMac: ${{ steps.versionNumberMac.outputs.versionNumberMac }}
|
versionMac: ${{ steps.versionNumberMac.outputs.versionNumberMac }}
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
@@ -51,19 +51,19 @@ jobs:
|
|||||||
file_suffix: ""
|
file_suffix: ""
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up JDK 21
|
- name: Set up JDK 21
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: "21"
|
java-version: "21"
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
|
|
||||||
- uses: gradle/actions/setup-gradle@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
|
- uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0
|
||||||
with:
|
with:
|
||||||
gradle-version: 8.12
|
gradle-version: 8.12
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ jobs:
|
|||||||
file_suffix: ""
|
file_suffix: ""
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
@@ -139,19 +139,19 @@ jobs:
|
|||||||
contents: write
|
contents: write
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up JDK 21
|
- name: Set up JDK 21
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: "21"
|
java-version: "21"
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
|
|
||||||
- uses: gradle/actions/setup-gradle@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
|
- uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0
|
||||||
with:
|
with:
|
||||||
gradle-version: 8.12
|
gradle-version: 8.12
|
||||||
|
|
||||||
@@ -210,7 +210,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
@@ -224,7 +224,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install Cosign
|
- name: Install Cosign
|
||||||
if: matrix.os == 'windows-latest'
|
if: matrix.os == 'windows-latest'
|
||||||
uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0
|
uses: sigstore/cosign-installer@c56c2d3e59e4281cc41dea2217323ba5694b171e # v3.8.0
|
||||||
|
|
||||||
- name: Generate key pair
|
- name: Generate key pair
|
||||||
if: matrix.os == 'windows-latest'
|
if: matrix.os == 'windows-latest'
|
||||||
@@ -271,7 +271,7 @@ jobs:
|
|||||||
contents: write
|
contents: write
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
|
|||||||
6
.github/workflows/pre_commit.yml
vendored
6
.github/workflows/pre_commit.yml
vendored
@@ -16,13 +16,13 @@ jobs:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Generate GitHub App Token
|
- name: Generate GitHub App Token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
|
uses: actions/create-github-app-token@136412a57a7081aa63c935a2cc2918f76c34f514 # v1.11.2
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.GH_APP_ID }}
|
app-id: ${{ secrets.GH_APP_ID }}
|
||||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||||
@@ -42,7 +42,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
|
||||||
with:
|
with:
|
||||||
python-version: 3.12
|
python-version: 3.12
|
||||||
cache: 'pip' # caching pip dependencies
|
cache: 'pip' # caching pip dependencies
|
||||||
|
|||||||
19
.github/workflows/push-docker.yml
vendored
19
.github/workflows/push-docker.yml
vendored
@@ -18,19 +18,19 @@ jobs:
|
|||||||
id-token: write
|
id-token: write
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: "17"
|
java-version: "17"
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
|
|
||||||
- uses: gradle/actions/setup-gradle@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
|
- uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0
|
||||||
with:
|
with:
|
||||||
gradle-version: 8.12
|
gradle-version: 8.12
|
||||||
|
|
||||||
@@ -38,16 +38,17 @@ jobs:
|
|||||||
run: ./gradlew clean build
|
run: ./gradlew clean build
|
||||||
env:
|
env:
|
||||||
DOCKER_ENABLE_SECURITY: false
|
DOCKER_ENABLE_SECURITY: false
|
||||||
|
STIRLING_PDF_DESKTOP_UI: false
|
||||||
|
|
||||||
- name: Install cosign
|
- name: Install cosign
|
||||||
if: github.ref == 'refs/heads/master'
|
if: github.ref == 'refs/heads/master'
|
||||||
uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0
|
uses: sigstore/cosign-installer@c56c2d3e59e4281cc41dea2217323ba5694b171e # v3.8.0
|
||||||
with:
|
with:
|
||||||
cosign-release: "v2.4.1"
|
cosign-release: "v2.4.1"
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
id: buildx
|
id: buildx
|
||||||
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
|
uses: docker/setup-buildx-action@f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca # v3.9.0
|
||||||
|
|
||||||
- name: Get version number
|
- name: Get version number
|
||||||
id: versionNumber
|
id: versionNumber
|
||||||
@@ -67,7 +68,7 @@ jobs:
|
|||||||
password: ${{ github.token }}
|
password: ${{ github.token }}
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v3.3.0
|
uses: docker/setup-qemu-action@4574d27a4764455b42196d70a065bc6853246a25 # v3.4.0
|
||||||
|
|
||||||
- name: Convert repository owner to lowercase
|
- name: Convert repository owner to lowercase
|
||||||
id: repoowner
|
id: repoowner
|
||||||
@@ -89,7 +90,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build and push main Dockerfile
|
- name: Build and push main Dockerfile
|
||||||
id: build-push-regular
|
id: build-push-regular
|
||||||
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0
|
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
|
||||||
with:
|
with:
|
||||||
builder: ${{ steps.buildx.outputs.name }}
|
builder: ${{ steps.buildx.outputs.name }}
|
||||||
context: .
|
context: .
|
||||||
@@ -134,7 +135,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build and push Dockerfile-ultra-lite
|
- name: Build and push Dockerfile-ultra-lite
|
||||||
id: build-push-lite
|
id: build-push-lite
|
||||||
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0
|
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
|
||||||
if: github.ref != 'refs/heads/main'
|
if: github.ref != 'refs/heads/main'
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
@@ -165,7 +166,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build and push main Dockerfile fat
|
- name: Build and push main Dockerfile fat
|
||||||
id: build-push-fat
|
id: build-push-fat
|
||||||
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0
|
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
|
||||||
if: github.ref != 'refs/heads/main'
|
if: github.ref != 'refs/heads/main'
|
||||||
with:
|
with:
|
||||||
builder: ${{ steps.buildx.outputs.name }}
|
builder: ${{ steps.buildx.outputs.name }}
|
||||||
|
|||||||
12
.github/workflows/releaseArtifacts.yml
vendored
12
.github/workflows/releaseArtifacts.yml
vendored
@@ -23,19 +23,19 @@ jobs:
|
|||||||
version: ${{ steps.versionNumber.outputs.versionNumber }}
|
version: ${{ steps.versionNumber.outputs.versionNumber }}
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: "17"
|
java-version: "17"
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
|
|
||||||
- uses: gradle/actions/setup-gradle@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
|
- uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0
|
||||||
with:
|
with:
|
||||||
gradle-version: 8.12
|
gradle-version: 8.12
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ jobs:
|
|||||||
file_suffix: ""
|
file_suffix: ""
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ jobs:
|
|||||||
run: ls -R
|
run: ls -R
|
||||||
|
|
||||||
- name: Install Cosign
|
- name: Install Cosign
|
||||||
uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0
|
uses: sigstore/cosign-installer@c56c2d3e59e4281cc41dea2217323ba5694b171e # v3.8.0
|
||||||
|
|
||||||
- name: Generate key pair
|
- name: Generate key pair
|
||||||
run: cosign generate-key-pair
|
run: cosign generate-key-pair
|
||||||
@@ -161,7 +161,7 @@ jobs:
|
|||||||
file_suffix: ""
|
file_suffix: ""
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
|
|||||||
4
.github/workflows/scorecards.yml
vendored
4
.github/workflows/scorecards.yml
vendored
@@ -34,7 +34,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
@@ -74,6 +74,6 @@ jobs:
|
|||||||
|
|
||||||
# Upload the results to GitHub's code scanning dashboard.
|
# Upload the results to GitHub's code scanning dashboard.
|
||||||
- name: "Upload to code-scanning"
|
- name: "Upload to code-scanning"
|
||||||
uses: github/codeql-action/upload-sarif@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1
|
uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
|||||||
63
.github/workflows/sonarqube.yml
vendored
Normal file
63
.github/workflows/sonarqube.yml
vendored
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
name: Run Sonarqube
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request_target:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
pull-requests: read
|
||||||
|
actions: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
sonarqube:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Harden Runner
|
||||||
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
|
with:
|
||||||
|
egress-policy: audit
|
||||||
|
|
||||||
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Setup Gradle
|
||||||
|
uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0
|
||||||
|
|
||||||
|
- name: Build and analyze with Gradle
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||||
|
DOCKER_ENABLE_SECURITY: true
|
||||||
|
STIRLING_PDF_DESKTOP_UI: true
|
||||||
|
run: |
|
||||||
|
./gradlew clean build sonar \
|
||||||
|
-Dsonar.projectKey=Stirling-Tools_Stirling-PDF \
|
||||||
|
-Dsonar.organization=stirling-tools \
|
||||||
|
-Dsonar.host.url=https://sonarcloud.io \
|
||||||
|
-Dsonar.login=${SONAR_TOKEN} \
|
||||||
|
-Dsonar.log.level=DEBUG \
|
||||||
|
--info
|
||||||
|
|
||||||
|
- name: Upload Problems Report on Failure
|
||||||
|
if: failure()
|
||||||
|
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||||
|
with:
|
||||||
|
name: gradle-problems-report
|
||||||
|
path: build/reports/problems/problems-report.html
|
||||||
|
retention-days: 7
|
||||||
|
|
||||||
|
- name: Upload Sonar Logs on Failure
|
||||||
|
if: failure()
|
||||||
|
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||||
|
with:
|
||||||
|
name: sonar-logs
|
||||||
|
path: |
|
||||||
|
.scannerwork/report-task.txt
|
||||||
|
build/sonar/
|
||||||
|
retention-days: 7
|
||||||
4
.github/workflows/stale.yml
vendored
4
.github/workflows/stale.yml
vendored
@@ -16,12 +16,12 @@ jobs:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: 30 days stale issues
|
- name: 30 days stale issues
|
||||||
uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0
|
uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
days-before-stale: 30
|
days-before-stale: 30
|
||||||
|
|||||||
6
.github/workflows/swagger.yml
vendored
6
.github/workflows/swagger.yml
vendored
@@ -14,19 +14,19 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: "17"
|
java-version: "17"
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
|
|
||||||
- uses: gradle/actions/setup-gradle@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
|
- uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0
|
||||||
|
|
||||||
- name: Generate Swagger documentation
|
- name: Generate Swagger documentation
|
||||||
run: ./gradlew generateOpenApiDocs
|
run: ./gradlew generateOpenApiDocs
|
||||||
|
|||||||
39
.github/workflows/sync_files.yml
vendored
39
.github/workflows/sync_files.yml
vendored
@@ -8,8 +8,6 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- "build.gradle"
|
- "build.gradle"
|
||||||
- "README.md"
|
- "README.md"
|
||||||
- "gradle/verification-keyring.keys"
|
|
||||||
- "gradle/verification-metadata.xml"
|
|
||||||
- "src/main/resources/messages_*.properties"
|
- "src/main/resources/messages_*.properties"
|
||||||
- "src/main/resources/static/3rdPartyLicenses.json"
|
- "src/main/resources/static/3rdPartyLicenses.json"
|
||||||
- "scripts/ignore_translation.toml"
|
- "scripts/ignore_translation.toml"
|
||||||
@@ -26,13 +24,13 @@ jobs:
|
|||||||
committer: ${{ steps.committer.outputs.committer }}
|
committer: ${{ steps.committer.outputs.committer }}
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Generate GitHub App Token
|
- name: Generate GitHub App Token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
|
uses: actions/create-github-app-token@136412a57a7081aa63c935a2cc2918f76c34f514 # v1.11.2
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.GH_APP_ID }}
|
app-id: ${{ secrets.GH_APP_ID }}
|
||||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||||
@@ -59,13 +57,13 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Generate GitHub App Token
|
- name: Generate GitHub App Token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
|
uses: actions/create-github-app-token@136412a57a7081aa63c935a2cc2918f76c34f514 # v1.11.2
|
||||||
with:
|
with:
|
||||||
app-id: ${{ vars.GH_APP_ID }}
|
app-id: ${{ vars.GH_APP_ID }}
|
||||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||||
@@ -73,7 +71,7 @@ jobs:
|
|||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
cache: 'pip' # caching pip dependencies
|
cache: 'pip' # caching pip dependencies
|
||||||
@@ -104,22 +102,6 @@ jobs:
|
|||||||
git add README.md
|
git add README.md
|
||||||
git diff --staged --quiet || git commit -m ":memo: Sync README.md" || echo "no changes"
|
git diff --staged --quiet || git commit -m ":memo: Sync README.md" || echo "no changes"
|
||||||
|
|
||||||
- name: Generate verification metadata with signatures and checksums
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
if [ -f ./gradle/verification-metadata.xml ]; then
|
|
||||||
rm ./gradle/verification-metadata.xml
|
|
||||||
fi
|
|
||||||
./gradlew clean dependencies buildEnvironment spotlessApply --write-verification-metadata sha256 help
|
|
||||||
./gradlew clean dependencies buildEnvironment spotlessApply --write-verification-metadata sha256,pgp --refresh-keys --export-keys --refresh-dependencies help
|
|
||||||
./gradlew clean build
|
|
||||||
|
|
||||||
- name: Run git add
|
|
||||||
run: |
|
|
||||||
git add gradle/verification-keyring.keys
|
|
||||||
git add gradle/verification-metadata.xml
|
|
||||||
git diff --staged --quiet || git commit -m ":memo: Generate verification metadata with signatures and checksums" || echo "no changes"
|
|
||||||
|
|
||||||
- name: Create Pull Request
|
- name: Create Pull Request
|
||||||
uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # v7.0.6
|
uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # v7.0.6
|
||||||
with:
|
with:
|
||||||
@@ -129,11 +111,11 @@ jobs:
|
|||||||
author: ${{ needs.read_bot_entries.outputs.committer }}
|
author: ${{ needs.read_bot_entries.outputs.committer }}
|
||||||
signoff: true
|
signoff: true
|
||||||
branch: sync_readme
|
branch: sync_readme
|
||||||
title: ":globe_with_meridians: Sync Translations + Update README Progress Table + Update Verification Metadata"
|
title: ":globe_with_meridians: Sync Translations + Update README Progress Table"
|
||||||
body: |
|
body: |
|
||||||
### Description of Changes
|
### Description of Changes
|
||||||
|
|
||||||
This Pull Request was automatically generated to synchronize updates to translation files, verification metadata, and documentation. Below are the details of the changes made:
|
This Pull Request was automatically generated to synchronize updates to translation files and documentation. Below are the details of the changes made:
|
||||||
|
|
||||||
#### **1. Synchronization of Translation Files**
|
#### **1. Synchronization of Translation Files**
|
||||||
- Updated translation files (`messages_*.properties`) to reflect changes in the reference file `messages_en_GB.properties`.
|
- Updated translation files (`messages_*.properties`) to reflect changes in the reference file `messages_en_GB.properties`.
|
||||||
@@ -145,14 +127,9 @@ jobs:
|
|||||||
- Added a summary of the current translation status for all supported languages.
|
- Added a summary of the current translation status for all supported languages.
|
||||||
- Included up-to-date statistics on translation coverage.
|
- Included up-to-date statistics on translation coverage.
|
||||||
|
|
||||||
#### **3. Verification Metadata Updates**
|
|
||||||
- Generated or refreshed the `verification-keyring.keys` and `verification-metadata.xml` files.
|
|
||||||
- Included the latest dependency signatures and checksums to enhance the build's integrity.
|
|
||||||
|
|
||||||
#### **Why these changes are necessary**
|
#### **Why these changes are necessary**
|
||||||
- Keeps translation files aligned with the latest reference updates.
|
- Keeps translation files aligned with the latest reference updates.
|
||||||
- Ensures the documentation reflects the current translation progress.
|
- Ensures the documentation reflects the current translation progress.
|
||||||
- Strengthens dependency verification for a more secure build process.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -166,5 +143,3 @@ jobs:
|
|||||||
add-paths: |
|
add-paths: |
|
||||||
README.md
|
README.md
|
||||||
src/main/resources/messages_*.properties
|
src/main/resources/messages_*.properties
|
||||||
gradle/verification-keyring.keys
|
|
||||||
gradle/verification-metadata.xml
|
|
||||||
|
|||||||
14
.github/workflows/testdriver.yml
vendored
14
.github/workflows/testdriver.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ jobs:
|
|||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up JDK
|
- name: Set up JDK
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
@@ -31,7 +31,7 @@ jobs:
|
|||||||
DOCKER_ENABLE_SECURITY: false
|
DOCKER_ENABLE_SECURITY: false
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
|
uses: docker/setup-buildx-action@f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca # v3.9.0
|
||||||
|
|
||||||
- name: Get version number
|
- name: Get version number
|
||||||
id: versionNumber
|
id: versionNumber
|
||||||
@@ -46,7 +46,7 @@ jobs:
|
|||||||
password: ${{ secrets.DOCKER_HUB_API }}
|
password: ${{ secrets.DOCKER_HUB_API }}
|
||||||
|
|
||||||
- name: Build and push test image
|
- name: Build and push test image
|
||||||
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0
|
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
@@ -105,14 +105,14 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Run TestDriver.ai
|
- name: Run TestDriver.ai
|
||||||
uses: testdriverai/action@47e87c5d50beeeb3da624b2d9b5c1391269d6d22 #1.0.0
|
uses: testdriverai/action@f0d0f45fdd684db628baa843fe9313f3ca3a8aa8 #1.1.3
|
||||||
with:
|
with:
|
||||||
key: ${{secrets.TESTDRIVER_API_KEY}}
|
key: ${{secrets.TESTDRIVER_API_KEY}}
|
||||||
prerun: |
|
prerun: |
|
||||||
@@ -134,7 +134,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -140,6 +140,7 @@ venv.bak/
|
|||||||
# VS Code
|
# VS Code
|
||||||
/.vscode/**/*
|
/.vscode/**/*
|
||||||
!/.vscode/settings.json
|
!/.vscode/settings.json
|
||||||
|
!/.vscode/extensions.json
|
||||||
|
|
||||||
# IntelliJ IDEA
|
# IntelliJ IDEA
|
||||||
.idea/
|
.idea/
|
||||||
|
|||||||
24
.vscode/extensions.json
vendored
Normal file
24
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"elagil.pre-commit-helper", // Support for pre-commit hooks to enforce code quality
|
||||||
|
"josevseb.google-java-format-for-vs-code", // Google Java code formatter to follow the Google Java Style Guide
|
||||||
|
"ms-python.black-formatter", // Python code formatter using Black
|
||||||
|
"ms-python.flake8", // Flake8 linter for Python to enforce code quality
|
||||||
|
"ms-python.python", // Official Microsoft Python extension with IntelliSense, debugging, and Jupyter support
|
||||||
|
// "ms-vscode-remote.remote-containers", // Support for remote development with containers (Docker, Dev Containers)
|
||||||
|
// "ms-vscode-remote.vscode-remote-extensionpack", // Remote Development Pack for SSH, WSL, and Containers
|
||||||
|
"Oracle.oracle-java", // Oracle Java extension with additional features for Java development
|
||||||
|
"redhat.java", // Java support by Red Hat with IntelliSense, debugging, and code navigation
|
||||||
|
"shengchen.vscode-checkstyle", // Checkstyle integration for Java code quality checks
|
||||||
|
"streetsidesoftware.code-spell-checker", // Spell checker for code to avoid typos
|
||||||
|
"vmware.vscode-boot-dev-pack", // Developer tools for Spring Boot by VMware
|
||||||
|
"vmware.vscode-spring-boot", // Spring Boot tools by VMware for enhanced Spring development
|
||||||
|
"vscjava.vscode-gradle", // Gradle extension for build and automation support
|
||||||
|
"vscjava.vscode-java-debug", // Debugging support for Java projects
|
||||||
|
"vscjava.vscode-java-dependency", // Java dependency management within VS Code
|
||||||
|
"vscjava.vscode-java-pack", // Java Extension Pack with essential Java tools for VS Code
|
||||||
|
"vscjava.vscode-java-test", // Java test framework for running and debugging tests in VS Code
|
||||||
|
"vscjava.vscode-spring-boot-dashboard", // Spring Boot dashboard for managing and visualizing Spring Boot applications
|
||||||
|
"vscjava.vscode-spring-initializr" // Support for Spring Initializr to create new Spring projects
|
||||||
|
]
|
||||||
|
}
|
||||||
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -40,7 +40,7 @@
|
|||||||
"files.insertFinalNewline": false
|
"files.insertFinalNewline": false
|
||||||
},
|
},
|
||||||
"diffEditor.maxComputationTime": 0,
|
"diffEditor.maxComputationTime": 0,
|
||||||
"editor.wordSegmenterLocales": null,
|
"editor.wordSegmenterLocales": "",
|
||||||
"editor.guides.bracketPairs": "active",
|
"editor.guides.bracketPairs": "active",
|
||||||
"editor.guides.bracketPairsHorizontal": "active",
|
"editor.guides.bracketPairsHorizontal": "active",
|
||||||
"files.insertFinalNewline": true,
|
"files.insertFinalNewline": true,
|
||||||
@@ -50,6 +50,9 @@
|
|||||||
"editor.stickyScroll.enabled": false,
|
"editor.stickyScroll.enabled": false,
|
||||||
"editor.minimap.enabled": false,
|
"editor.minimap.enabled": false,
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
|
"java.format.enabled": true,
|
||||||
|
"java.format.settings.profile": "GoogleStyle",
|
||||||
|
"java.format.settings.google.version": "1.25.2",
|
||||||
"java.format.settings.google.mode": "jar-file",
|
"java.format.settings.google.mode": "jar-file",
|
||||||
"java.format.settings.google.extra": "--aosp --skip-sorting-imports"
|
"java.format.settings.google.extra": "--aosp --skip-sorting-imports"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,16 @@ Stirling-PDF is built using:
|
|||||||
2. Install Docker and JDK17 if not already installed.
|
2. Install Docker and JDK17 if not already installed.
|
||||||
|
|
||||||
3. Install a recommended Java IDE such as Eclipse, IntelliJ, or VSCode
|
3. Install a recommended Java IDE such as Eclipse, IntelliJ, or VSCode
|
||||||
|
1. Only VSCode
|
||||||
|
1. Open VS Code.
|
||||||
|
2. When prompted, install the recommended extensions.
|
||||||
|
3. Alternatively, open the command palette (`Ctrl + Shift + P` or `Cmd + Shift + P` on macOS) and run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
Extensions: Show Recommended Extensions
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Install the required extensions from the list.
|
||||||
|
|
||||||
4. Lombok Setup
|
4. Lombok Setup
|
||||||
Stirling-PDF uses Lombok to reduce boilerplate code. Some IDEs, like Eclipse, don't support Lombok out of the box. To set up Lombok in your development environment:
|
Stirling-PDF uses Lombok to reduce boilerplate code. Some IDEs, like Eclipse, don't support Lombok out of the box. To set up Lombok in your development environment:
|
||||||
@@ -575,42 +585,3 @@ In your Thymeleaf templates, use the `#{key}` syntax to reference the new transl
|
|||||||
```
|
```
|
||||||
|
|
||||||
Remember, never hard-code text in your templates or Java code. Always use translation keys to ensure proper localization.
|
Remember, never hard-code text in your templates or Java code. Always use translation keys to ensure proper localization.
|
||||||
|
|
||||||
|
|
||||||
## Managing Dependencies
|
|
||||||
|
|
||||||
When adding new dependencies or updating existing ones in Stirling-PDF, follow these steps to ensure proper verification and security:
|
|
||||||
|
|
||||||
1. Update the dependency in `build.gradle`:
|
|
||||||
```groovy
|
|
||||||
dependencies {
|
|
||||||
// Add or update your dependency
|
|
||||||
implementation "com.example:new-library:1.2.3"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Generate new verification metadata and keys:
|
|
||||||
```bash
|
|
||||||
# Generate verification metadata with signatures and checksums
|
|
||||||
./gradlew clean dependencies buildEnvironment spotlessApply --write-verification-metadata sha256,pgp
|
|
||||||
|
|
||||||
# Export the .keys file
|
|
||||||
./gradlew --export-keys
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Files to commit:
|
|
||||||
- `build.gradle` - Your dependency changes
|
|
||||||
- `gradle/verification-metadata.xml` - Contains verification rules and checksums
|
|
||||||
- `gradle/verification-keyring.keys` - Contains PGP keys in text format
|
|
||||||
|
|
||||||
4. Verify the build works with the new verification:
|
|
||||||
```bash
|
|
||||||
./gradlew build
|
|
||||||
```
|
|
||||||
|
|
||||||
5. Before committing, check:
|
|
||||||
- Verify any new BOM files are properly handled in verification metadata
|
|
||||||
- Review the changes in `verification-metadata.xml` to ensure they match your dependency updates
|
|
||||||
|
|
||||||
This ensures dependencies are properly verified and secure while maintaining transparency in the repository.
|
|
||||||
|
|
||||||
|
|||||||
29
Dockerfile
29
Dockerfile
@@ -1,5 +1,5 @@
|
|||||||
# Main stage
|
# Main stage
|
||||||
FROM alpine:3.21.2@sha256:56fa17d2a7e7f168a043a2712e63aed1f8543aeafdcee47c58dcffe38ed51099
|
FROM alpine:3.21.3@sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c
|
||||||
|
|
||||||
# Copy necessary files
|
# Copy necessary files
|
||||||
COPY scripts /scripts
|
COPY scripts /scripts
|
||||||
@@ -35,12 +35,15 @@ ENV DOCKER_ENABLE_SECURITY=false \
|
|||||||
HOME=/home/stirlingpdfuser \
|
HOME=/home/stirlingpdfuser \
|
||||||
PUID=1000 \
|
PUID=1000 \
|
||||||
PGID=1000 \
|
PGID=1000 \
|
||||||
UMASK=022
|
UMASK=022 \
|
||||||
|
PYTHONPATH=/usr/lib/libreoffice/program:/opt/venv/lib/python3.12/site-packages \
|
||||||
|
UNO_PATH=/usr/lib/libreoffice/program \
|
||||||
|
URE_BOOTSTRAP=file:///usr/lib/libreoffice/program/fundamentalrc
|
||||||
|
|
||||||
|
|
||||||
# JDK for app
|
# JDK for app
|
||||||
RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
|
RUN echo "@main 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 "@community 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 upgrade --no-cache -a && \
|
apk upgrade --no-cache -a && \
|
||||||
apk add --no-cache \
|
apk add --no-cache \
|
||||||
@@ -56,6 +59,8 @@ RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /et
|
|||||||
openssl-dev \
|
openssl-dev \
|
||||||
openjdk21-jre \
|
openjdk21-jre \
|
||||||
# Doc conversion
|
# Doc conversion
|
||||||
|
gcompat \
|
||||||
|
libc6-compat \
|
||||||
libreoffice \
|
libreoffice \
|
||||||
# pdftohtml
|
# pdftohtml
|
||||||
poppler-utils \
|
poppler-utils \
|
||||||
@@ -63,11 +68,17 @@ RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /et
|
|||||||
tesseract-ocr-data-eng \
|
tesseract-ocr-data-eng \
|
||||||
# CV
|
# CV
|
||||||
py3-opencv \
|
py3-opencv \
|
||||||
# python3/pip
|
|
||||||
python3 \
|
python3 \
|
||||||
py3-pip && \
|
py3-pip \
|
||||||
# uno unoconv and HTML
|
py3-pillow@testing \
|
||||||
pip install --break-system-packages --no-cache-dir --upgrade unoconv WeasyPrint pdf2image pillow && \
|
py3-pdf2image@testing && \
|
||||||
|
python3 -m venv /opt/venv && \
|
||||||
|
export PATH="/opt/venv/bin:$PATH" && \
|
||||||
|
pip install --upgrade pip && \
|
||||||
|
pip install --no-cache-dir --upgrade unoserver weasyprint && \
|
||||||
|
ln -s /usr/lib/libreoffice/program/uno.py /opt/venv/lib/python3.12/site-packages/ && \
|
||||||
|
ln -s /usr/lib/libreoffice/program/unohelper.py /opt/venv/lib/python3.12/site-packages/ && \
|
||||||
|
ln -s /usr/lib/libreoffice/program /opt/venv/lib/python3.12/site-packages/LibreOffice && \
|
||||||
mv /usr/share/tessdata /usr/share/tessdata-original && \
|
mv /usr/share/tessdata /usr/share/tessdata-original && \
|
||||||
mkdir -p $HOME /configs /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders && \
|
mkdir -p $HOME /configs /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders && \
|
||||||
fc-cache -f -v && \
|
fc-cache -f -v && \
|
||||||
@@ -82,4 +93,4 @@ EXPOSE 8080/tcp
|
|||||||
|
|
||||||
# Set user and run command
|
# Set user and run command
|
||||||
ENTRYPOINT ["tini", "--", "/scripts/init.sh"]
|
ENTRYPOINT ["tini", "--", "/scripts/init.sh"]
|
||||||
CMD ["java", "-Dfile.encoding=UTF-8", "-jar", "/app.jar"]
|
CMD ["sh", "-c", "java -Dfile.encoding=UTF-8 -jar /app.jar & /opt/venv/bin/unoserver --port 2003 --interface 0.0.0.0"]
|
||||||
@@ -9,10 +9,11 @@ COPY . .
|
|||||||
|
|
||||||
# Build the application with DOCKER_ENABLE_SECURITY=false
|
# Build the application with DOCKER_ENABLE_SECURITY=false
|
||||||
RUN DOCKER_ENABLE_SECURITY=true \
|
RUN DOCKER_ENABLE_SECURITY=true \
|
||||||
|
STIRLING_PDF_DESKTOP_UI=false \
|
||||||
./gradlew clean build
|
./gradlew clean build
|
||||||
|
|
||||||
# Main stage
|
# Main stage
|
||||||
FROM alpine:3.21.2@sha256:56fa17d2a7e7f168a043a2712e63aed1f8543aeafdcee47c58dcffe38ed51099
|
FROM alpine:3.21.3@sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c
|
||||||
|
|
||||||
# Copy necessary files
|
# Copy necessary files
|
||||||
COPY scripts /scripts
|
COPY scripts /scripts
|
||||||
@@ -37,12 +38,15 @@ ENV DOCKER_ENABLE_SECURITY=false \
|
|||||||
PGID=1000 \
|
PGID=1000 \
|
||||||
UMASK=022 \
|
UMASK=022 \
|
||||||
FAT_DOCKER=true \
|
FAT_DOCKER=true \
|
||||||
INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false
|
INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false \
|
||||||
|
PYTHONPATH=/usr/lib/libreoffice/program:/opt/venv/lib/python3.12/site-packages \
|
||||||
|
UNO_PATH=/usr/lib/libreoffice/program \
|
||||||
|
URE_BOOTSTRAP=file:///usr/lib/libreoffice/program/fundamentalrc
|
||||||
|
|
||||||
|
|
||||||
# JDK for app
|
# JDK for app
|
||||||
RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
|
RUN echo "@main 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 "@community 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 upgrade --no-cache -a && \
|
apk upgrade --no-cache -a && \
|
||||||
apk add --no-cache \
|
apk add --no-cache \
|
||||||
@@ -57,20 +61,29 @@ RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /et
|
|||||||
openssl-dev \
|
openssl-dev \
|
||||||
openjdk21-jre \
|
openjdk21-jre \
|
||||||
# Doc conversion
|
# Doc conversion
|
||||||
|
gcompat \
|
||||||
|
libc6-compat \
|
||||||
libreoffice \
|
libreoffice \
|
||||||
# pdftohtml
|
# pdftohtml
|
||||||
poppler-utils \
|
poppler-utils \
|
||||||
# OCR MY PDF (unpaper for descew and other advanced featues)
|
# OCR MY PDF (unpaper for descew and other advanced featues)
|
||||||
qpdf \
|
qpdf \
|
||||||
tesseract-ocr-data-eng \
|
tesseract-ocr-data-eng \
|
||||||
|
|
||||||
font-terminus font-dejavu font-noto font-noto-cjk font-awesome font-noto-extra \
|
font-terminus font-dejavu font-noto font-noto-cjk font-awesome font-noto-extra \
|
||||||
# CV
|
# CV
|
||||||
py3-opencv \
|
py3-opencv \
|
||||||
# python3/pip
|
|
||||||
python3 \
|
python3 \
|
||||||
py3-pip && \
|
py3-pip \
|
||||||
# uno unoconv and HTML
|
py3-pillow@testing \
|
||||||
pip install --break-system-packages --no-cache-dir --upgrade unoconv WeasyPrint pdf2image pillow && \
|
py3-pdf2image@testing && \
|
||||||
|
python3 -m venv /opt/venv && \
|
||||||
|
export PATH="/opt/venv/bin:$PATH" && \
|
||||||
|
pip install --upgrade pip && \
|
||||||
|
pip install --no-cache-dir --upgrade unoserver weasyprint && \
|
||||||
|
ln -s /usr/lib/libreoffice/program/uno.py /opt/venv/lib/python3.12/site-packages/ && \
|
||||||
|
ln -s /usr/lib/libreoffice/program/unohelper.py /opt/venv/lib/python3.12/site-packages/ && \
|
||||||
|
ln -s /usr/lib/libreoffice/program /opt/venv/lib/python3.12/site-packages/LibreOffice && \
|
||||||
mv /usr/share/tessdata /usr/share/tessdata-original && \
|
mv /usr/share/tessdata /usr/share/tessdata-original && \
|
||||||
mkdir -p $HOME /configs /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders && \
|
mkdir -p $HOME /configs /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders && \
|
||||||
fc-cache -f -v && \
|
fc-cache -f -v && \
|
||||||
@@ -82,7 +95,6 @@ RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /et
|
|||||||
chown stirlingpdfuser:stirlingpdfgroup /app.jar
|
chown stirlingpdfuser:stirlingpdfgroup /app.jar
|
||||||
|
|
||||||
EXPOSE 8080/tcp
|
EXPOSE 8080/tcp
|
||||||
|
|
||||||
# Set user and run command
|
# Set user and run command
|
||||||
ENTRYPOINT ["tini", "--", "/scripts/init.sh"]
|
ENTRYPOINT ["tini", "--", "/scripts/init.sh"]
|
||||||
CMD ["java", "-Dfile.encoding=UTF-8", "-jar", "/app.jar"]
|
CMD ["sh", "-c", "java -Dfile.encoding=UTF-8 -jar /app.jar & /opt/venv/bin/unoserver --port 2003 --interface 0.0.0.0"]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# use alpine
|
# use alpine
|
||||||
FROM alpine:3.21.2@sha256:56fa17d2a7e7f168a043a2712e63aed1f8543aeafdcee47c58dcffe38ed51099
|
FROM alpine:3.21.3@sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c
|
||||||
|
|
||||||
ARG VERSION_TAG
|
ARG VERSION_TAG
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,7 @@ Any SVG flags are fine; most of the current ones were sourced from [here](https:
|
|||||||
For example, to add Polish, you would add:
|
For example, to add Polish, you would add:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="pl_PL">
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'pl_PL')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="pl_PL"> <img th:src="@{'/images/flags/pl.svg'}" alt="icon" width="20" height="15"> Polski</a>
|
||||||
<img src="images/flags/pl.svg" alt="icon" width="20" height="15"> Polski
|
|
||||||
</a>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The `data-bs-language-code` is the code used to reference the file in the next step.
|
The `data-bs-language-code` is the code used to reference the file in the next step.
|
||||||
|
|||||||
59
README.md
59
README.md
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
[](https://hub.docker.com/r/frooodle/s-pdf)
|
[](https://hub.docker.com/r/frooodle/s-pdf)
|
||||||
[](https://discord.gg/HYmhKj45pU)
|
[](https://discord.gg/HYmhKj45pU)
|
||||||
[](https://github.com/Stirling-Tools/Stirling-PDF/)
|
|
||||||
[](https://scorecard.dev/viewer/?uri=github.com/Stirling-Tools/Stirling-PDF)
|
[](https://scorecard.dev/viewer/?uri=github.com/Stirling-Tools/Stirling-PDF)
|
||||||
[](https://github.com/Stirling-Tools/stirling-pdf)
|
[](https://github.com/Stirling-Tools/stirling-pdf)
|
||||||
|
|
||||||
@@ -117,46 +116,46 @@ Stirling-PDF currently supports 39 languages!
|
|||||||
|
|
||||||
| Language | Progress |
|
| Language | Progress |
|
||||||
| -------------------------------------------- | -------------------------------------- |
|
| -------------------------------------------- | -------------------------------------- |
|
||||||
| Arabic (العربية) (ar_AR) |  |
|
| Arabic (العربية) (ar_AR) |  |
|
||||||
| Azerbaijani (Azərbaycan Dili) (az_AZ) |  |
|
| Azerbaijani (Azərbaycan Dili) (az_AZ) |  |
|
||||||
| Basque (Euskara) (eu_ES) |  |
|
| Basque (Euskara) (eu_ES) |  |
|
||||||
| Bulgarian (Български) (bg_BG) |  |
|
| Bulgarian (Български) (bg_BG) |  |
|
||||||
| Catalan (Català) (ca_CA) |  |
|
| Catalan (Català) (ca_CA) |  |
|
||||||
| Croatian (Hrvatski) (hr_HR) |  |
|
| Croatian (Hrvatski) (hr_HR) |  |
|
||||||
| Czech (Česky) (cs_CZ) |  |
|
| Czech (Česky) (cs_CZ) |  |
|
||||||
| Danish (Dansk) (da_DK) |  |
|
| Danish (Dansk) (da_DK) |  |
|
||||||
| Dutch (Nederlands) (nl_NL) |  |
|
| Dutch (Nederlands) (nl_NL) |  |
|
||||||
| English (English) (en_GB) |  |
|
| English (English) (en_GB) |  |
|
||||||
| English (US) (en_US) |  |
|
| English (US) (en_US) |  |
|
||||||
| French (Français) (fr_FR) |  |
|
| French (Français) (fr_FR) |  |
|
||||||
| German (Deutsch) (de_DE) |  |
|
| German (Deutsch) (de_DE) |  |
|
||||||
| Greek (Ελληνικά) (el_GR) |  |
|
| Greek (Ελληνικά) (el_GR) |  |
|
||||||
| Hindi (हिंदी) (hi_IN) |  |
|
| Hindi (हिंदी) (hi_IN) |  |
|
||||||
| Hungarian (Magyar) (hu_HU) |  |
|
| Hungarian (Magyar) (hu_HU) |  |
|
||||||
| Indonesian (Bahasa Indonesia) (id_ID) |  |
|
| Indonesian (Bahasa Indonesia) (id_ID) |  |
|
||||||
| Irish (Gaeilge) (ga_IE) |  |
|
| Irish (Gaeilge) (ga_IE) |  |
|
||||||
| Italian (Italiano) (it_IT) |  |
|
| Italian (Italiano) (it_IT) |  |
|
||||||
| Japanese (日本語) (ja_JP) |  |
|
| Japanese (日本語) (ja_JP) |  |
|
||||||
| Korean (한국어) (ko_KR) |  |
|
| Korean (한국어) (ko_KR) |  |
|
||||||
| Norwegian (Norsk) (no_NB) |  |
|
| Norwegian (Norsk) (no_NB) |  |
|
||||||
| Persian (فارسی) (fa_IR) |  |
|
| Persian (فارسی) (fa_IR) |  |
|
||||||
| Polish (Polski) (pl_PL) |  |
|
| Polish (Polski) (pl_PL) |  |
|
||||||
| Portuguese (Português) (pt_PT) |  |
|
| Portuguese (Português) (pt_PT) |  |
|
||||||
| Portuguese Brazilian (Português) (pt_BR) |  |
|
| Portuguese Brazilian (Português) (pt_BR) |  |
|
||||||
| Romanian (Română) (ro_RO) |  |
|
| Romanian (Română) (ro_RO) |  |
|
||||||
| Russian (Русский) (ru_RU) |  |
|
| Russian (Русский) (ru_RU) |  |
|
||||||
| Serbian Latin alphabet (Srpski) (sr_LATN_RS) |  |
|
| Serbian Latin alphabet (Srpski) (sr_LATN_RS) |  |
|
||||||
| Simplified Chinese (简体中文) (zh_CN) |  |
|
| Simplified Chinese (简体中文) (zh_CN) |  |
|
||||||
| Slovakian (Slovensky) (sk_SK) |  |
|
| Slovakian (Slovensky) (sk_SK) |  |
|
||||||
| Slovenian (Slovenščina) (sl_SI) |  |
|
| Slovenian (Slovenščina) (sl_SI) |  |
|
||||||
| Spanish (Español) (es_ES) |  |
|
| Spanish (Español) (es_ES) |  |
|
||||||
| Swedish (Svenska) (sv_SE) |  |
|
| Swedish (Svenska) (sv_SE) |  |
|
||||||
| Thai (ไทย) (th_TH) |  |
|
| Thai (ไทย) (th_TH) |  |
|
||||||
| Tibetan (བོད་ཡིག་) (zh_BO) |  |
|
| Tibetan (བོད་ཡིག་) (zh_BO) |  |
|
||||||
| Traditional Chinese (繁體中文) (zh_TW) |  |
|
| Traditional Chinese (繁體中文) (zh_TW) |  |
|
||||||
| Turkish (Türkçe) (tr_TR) |  |
|
| Turkish (Türkçe) (tr_TR) |  |
|
||||||
| Ukrainian (Українська) (uk_UA) |  |
|
| Ukrainian (Українська) (uk_UA) |  |
|
||||||
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
||||||
|
|
||||||
|
|
||||||
## Stirling PDF Enterprise
|
## Stirling PDF Enterprise
|
||||||
|
|||||||
164
allowed-licenses.json
Normal file
164
allowed-licenses.json
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
{
|
||||||
|
"allowedLicenses": [
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "BSD License"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "The BSD License"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "BSD-2-Clause"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "BSD 2-Clause License"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "The 2-Clause BSD License"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "BSD-3-Clause"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "The BSD 3-Clause License (BSD3)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "BSD-4 License"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "MIT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "MIT License"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "The MIT License"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": "com.github.jai-imageio:jai-imageio-core",
|
||||||
|
"moduleLicense": "LICENSE.txt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": "com.github.jai-imageio:jai-imageio-jpeg2000",
|
||||||
|
"moduleLicense": "LICENSE-JJ2000.txt, LICENSE-Sun.txt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Apache 2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Apache 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Apache-2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Apache-2.0 License"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Apache License 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Apache License Version 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Apache License, Version 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "The Apache License, Version 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "The Apache Software License, Version 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": "com.nimbusds:oauth2-oidc-sdk",
|
||||||
|
"moduleLicense": "\"Apache License, version 2.0\";link=\"https://www.apache.org/licenses/LICENSE-2.0.html\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "MPL 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "UnboundID SCIM2 SDK Free Use License"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "GPL2 w/ CPE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "GPLv2+CE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "GNU GENERAL PUBLIC LICENSE, Version 2 + Classpath Exception"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": "com.martiansoftware:jsap",
|
||||||
|
"moduleLicense": "LGPL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": "org.hibernate.orm:hibernate-core",
|
||||||
|
"moduleLicense": "GNU Library General Public License v2.1 or later"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Eclipse Public License - v 1.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Eclipse Public License v. 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Eclipse Public License - v 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Eclipse Public License - Version 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Eclipse Public License, Version 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Ubuntu Font Licence 1.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Bouncy Castle Licence"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Public Domain, per Creative Commons CC0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "The W3C License"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
51
build.gradle
51
build.gradle
@@ -8,15 +8,15 @@ plugins {
|
|||||||
id "com.diffplug.spotless" version "7.0.2"
|
id "com.diffplug.spotless" version "7.0.2"
|
||||||
id "com.github.jk1.dependency-license-report" version "2.9"
|
id "com.github.jk1.dependency-license-report" version "2.9"
|
||||||
//id "nebula.lint" version "19.0.3"
|
//id "nebula.lint" version "19.0.3"
|
||||||
id("org.panteleyev.jpackageplugin") version "1.6.0"
|
id("org.panteleyev.jpackageplugin") version "1.6.1"
|
||||||
|
id "org.sonarqube" version "6.0.1.5171"
|
||||||
}
|
}
|
||||||
|
|
||||||
import com.github.jk1.license.render.*
|
import com.github.jk1.license.render.*
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
springBootVersion = "3.4.1"
|
springBootVersion = "3.4.2"
|
||||||
pdfboxVersion = "3.0.3"
|
pdfboxVersion = "3.0.4"
|
||||||
logbackVersion = "1.5.7"
|
|
||||||
imageioVersion = "3.12.0"
|
imageioVersion = "3.12.0"
|
||||||
lombokVersion = "1.18.36"
|
lombokVersion = "1.18.36"
|
||||||
bouncycastleVersion = "1.80"
|
bouncycastleVersion = "1.80"
|
||||||
@@ -25,8 +25,7 @@ ext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "stirling.software"
|
group = "stirling.software"
|
||||||
version = "0.39.0"
|
version = "0.42.0"
|
||||||
|
|
||||||
|
|
||||||
java {
|
java {
|
||||||
// 17 is lowest but we support and recommend 21
|
// 17 is lowest but we support and recommend 21
|
||||||
@@ -35,14 +34,13 @@ java {
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven { url = "https://jitpack.io" }
|
|
||||||
maven { url = "https://build.shibboleth.net/maven/releases" }
|
maven { url = "https://build.shibboleth.net/maven/releases" }
|
||||||
maven { url = "https://maven.pkg.github.com/jcefmaven/jcefmaven" }
|
maven { url = "https://maven.pkg.github.com/jcefmaven/jcefmaven" }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
licenseReport {
|
licenseReport {
|
||||||
renderers = [new JsonReportRenderer()]
|
renderers = [new JsonReportRenderer()]
|
||||||
|
allowedLicensesFile = new File("$projectDir/allowed-licenses.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
@@ -270,6 +268,17 @@ spotless {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sonar {
|
||||||
|
properties {
|
||||||
|
property "sonar.projectKey", "Stirling-Tools_Stirling-PDF"
|
||||||
|
property "sonar.organization", "stirling-tools"
|
||||||
|
|
||||||
|
property "sonar.exclusions", "**/build-wrapper-dump.json, src/main/java/org/apache/**, src/main/resources/static/pdfjs/**, src/main/resources/static/pdfjs-legacy/**, src/main/resources/static/js/thirdParty/**"
|
||||||
|
property "sonar.coverage.exclusions", "src/main/java/org/apache/**, src/main/resources/static/pdfjs/**, src/main/resources/static/pdfjs-legacy/**, src/main/resources/static/js/thirdParty/**"
|
||||||
|
property "sonar.cpd.exclusions", "src/main/java/org/apache/**, src/main/resources/static/pdfjs/**, src/main/resources/static/pdfjs-legacy/**, src/main/resources/static/js/thirdParty/**"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//gradleLint {
|
//gradleLint {
|
||||||
// rules=['unused-dependency']
|
// rules=['unused-dependency']
|
||||||
// }
|
// }
|
||||||
@@ -284,26 +293,36 @@ configurations.all {
|
|||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
|
//tmp for security bumps
|
||||||
|
implementation 'ch.qos.logback:logback-core:1.5.15'
|
||||||
|
implementation 'ch.qos.logback:logback-classic:1.5.15'
|
||||||
|
|
||||||
|
|
||||||
|
// Exclude vulnerable BouncyCastle version used in tableau
|
||||||
|
configurations.all {
|
||||||
|
exclude group: 'org.bouncycastle', module: 'bcpkix-jdk15on'
|
||||||
|
exclude group: 'org.bouncycastle', module: 'bcutil-jdk15on'
|
||||||
|
exclude group: 'org.bouncycastle', module: 'bcmail-jdk15on'
|
||||||
|
}
|
||||||
|
|
||||||
if (System.getenv("STIRLING_PDF_DESKTOP_UI") != "false") {
|
if (System.getenv("STIRLING_PDF_DESKTOP_UI") != "false") {
|
||||||
|
implementation 'org.apache.commons:commons-compress:1.26.0'
|
||||||
implementation "me.friwi:jcefmaven:127.3.1"
|
implementation "me.friwi:jcefmaven:127.3.1"
|
||||||
implementation "org.openjfx:javafx-controls:21"
|
implementation "org.openjfx:javafx-controls:21"
|
||||||
implementation "org.openjfx:javafx-swing:21"
|
implementation "org.openjfx:javafx-swing:21"
|
||||||
}
|
}
|
||||||
|
|
||||||
//security updates
|
//security updates
|
||||||
implementation "org.springframework:spring-webmvc:6.2.2"
|
implementation "org.springframework:spring-webmvc:6.2.3"
|
||||||
|
|
||||||
implementation("io.github.pixee:java-security-toolkit:1.2.1")
|
implementation("io.github.pixee:java-security-toolkit:1.2.1")
|
||||||
|
|
||||||
// implementation "org.yaml:snakeyaml:2.2"
|
|
||||||
implementation 'com.github.Carleslc.Simple-YAML:Simple-Yaml:1.8.4'
|
|
||||||
|
|
||||||
// Exclude Tomcat and include Jetty
|
// Exclude Tomcat and include Jetty
|
||||||
implementation("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
|
implementation("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
|
||||||
implementation "org.springframework.boot:spring-boot-starter-jetty:$springBootVersion"
|
implementation "org.springframework.boot:spring-boot-starter-jetty:$springBootVersion"
|
||||||
|
|
||||||
implementation "org.springframework.boot:spring-boot-starter-thymeleaf:$springBootVersion"
|
implementation "org.springframework.boot:spring-boot-starter-thymeleaf:$springBootVersion"
|
||||||
implementation 'com.posthog.java:posthog:1.1.1'
|
implementation 'com.posthog.java:posthog:1.2.0'
|
||||||
implementation 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20240325.1'
|
implementation 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20240325.1'
|
||||||
|
|
||||||
|
|
||||||
@@ -313,13 +332,13 @@ dependencies {
|
|||||||
implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion"
|
implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion"
|
||||||
implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion"
|
implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion"
|
||||||
|
|
||||||
implementation "org.springframework.session:spring-session-core:$springBootVersion"
|
implementation "org.springframework.session:spring-session-core:3.4.1"
|
||||||
implementation "org.springframework:spring-jdbc:6.2.2"
|
implementation "org.springframework:spring-jdbc:6.2.3"
|
||||||
|
|
||||||
implementation 'com.unboundid.product.scim2:scim2-sdk-client:2.3.5'
|
implementation 'com.unboundid.product.scim2:scim2-sdk-client:2.3.5'
|
||||||
// Don't upgrade h2database
|
// Don't upgrade h2database
|
||||||
runtimeOnly "com.h2database:h2:2.3.232"
|
runtimeOnly "com.h2database:h2:2.3.232"
|
||||||
runtimeOnly "org.postgresql:postgresql:42.7.4"
|
runtimeOnly "org.postgresql:postgresql:42.7.5"
|
||||||
constraints {
|
constraints {
|
||||||
implementation "org.opensaml:opensaml-core:$openSamlVersion"
|
implementation "org.opensaml:opensaml-core:$openSamlVersion"
|
||||||
implementation "org.opensaml:opensaml-saml-api:$openSamlVersion"
|
implementation "org.opensaml:opensaml-saml-api:$openSamlVersion"
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 50 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 9.4 KiB |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 242 KiB After Width: | Height: | Size: 169 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 118 KiB |
@@ -41,6 +41,7 @@ import me.friwi.jcefmaven.MavenCefAppHandlerAdapter;
|
|||||||
import me.friwi.jcefmaven.impl.progress.ConsoleProgressHandler;
|
import me.friwi.jcefmaven.impl.progress.ConsoleProgressHandler;
|
||||||
import stirling.software.SPDF.UI.WebBrowser;
|
import stirling.software.SPDF.UI.WebBrowser;
|
||||||
import stirling.software.SPDF.config.InstallationPathConfig;
|
import stirling.software.SPDF.config.InstallationPathConfig;
|
||||||
|
import stirling.software.SPDF.utils.UIScaling;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -215,7 +216,7 @@ public class DesktopBrowser implements WebBrowser {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
frame.setSize(1280, 768);
|
frame.setSize(UIScaling.scaleWidth(1280), UIScaling.scaleHeight(800));
|
||||||
frame.setLocationRelativeTo(null);
|
frame.setLocationRelativeTo(null);
|
||||||
|
|
||||||
loadIcon();
|
loadIcon();
|
||||||
@@ -264,7 +265,9 @@ public class DesktopBrowser implements WebBrowser {
|
|||||||
frame.setOpacity(1.0f);
|
frame.setOpacity(1.0f);
|
||||||
frame.setUndecorated(false);
|
frame.setUndecorated(false);
|
||||||
frame.pack();
|
frame.pack();
|
||||||
frame.setSize(1280, 800);
|
frame.setSize(
|
||||||
|
UIScaling.scaleWidth(1280),
|
||||||
|
UIScaling.scaleHeight(800));
|
||||||
frame.setLocationRelativeTo(null);
|
frame.setLocationRelativeTo(null);
|
||||||
log.debug("Frame reconfigured");
|
log.debug("Frame reconfigured");
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,20 @@
|
|||||||
package stirling.software.SPDF.UI.impl;
|
package stirling.software.SPDF.UI.impl;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
|
import io.github.pixee.security.BoundedLineReader;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import stirling.software.SPDF.utils.UIScaling;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class LoadingWindow extends JDialog {
|
public class LoadingWindow extends JDialog {
|
||||||
@@ -16,6 +24,13 @@ public class LoadingWindow extends JDialog {
|
|||||||
private final JLabel brandLabel;
|
private final JLabel brandLabel;
|
||||||
private long startTime;
|
private long startTime;
|
||||||
|
|
||||||
|
private Timer stuckTimer;
|
||||||
|
private long stuckThreshold = 4000;
|
||||||
|
private long timeAt90Percent = -1;
|
||||||
|
private volatile Process explorerProcess;
|
||||||
|
private static final boolean IS_WINDOWS =
|
||||||
|
System.getProperty("os.name").toLowerCase().contains("win");
|
||||||
|
|
||||||
public LoadingWindow(Frame parent, String initialUrl) {
|
public LoadingWindow(Frame parent, String initialUrl) {
|
||||||
super(parent, "Initializing Stirling-PDF", true);
|
super(parent, "Initializing Stirling-PDF", true);
|
||||||
startTime = System.currentTimeMillis();
|
startTime = System.currentTimeMillis();
|
||||||
@@ -41,12 +56,12 @@ public class LoadingWindow extends JDialog {
|
|||||||
if (is != null) {
|
if (is != null) {
|
||||||
Image img = ImageIO.read(is);
|
Image img = ImageIO.read(is);
|
||||||
if (img != null) {
|
if (img != null) {
|
||||||
Image scaledImg = img.getScaledInstance(48, 48, Image.SCALE_SMOOTH);
|
Image scaledImg = UIScaling.scaleIcon(img, 48, 48);
|
||||||
JLabel iconLabel = new JLabel(new ImageIcon(scaledImg));
|
JLabel iconLabel = new JLabel(new ImageIcon(scaledImg));
|
||||||
iconLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
iconLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
gbc.gridy = 0;
|
gbc.gridy = 0;
|
||||||
mainPanel.add(iconLabel, gbc);
|
mainPanel.add(iconLabel, gbc);
|
||||||
log.debug("Icon loaded and scaled successfully");
|
log.info("Icon loaded and scaled successfully");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,7 +98,8 @@ public class LoadingWindow extends JDialog {
|
|||||||
setUndecorated(false);
|
setUndecorated(false);
|
||||||
|
|
||||||
// Set size and position
|
// Set size and position
|
||||||
setSize(400, 200);
|
setSize(UIScaling.scaleWidth(400), UIScaling.scaleHeight(200));
|
||||||
|
|
||||||
setLocationRelativeTo(parent);
|
setLocationRelativeTo(parent);
|
||||||
setAlwaysOnTop(true);
|
setAlwaysOnTop(true);
|
||||||
setProgress(0);
|
setProgress(0);
|
||||||
@@ -94,6 +110,163 @@ public class LoadingWindow extends JDialog {
|
|||||||
System.currentTimeMillis() - startTime);
|
System.currentTimeMillis() - startTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkAndRefreshExplorer() {
|
||||||
|
if (!IS_WINDOWS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (timeAt90Percent == -1) {
|
||||||
|
timeAt90Percent = System.currentTimeMillis();
|
||||||
|
stuckTimer =
|
||||||
|
new Timer(
|
||||||
|
1000,
|
||||||
|
e -> {
|
||||||
|
long currentTime = System.currentTimeMillis();
|
||||||
|
if (currentTime - timeAt90Percent > stuckThreshold) {
|
||||||
|
try {
|
||||||
|
log.debug(
|
||||||
|
"Attempting Windows explorer refresh due to 90% stuck state");
|
||||||
|
String currentDir = System.getProperty("user.dir");
|
||||||
|
|
||||||
|
// Store current explorer PIDs before we start new one
|
||||||
|
Set<String> existingPids = new HashSet<>();
|
||||||
|
ProcessBuilder listExplorer =
|
||||||
|
new ProcessBuilder(
|
||||||
|
"cmd",
|
||||||
|
"/c",
|
||||||
|
"wmic",
|
||||||
|
"process",
|
||||||
|
"where",
|
||||||
|
"name='explorer.exe'",
|
||||||
|
"get",
|
||||||
|
"ProcessId",
|
||||||
|
"/format:csv");
|
||||||
|
Process process = listExplorer.start();
|
||||||
|
BufferedReader reader =
|
||||||
|
new BufferedReader(
|
||||||
|
new InputStreamReader(
|
||||||
|
process.getInputStream()));
|
||||||
|
String line;
|
||||||
|
while ((line =
|
||||||
|
BoundedLineReader.readLine(
|
||||||
|
reader, 5_000_000))
|
||||||
|
!= null) {
|
||||||
|
if (line.matches(".*\\d+.*")) { // Contains numbers
|
||||||
|
String[] parts = line.trim().split(",");
|
||||||
|
if (parts.length >= 2) {
|
||||||
|
existingPids.add(
|
||||||
|
parts[parts.length - 1].trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
process.waitFor(2, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
// Start new explorer
|
||||||
|
ProcessBuilder pb =
|
||||||
|
new ProcessBuilder(
|
||||||
|
"cmd",
|
||||||
|
"/c",
|
||||||
|
"start",
|
||||||
|
"/min",
|
||||||
|
"/b",
|
||||||
|
"explorer.exe",
|
||||||
|
currentDir);
|
||||||
|
pb.redirectErrorStream(true);
|
||||||
|
explorerProcess = pb.start();
|
||||||
|
|
||||||
|
// Schedule cleanup
|
||||||
|
Timer cleanupTimer =
|
||||||
|
new Timer(
|
||||||
|
2000,
|
||||||
|
cleanup -> {
|
||||||
|
try {
|
||||||
|
// Find new explorer processes
|
||||||
|
ProcessBuilder findNewExplorer =
|
||||||
|
new ProcessBuilder(
|
||||||
|
"cmd",
|
||||||
|
"/c",
|
||||||
|
"wmic",
|
||||||
|
"process",
|
||||||
|
"where",
|
||||||
|
"name='explorer.exe'",
|
||||||
|
"get",
|
||||||
|
"ProcessId",
|
||||||
|
"/format:csv");
|
||||||
|
Process newProcess =
|
||||||
|
findNewExplorer.start();
|
||||||
|
BufferedReader newReader =
|
||||||
|
new BufferedReader(
|
||||||
|
new InputStreamReader(
|
||||||
|
newProcess
|
||||||
|
.getInputStream()));
|
||||||
|
String newLine;
|
||||||
|
while ((newLine =
|
||||||
|
BoundedLineReader
|
||||||
|
.readLine(
|
||||||
|
newReader,
|
||||||
|
5_000_000))
|
||||||
|
!= null) {
|
||||||
|
if (newLine.matches(
|
||||||
|
".*\\d+.*")) {
|
||||||
|
String[] parts =
|
||||||
|
newLine.trim()
|
||||||
|
.split(",");
|
||||||
|
if (parts.length >= 2) {
|
||||||
|
String pid =
|
||||||
|
parts[
|
||||||
|
parts.length
|
||||||
|
- 1]
|
||||||
|
.trim();
|
||||||
|
if (!existingPids
|
||||||
|
.contains(
|
||||||
|
pid)) {
|
||||||
|
log.debug(
|
||||||
|
"Found new explorer.exe with PID: "
|
||||||
|
+ pid);
|
||||||
|
ProcessBuilder
|
||||||
|
killProcess =
|
||||||
|
new ProcessBuilder(
|
||||||
|
"taskkill",
|
||||||
|
"/PID",
|
||||||
|
pid,
|
||||||
|
"/F");
|
||||||
|
killProcess
|
||||||
|
.redirectErrorStream(
|
||||||
|
true);
|
||||||
|
Process killResult =
|
||||||
|
killProcess
|
||||||
|
.start();
|
||||||
|
killResult.waitFor(
|
||||||
|
2,
|
||||||
|
TimeUnit
|
||||||
|
.SECONDS);
|
||||||
|
log.debug(
|
||||||
|
"Explorer process terminated: "
|
||||||
|
+ pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newProcess.waitFor(
|
||||||
|
2, TimeUnit.SECONDS);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error(
|
||||||
|
"Error cleaning up Windows explorer process",
|
||||||
|
ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cleanupTimer.setRepeats(false);
|
||||||
|
cleanupTimer.start();
|
||||||
|
stuckTimer.stop();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("Error refreshing Windows explorer", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
stuckTimer.setRepeats(true);
|
||||||
|
stuckTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setProgress(final int progress) {
|
public void setProgress(final int progress) {
|
||||||
SwingUtilities.invokeLater(
|
SwingUtilities.invokeLater(
|
||||||
() -> {
|
() -> {
|
||||||
@@ -115,11 +288,23 @@ public class LoadingWindow extends JDialog {
|
|||||||
|
|
||||||
// Add thread state logging
|
// Add thread state logging
|
||||||
Thread currentThread = Thread.currentThread();
|
Thread currentThread = Thread.currentThread();
|
||||||
log.debug(
|
log.info(
|
||||||
"Current thread state - Name: {}, State: {}, Priority: {}",
|
"Current thread state - Name: {}, State: {}, Priority: {}",
|
||||||
currentThread.getName(),
|
currentThread.getName(),
|
||||||
currentThread.getState(),
|
currentThread.getState(),
|
||||||
currentThread.getPriority());
|
currentThread.getPriority());
|
||||||
|
|
||||||
|
if (validProgress >= 90 && validProgress < 95) {
|
||||||
|
checkAndRefreshExplorer();
|
||||||
|
} else {
|
||||||
|
// Reset the timer if we move past 95%
|
||||||
|
if (validProgress >= 95) {
|
||||||
|
if (stuckTimer != null) {
|
||||||
|
stuckTimer.stop();
|
||||||
|
}
|
||||||
|
timeAt90Percent = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
progressBar.setValue(validProgress);
|
progressBar.setValue(validProgress);
|
||||||
@@ -145,7 +330,7 @@ public class LoadingWindow extends JDialog {
|
|||||||
statusLabel.setText(validStatus);
|
statusLabel.setText(validStatus);
|
||||||
|
|
||||||
// Log UI state when status changes
|
// Log UI state when status changes
|
||||||
log.debug(
|
log.info(
|
||||||
"UI State - Window visible: {}, Progress: {}%, Status: {}",
|
"UI State - Window visible: {}, Progress: {}%, Status: {}",
|
||||||
isVisible(), progressBar.getValue(), validStatus);
|
isVisible(), progressBar.getValue(), validStatus);
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.io.IOException;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
@@ -74,6 +75,11 @@ public class AppConfig {
|
|||||||
: "null";
|
: "null";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean(name = "languages")
|
||||||
|
public List<String> languages() {
|
||||||
|
return applicationProperties.getUi().getLanguages();
|
||||||
|
}
|
||||||
|
|
||||||
@Bean(name = "navBarText")
|
@Bean(name = "navBarText")
|
||||||
public String navBarText() {
|
public String navBarText() {
|
||||||
String defaultNavBar =
|
String defaultNavBar =
|
||||||
|
|||||||
@@ -9,135 +9,200 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.simpleyaml.configuration.comments.CommentType;
|
|
||||||
import org.simpleyaml.configuration.file.YamlFile;
|
|
||||||
import org.simpleyaml.configuration.implementation.SimpleYamlImplementation;
|
|
||||||
import org.simpleyaml.configuration.implementation.snakeyaml.lib.DumperOptions;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A naive, line-based approach to merging "settings.yml" with "settings.yml.template" while
|
||||||
|
* preserving exact whitespace, blank lines, and inline comments -- but we only rewrite the file if
|
||||||
|
* the merged content actually differs.
|
||||||
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ConfigInitializer {
|
public class ConfigInitializer {
|
||||||
|
|
||||||
public void ensureConfigExists() throws IOException, URISyntaxException {
|
public void ensureConfigExists() throws IOException, URISyntaxException {
|
||||||
// Define the path to the external config directory
|
// 1) If settings file doesn't exist, create from template
|
||||||
Path destPath = Paths.get(InstallationPathConfig.getSettingsPath());
|
Path destPath = Paths.get(InstallationPathConfig.getSettingsPath());
|
||||||
|
|
||||||
// Check if the file already exists
|
|
||||||
if (Files.notExists(destPath)) {
|
if (Files.notExists(destPath)) {
|
||||||
// Ensure the destination directory exists
|
|
||||||
Files.createDirectories(destPath.getParent());
|
Files.createDirectories(destPath.getParent());
|
||||||
|
|
||||||
// Copy the resource from classpath to the external directory
|
|
||||||
try (InputStream in =
|
try (InputStream in =
|
||||||
getClass().getClassLoader().getResourceAsStream("settings.yml.template")) {
|
getClass().getClassLoader().getResourceAsStream("settings.yml.template")) {
|
||||||
if (in != null) {
|
if (in == null) {
|
||||||
Files.copy(in, destPath);
|
|
||||||
} else {
|
|
||||||
throw new FileNotFoundException(
|
throw new FileNotFoundException(
|
||||||
"Resource file not found: settings.yml.template");
|
"Resource file not found: settings.yml.template");
|
||||||
}
|
}
|
||||||
|
Files.copy(in, destPath);
|
||||||
}
|
}
|
||||||
log.info("Created settings file from template");
|
log.info("Created settings file from template");
|
||||||
} else {
|
} else {
|
||||||
|
// 2) Merge existing file with the template
|
||||||
// Define the path to the config settings file
|
|
||||||
Path settingsPath = Paths.get(InstallationPathConfig.getSettingsPath());
|
Path settingsPath = Paths.get(InstallationPathConfig.getSettingsPath());
|
||||||
// Load the template resource
|
URL templateResource = getClass().getClassLoader().getResource("settings.yml.template");
|
||||||
URL settingsTemplateResource =
|
if (templateResource == null) {
|
||||||
getClass().getClassLoader().getResource("settings.yml.template");
|
|
||||||
if (settingsTemplateResource == null) {
|
|
||||||
throw new IOException("Resource not found: settings.yml.template");
|
throw new IOException("Resource not found: settings.yml.template");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a temporary file to copy the resource content
|
// Copy template to a temp location so we can read lines
|
||||||
Path tempTemplatePath = Files.createTempFile("settings.yml", ".template");
|
Path tempTemplatePath = Files.createTempFile("settings.yml", ".template");
|
||||||
|
try (InputStream in = templateResource.openStream()) {
|
||||||
try (InputStream in = settingsTemplateResource.openStream()) {
|
|
||||||
Files.copy(in, tempTemplatePath, StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(in, tempTemplatePath, StandardCopyOption.REPLACE_EXISTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
final YamlFile settingsTemplateFile = new YamlFile(tempTemplatePath.toFile());
|
// 2a) Read lines from both files
|
||||||
DumperOptions yamlOptionsSettingsTemplateFile =
|
List<String> templateLines = Files.readAllLines(tempTemplatePath);
|
||||||
((SimpleYamlImplementation) settingsTemplateFile.getImplementation())
|
List<String> mainLines = Files.readAllLines(settingsPath);
|
||||||
.getDumperOptions();
|
|
||||||
yamlOptionsSettingsTemplateFile.setSplitLines(false);
|
|
||||||
settingsTemplateFile.loadWithComments();
|
|
||||||
|
|
||||||
final YamlFile settingsFile = new YamlFile(settingsPath.toFile());
|
// 2b) Merge lines
|
||||||
DumperOptions yamlOptionsSettingsFile =
|
List<String> mergedLines = mergeYamlLinesWithTemplate(templateLines, mainLines);
|
||||||
((SimpleYamlImplementation) settingsFile.getImplementation())
|
|
||||||
.getDumperOptions();
|
|
||||||
yamlOptionsSettingsFile.setSplitLines(false);
|
|
||||||
settingsFile.loadWithComments();
|
|
||||||
|
|
||||||
// Load headers and comments
|
// 2c) Only write if there's an actual difference
|
||||||
String header = settingsTemplateFile.getHeader();
|
if (!mergedLines.equals(mainLines)) {
|
||||||
|
Files.write(settingsPath, mergedLines);
|
||||||
// Create a new file for temporary settings
|
log.info("Settings file updated based on template changes.");
|
||||||
final YamlFile tempSettingFile = new YamlFile(settingsPath.toFile());
|
} else {
|
||||||
DumperOptions yamlOptionsTempSettingFile =
|
log.info("No changes detected; settings file left as-is.");
|
||||||
((SimpleYamlImplementation) tempSettingFile.getImplementation())
|
|
||||||
.getDumperOptions();
|
|
||||||
yamlOptionsTempSettingFile.setSplitLines(false);
|
|
||||||
tempSettingFile.createNewFile(true);
|
|
||||||
tempSettingFile.setHeader(header);
|
|
||||||
|
|
||||||
// Get all keys from the template
|
|
||||||
List<String> keys =
|
|
||||||
Arrays.asList(settingsTemplateFile.getKeys(true).toArray(new String[0]));
|
|
||||||
|
|
||||||
for (String key : keys) {
|
|
||||||
if (!key.contains(".")) {
|
|
||||||
// Add blank lines and comments to specific sections
|
|
||||||
tempSettingFile
|
|
||||||
.path(key)
|
|
||||||
.comment(settingsTemplateFile.getComment(key))
|
|
||||||
.blankLine();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Copy settings from the template to the settings.yml file
|
|
||||||
changeConfigItemFromCommentToKeyValue(
|
|
||||||
settingsTemplateFile, settingsFile, tempSettingFile, key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the settings.yml file
|
Files.deleteIfExists(tempTemplatePath);
|
||||||
tempSettingFile.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create custom settings file if it doesn't exist
|
// 3) Ensure custom settings file exists
|
||||||
Path customSettingsPath = Paths.get(InstallationPathConfig.getCustomSettingsPath());
|
Path customSettingsPath = Paths.get(InstallationPathConfig.getCustomSettingsPath());
|
||||||
if (!Files.exists(customSettingsPath)) {
|
if (!Files.exists(customSettingsPath)) {
|
||||||
Files.createFile(customSettingsPath);
|
Files.createFile(customSettingsPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changeConfigItemFromCommentToKeyValue(
|
/**
|
||||||
final YamlFile settingsTemplateFile,
|
* Merge logic that: - Reads the template lines block-by-block (where a "block" = a key and all
|
||||||
final YamlFile settingsFile,
|
* the lines that belong to it), - If the main file has that key, we keep the main file's block
|
||||||
final YamlFile tempSettingFile,
|
* (preserving whitespace + inline comments). - Otherwise, we insert the template's block. - We
|
||||||
String path) {
|
* also remove keys from main that no longer exist in the template.
|
||||||
if (settingsFile.get(path) == null && settingsTemplateFile.get(path) != null) {
|
*
|
||||||
// If the key is only in the template, add it to the temporary settings with comments
|
* @param templateLines lines from settings.yml.template
|
||||||
tempSettingFile
|
* @param mainLines lines from the existing settings.yml
|
||||||
.path(path)
|
* @return merged lines
|
||||||
.set(settingsTemplateFile.get(path))
|
*/
|
||||||
.comment(settingsTemplateFile.getComment(path, CommentType.BLOCK))
|
private List<String> mergeYamlLinesWithTemplate(
|
||||||
.commentSide(settingsTemplateFile.getComment(path, CommentType.SIDE));
|
List<String> templateLines, List<String> mainLines) {
|
||||||
} else if (settingsFile.get(path) != null && settingsTemplateFile.get(path) != null) {
|
|
||||||
// If the key is in both, update the temporary settings with the main settings' value
|
// 1) Parse template lines into an ordered map: path -> Block
|
||||||
// and comments
|
LinkedHashMap<String, Block> templateBlocks = parseYamlBlocks(templateLines);
|
||||||
tempSettingFile
|
|
||||||
.path(path)
|
// 2) Parse main lines into a map: path -> Block
|
||||||
.set(settingsFile.get(path))
|
LinkedHashMap<String, Block> mainBlocks = parseYamlBlocks(mainLines);
|
||||||
.comment(settingsTemplateFile.getComment(path, CommentType.BLOCK))
|
|
||||||
.commentSide(settingsTemplateFile.getComment(path, CommentType.SIDE));
|
// 3) Build the final list by iterating template blocks in order
|
||||||
|
List<String> merged = new ArrayList<>();
|
||||||
|
for (Map.Entry<String, Block> entry : templateBlocks.entrySet()) {
|
||||||
|
String path = entry.getKey();
|
||||||
|
Block templateBlock = entry.getValue();
|
||||||
|
|
||||||
|
if (mainBlocks.containsKey(path)) {
|
||||||
|
// If main has the same block, prefer main's lines
|
||||||
|
merged.addAll(mainBlocks.get(path).lines);
|
||||||
} else {
|
} else {
|
||||||
// Log if the key is not found in both YAML files
|
// Otherwise, add the template block
|
||||||
log.info("Key not found in both YAML files: " + path);
|
merged.addAll(templateBlock.lines);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return merged;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a list of lines into a map of "path -> Block" where "Block" is all lines that belong to
|
||||||
|
* that key (including subsequent indented lines). Very naive approach that may not work with
|
||||||
|
* advanced YAML.
|
||||||
|
*/
|
||||||
|
private LinkedHashMap<String, Block> parseYamlBlocks(List<String> lines) {
|
||||||
|
LinkedHashMap<String, Block> blocks = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
Block currentBlock = null;
|
||||||
|
String currentPath = null;
|
||||||
|
|
||||||
|
for (String line : lines) {
|
||||||
|
if (isLikelyKeyLine(line)) {
|
||||||
|
// Found a new "key: ..." line
|
||||||
|
if (currentBlock != null && currentPath != null) {
|
||||||
|
blocks.put(currentPath, currentBlock);
|
||||||
|
}
|
||||||
|
currentBlock = new Block();
|
||||||
|
currentBlock.lines.add(line);
|
||||||
|
currentPath = computePathForLine(line);
|
||||||
|
} else {
|
||||||
|
// Continuation of current block (comments, blank lines, sub-lines)
|
||||||
|
if (currentBlock == null) {
|
||||||
|
// If file starts with comments/blank lines, treat as "header block" with path
|
||||||
|
// ""
|
||||||
|
currentBlock = new Block();
|
||||||
|
currentPath = "";
|
||||||
|
}
|
||||||
|
currentBlock.lines.add(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentBlock != null && currentPath != null) {
|
||||||
|
blocks.put(currentPath, currentBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
return blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the line is likely "key:" or "key: value", ignoring comments/blank. Skips lines
|
||||||
|
* starting with "-" or "#".
|
||||||
|
*/
|
||||||
|
private boolean isLikelyKeyLine(String line) {
|
||||||
|
String trimmed = line.trim();
|
||||||
|
if (trimmed.isEmpty() || trimmed.startsWith("#") || trimmed.startsWith("-")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int colonIdx = trimmed.indexOf(':');
|
||||||
|
return (colonIdx > 0); // someKey:
|
||||||
|
}
|
||||||
|
|
||||||
|
// For a line like "security: ", returns "security" or "security.enableLogin"
|
||||||
|
// by looking at indentation. Very naive.
|
||||||
|
private static final Deque<String> pathStack = new ArrayDeque<>();
|
||||||
|
private static int currentIndentLevel = 0;
|
||||||
|
|
||||||
|
private String computePathForLine(String line) {
|
||||||
|
// count leading spaces
|
||||||
|
int leadingSpaces = 0;
|
||||||
|
for (char c : line.toCharArray()) {
|
||||||
|
if (c == ' ') leadingSpaces++;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
// assume 2 spaces = 1 indent
|
||||||
|
int indentLevel = leadingSpaces / 2;
|
||||||
|
|
||||||
|
String trimmed = line.trim();
|
||||||
|
int colonIdx = trimmed.indexOf(':');
|
||||||
|
String keyName = trimmed.substring(0, colonIdx).trim();
|
||||||
|
|
||||||
|
// pop stack until we match the new indent level
|
||||||
|
while (currentIndentLevel >= indentLevel && !pathStack.isEmpty()) {
|
||||||
|
pathStack.pop();
|
||||||
|
currentIndentLevel--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// push the new key
|
||||||
|
pathStack.push(keyName);
|
||||||
|
currentIndentLevel = indentLevel;
|
||||||
|
|
||||||
|
// build path by reversing the stack
|
||||||
|
String[] arr = pathStack.toArray(new String[0]);
|
||||||
|
List<String> reversed = Arrays.asList(arr);
|
||||||
|
Collections.reverse(reversed);
|
||||||
|
return String.join(".", reversed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple holder for the lines that comprise a "block" (i.e. a key and its subsequent lines).
|
||||||
|
*/
|
||||||
|
private static class Block {
|
||||||
|
List<String> lines = new ArrayList<>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -265,9 +265,6 @@ public class EndpointConfiguration {
|
|||||||
// Pdftohtml dependent endpoints
|
// Pdftohtml dependent endpoints
|
||||||
addEndpointToGroup("Pdftohtml", "pdf-to-html");
|
addEndpointToGroup("Pdftohtml", "pdf-to-html");
|
||||||
addEndpointToGroup("Pdftohtml", "pdf-to-markdown");
|
addEndpointToGroup("Pdftohtml", "pdf-to-markdown");
|
||||||
|
|
||||||
// disabled for now while we resolve issues
|
|
||||||
disableEndpoint("pdf-to-pdfa");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processEnvironmentConfigs() {
|
private void processEnvironmentConfigs() {
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ public class ExternalAppDepConfig {
|
|||||||
|
|
||||||
{
|
{
|
||||||
put("soffice", List.of("LibreOffice"));
|
put("soffice", List.of("LibreOffice"));
|
||||||
put("weasyprint", List.of("Weasyprint"));
|
put("/opt/venv/bin/weasyprint", List.of("Weasyprint"));
|
||||||
put("pdftohtml", List.of("Pdftohtml"));
|
put("pdftohtml", List.of("Pdftohtml"));
|
||||||
put("unoconv", List.of("Unoconv"));
|
put("/opt/venv/bin/unoconvert", List.of("Unoconv"));
|
||||||
put("qpdf", List.of("qpdf"));
|
put("qpdf", List.of("qpdf"));
|
||||||
put("tesseract", List.of("tesseract"));
|
put("tesseract", List.of("tesseract"));
|
||||||
}
|
}
|
||||||
@@ -101,9 +101,9 @@ public class ExternalAppDepConfig {
|
|||||||
checkDependencyAndDisableGroup("tesseract");
|
checkDependencyAndDisableGroup("tesseract");
|
||||||
checkDependencyAndDisableGroup("soffice");
|
checkDependencyAndDisableGroup("soffice");
|
||||||
checkDependencyAndDisableGroup("qpdf");
|
checkDependencyAndDisableGroup("qpdf");
|
||||||
checkDependencyAndDisableGroup("weasyprint");
|
checkDependencyAndDisableGroup("/opt/venv/bin/weasyprint");
|
||||||
checkDependencyAndDisableGroup("pdftohtml");
|
checkDependencyAndDisableGroup("pdftohtml");
|
||||||
checkDependencyAndDisableGroup("unoconv");
|
checkDependencyAndDisableGroup("/opt/venv/bin/unoconvert");
|
||||||
// Special handling for Python/OpenCV dependencies
|
// Special handling for Python/OpenCV dependencies
|
||||||
boolean pythonAvailable = isCommandAvailable("python3") || isCommandAvailable("python");
|
boolean pythonAvailable = isCommandAvailable("python3") || isCommandAvailable("python");
|
||||||
if (!pythonAvailable) {
|
if (!pythonAvailable) {
|
||||||
|
|||||||
@@ -7,8 +7,10 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import com.posthog.java.PostHog;
|
import com.posthog.java.PostHog;
|
||||||
|
|
||||||
import jakarta.annotation.PreDestroy;
|
import jakarta.annotation.PreDestroy;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@Slf4j
|
||||||
public class PostHogConfig {
|
public class PostHogConfig {
|
||||||
|
|
||||||
@Value("${posthog.api.key}")
|
@Value("${posthog.api.key}")
|
||||||
@@ -21,7 +23,11 @@ public class PostHogConfig {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public PostHog postHogClient() {
|
public PostHog postHogClient() {
|
||||||
postHogClient = new PostHog.Builder(posthogApiKey).host(posthogHost).build();
|
postHogClient =
|
||||||
|
new PostHog.Builder(posthogApiKey)
|
||||||
|
.host(posthogHost)
|
||||||
|
.logger(new PostHogLoggerImpl())
|
||||||
|
.build();
|
||||||
return postHogClient;
|
return postHogClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package stirling.software.SPDF.config;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.posthog.java.PostHogLogger;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class PostHogLoggerImpl implements PostHogLogger {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void debug(String message) {
|
||||||
|
log.debug(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String message) {
|
||||||
|
log.info(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warn(String message) {
|
||||||
|
log.warn(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String message) {
|
||||||
|
log.error(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String message, Throwable throwable) {
|
||||||
|
if (message.contains("Error sending events to PostHog")) {
|
||||||
|
log.warn(
|
||||||
|
"Error sending metrics, Likely caused by no internet connection. Non Blocking");
|
||||||
|
} else {
|
||||||
|
log.error(message, throwable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,9 @@ package stirling.software.SPDF.controller.api;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@@ -26,11 +28,14 @@ public class AdditionalLanguageJsController {
|
|||||||
@Hidden
|
@Hidden
|
||||||
@GetMapping(value = "/additionalLanguageCode.js", produces = "application/javascript")
|
@GetMapping(value = "/additionalLanguageCode.js", produces = "application/javascript")
|
||||||
public void generateAdditionalLanguageJs(HttpServletResponse response) throws IOException {
|
public void generateAdditionalLanguageJs(HttpServletResponse response) throws IOException {
|
||||||
List<String> supportedLanguages = languageService.getSupportedLanguages();
|
Set<String> supportedLanguages = languageService.getSupportedLanguages();
|
||||||
response.setContentType("application/javascript");
|
response.setContentType("application/javascript");
|
||||||
PrintWriter writer = response.getWriter();
|
PrintWriter writer = response.getWriter();
|
||||||
// Erstelle das JavaScript dynamisch
|
// Erstelle das JavaScript dynamisch
|
||||||
writer.println("const supportedLanguages = " + toJsonArray(supportedLanguages) + ";");
|
writer.println(
|
||||||
|
"const supportedLanguages = "
|
||||||
|
+ toJsonArray(new ArrayList<>(supportedLanguages))
|
||||||
|
+ ";");
|
||||||
// Generiere die `getDetailedLanguageCode`-Funktion
|
// Generiere die `getDetailedLanguageCode`-Funktion
|
||||||
writer.println(
|
writer.println(
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,31 +1,32 @@
|
|||||||
package stirling.software.SPDF.controller.api;
|
package stirling.software.SPDF.controller.api;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
import org.apache.pdfbox.Loader;
|
import org.apache.pdfbox.Loader;
|
||||||
import org.apache.pdfbox.cos.COSName;
|
import org.apache.pdfbox.cos.COSName;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.pdmodel.PDPageTree;
|
import org.apache.pdfbox.pdmodel.PDPageTree;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
|
|
||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
|
||||||
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
|
|
||||||
import org.apache.pdfbox.pdmodel.encryption.PDEncryption;
|
import org.apache.pdfbox.pdmodel.encryption.PDEncryption;
|
||||||
|
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
|
||||||
|
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import stirling.software.SPDF.model.api.PDFFile;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import stirling.software.SPDF.model.api.PDFFile;
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/v1/analysis")
|
@RequestMapping("/api/v1/analysis")
|
||||||
@Tag(name = "Analysis", description = "Analysis APIs")
|
@Tag(name = "Analysis", description = "Analysis APIs")
|
||||||
public class AnalysisController {
|
public class AnalysisController {
|
||||||
|
|
||||||
|
|
||||||
@PostMapping(value = "/page-count", consumes = "multipart/form-data")
|
@PostMapping(value = "/page-count", consumes = "multipart/form-data")
|
||||||
@Operation(summary = "Get PDF page count",
|
@Operation(
|
||||||
|
summary = "Get PDF page count",
|
||||||
description = "Returns total number of pages in PDF. Input:PDF Output:JSON Type:SISO")
|
description = "Returns total number of pages in PDF. Input:PDF Output:JSON Type:SISO")
|
||||||
public Map<String, Integer> getPageCount(@ModelAttribute PDFFile file) throws IOException {
|
public Map<String, Integer> getPageCount(@ModelAttribute PDFFile file) throws IOException {
|
||||||
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
||||||
@@ -34,7 +35,8 @@ public class AnalysisController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/basic-info", consumes = "multipart/form-data")
|
@PostMapping(value = "/basic-info", consumes = "multipart/form-data")
|
||||||
@Operation(summary = "Get basic PDF information",
|
@Operation(
|
||||||
|
summary = "Get basic PDF information",
|
||||||
description = "Returns page count, version, file size. Input:PDF Output:JSON Type:SISO")
|
description = "Returns page count, version, file size. Input:PDF Output:JSON Type:SISO")
|
||||||
public Map<String, Object> getBasicInfo(@ModelAttribute PDFFile file) throws IOException {
|
public Map<String, Object> getBasicInfo(@ModelAttribute PDFFile file) throws IOException {
|
||||||
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
||||||
@@ -47,9 +49,11 @@ public class AnalysisController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/document-properties", consumes = "multipart/form-data")
|
@PostMapping(value = "/document-properties", consumes = "multipart/form-data")
|
||||||
@Operation(summary = "Get PDF document properties",
|
@Operation(
|
||||||
|
summary = "Get PDF document properties",
|
||||||
description = "Returns title, author, subject, etc. Input:PDF Output:JSON Type:SISO")
|
description = "Returns title, author, subject, etc. Input:PDF Output:JSON Type:SISO")
|
||||||
public Map<String, String> getDocumentProperties(@ModelAttribute PDFFile file) throws IOException {
|
public Map<String, String> getDocumentProperties(@ModelAttribute PDFFile file)
|
||||||
|
throws IOException {
|
||||||
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
||||||
PDDocumentInformation info = document.getDocumentInformation();
|
PDDocumentInformation info = document.getDocumentInformation();
|
||||||
Map<String, String> properties = new HashMap<>();
|
Map<String, String> properties = new HashMap<>();
|
||||||
@@ -66,9 +70,11 @@ public class AnalysisController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/page-dimensions", consumes = "multipart/form-data")
|
@PostMapping(value = "/page-dimensions", consumes = "multipart/form-data")
|
||||||
@Operation(summary = "Get page dimensions for all pages",
|
@Operation(
|
||||||
|
summary = "Get page dimensions for all pages",
|
||||||
description = "Returns width and height of each page. Input:PDF Output:JSON Type:SISO")
|
description = "Returns width and height of each page. Input:PDF Output:JSON Type:SISO")
|
||||||
public List<Map<String, Float>> getPageDimensions(@ModelAttribute PDFFile file) throws IOException {
|
public List<Map<String, Float>> getPageDimensions(@ModelAttribute PDFFile file)
|
||||||
|
throws IOException {
|
||||||
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
||||||
List<Map<String, Float>> dimensions = new ArrayList<>();
|
List<Map<String, Float>> dimensions = new ArrayList<>();
|
||||||
PDPageTree pages = document.getPages();
|
PDPageTree pages = document.getPages();
|
||||||
@@ -84,8 +90,10 @@ public class AnalysisController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/form-fields", consumes = "multipart/form-data")
|
@PostMapping(value = "/form-fields", consumes = "multipart/form-data")
|
||||||
@Operation(summary = "Get form field information",
|
@Operation(
|
||||||
description = "Returns count and details of form fields. Input:PDF Output:JSON Type:SISO")
|
summary = "Get form field information",
|
||||||
|
description =
|
||||||
|
"Returns count and details of form fields. Input:PDF Output:JSON Type:SISO")
|
||||||
public Map<String, Object> getFormFields(@ModelAttribute PDFFile file) throws IOException {
|
public Map<String, Object> getFormFields(@ModelAttribute PDFFile file) throws IOException {
|
||||||
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
||||||
Map<String, Object> formInfo = new HashMap<>();
|
Map<String, Object> formInfo = new HashMap<>();
|
||||||
@@ -105,7 +113,8 @@ public class AnalysisController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/annotation-info", consumes = "multipart/form-data")
|
@PostMapping(value = "/annotation-info", consumes = "multipart/form-data")
|
||||||
@Operation(summary = "Get annotation information",
|
@Operation(
|
||||||
|
summary = "Get annotation information",
|
||||||
description = "Returns count and types of annotations. Input:PDF Output:JSON Type:SISO")
|
description = "Returns count and types of annotations. Input:PDF Output:JSON Type:SISO")
|
||||||
public Map<String, Object> getAnnotationInfo(@ModelAttribute PDFFile file) throws IOException {
|
public Map<String, Object> getAnnotationInfo(@ModelAttribute PDFFile file) throws IOException {
|
||||||
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
||||||
@@ -128,8 +137,10 @@ public class AnalysisController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/font-info", consumes = "multipart/form-data")
|
@PostMapping(value = "/font-info", consumes = "multipart/form-data")
|
||||||
@Operation(summary = "Get font information",
|
@Operation(
|
||||||
description = "Returns list of fonts used in the document. Input:PDF Output:JSON Type:SISO")
|
summary = "Get font information",
|
||||||
|
description =
|
||||||
|
"Returns list of fonts used in the document. Input:PDF Output:JSON Type:SISO")
|
||||||
public Map<String, Object> getFontInfo(@ModelAttribute PDFFile file) throws IOException {
|
public Map<String, Object> getFontInfo(@ModelAttribute PDFFile file) throws IOException {
|
||||||
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
||||||
Map<String, Object> fontInfo = new HashMap<>();
|
Map<String, Object> fontInfo = new HashMap<>();
|
||||||
@@ -148,8 +159,10 @@ public class AnalysisController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/security-info", consumes = "multipart/form-data")
|
@PostMapping(value = "/security-info", consumes = "multipart/form-data")
|
||||||
@Operation(summary = "Get security information",
|
@Operation(
|
||||||
description = "Returns encryption and permission details. Input:PDF Output:JSON Type:SISO")
|
summary = "Get security information",
|
||||||
|
description =
|
||||||
|
"Returns encryption and permission details. Input:PDF Output:JSON Type:SISO")
|
||||||
public Map<String, Object> getSecurityInfo(@ModelAttribute PDFFile file) throws IOException {
|
public Map<String, Object> getSecurityInfo(@ModelAttribute PDFFile file) throws IOException {
|
||||||
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
||||||
Map<String, Object> securityInfo = new HashMap<>();
|
Map<String, Object> securityInfo = new HashMap<>();
|
||||||
@@ -163,8 +176,12 @@ public class AnalysisController {
|
|||||||
Map<String, Boolean> permissions = new HashMap<>();
|
Map<String, Boolean> permissions = new HashMap<>();
|
||||||
permissions.put("canPrint", document.getCurrentAccessPermission().canPrint());
|
permissions.put("canPrint", document.getCurrentAccessPermission().canPrint());
|
||||||
permissions.put("canModify", document.getCurrentAccessPermission().canModify());
|
permissions.put("canModify", document.getCurrentAccessPermission().canModify());
|
||||||
permissions.put("canExtractContent", document.getCurrentAccessPermission().canExtractContent());
|
permissions.put(
|
||||||
permissions.put("canModifyAnnotations", document.getCurrentAccessPermission().canModifyAnnotations());
|
"canExtractContent",
|
||||||
|
document.getCurrentAccessPermission().canExtractContent());
|
||||||
|
permissions.put(
|
||||||
|
"canModifyAnnotations",
|
||||||
|
document.getCurrentAccessPermission().canModifyAnnotations());
|
||||||
|
|
||||||
securityInfo.put("permissions", permissions);
|
securityInfo.put("permissions", permissions);
|
||||||
} else {
|
} else {
|
||||||
@@ -174,7 +191,4 @@ public class AnalysisController {
|
|||||||
return securityInfo;
|
return securityInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -174,7 +174,38 @@ public class RearrangePagesPDFController {
|
|||||||
return newPageOrderZeroBased;
|
return newPageOrderZeroBased;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Integer> processSortTypes(String sortTypes, int totalPages) {
|
private List<Integer> duplicate(int totalPages, String pageOrder) {
|
||||||
|
List<Integer> newPageOrder = new ArrayList<>();
|
||||||
|
int duplicateCount;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Parse the duplicate count from pageOrder
|
||||||
|
duplicateCount =
|
||||||
|
pageOrder != null && !pageOrder.isEmpty()
|
||||||
|
? Integer.parseInt(pageOrder.trim())
|
||||||
|
: 2; // Default to 2 if not specified
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.error("Invalid duplicate count specified", e);
|
||||||
|
duplicateCount = 2; // Default to 2 if invalid input
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate duplicate count
|
||||||
|
if (duplicateCount < 1) {
|
||||||
|
duplicateCount = 2; // Default to 2 if invalid input
|
||||||
|
}
|
||||||
|
|
||||||
|
// For each page in the document
|
||||||
|
for (int pageNum = 0; pageNum < totalPages; pageNum++) {
|
||||||
|
// Add the current page index duplicateCount times
|
||||||
|
for (int dupCount = 0; dupCount < duplicateCount; dupCount++) {
|
||||||
|
newPageOrder.add(pageNum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newPageOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Integer> processSortTypes(String sortTypes, int totalPages, String pageOrder) {
|
||||||
try {
|
try {
|
||||||
SortTypes mode = SortTypes.valueOf(sortTypes.toUpperCase());
|
SortTypes mode = SortTypes.valueOf(sortTypes.toUpperCase());
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
@@ -196,6 +227,8 @@ public class RearrangePagesPDFController {
|
|||||||
return removeLast(totalPages);
|
return removeLast(totalPages);
|
||||||
case REMOVE_FIRST_AND_LAST:
|
case REMOVE_FIRST_AND_LAST:
|
||||||
return removeFirstAndLast(totalPages);
|
return removeFirstAndLast(totalPages);
|
||||||
|
case DUPLICATE:
|
||||||
|
return duplicate(totalPages, pageOrder);
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unsupported custom mode");
|
throw new IllegalArgumentException("Unsupported custom mode");
|
||||||
}
|
}
|
||||||
@@ -223,8 +256,10 @@ public class RearrangePagesPDFController {
|
|||||||
String[] pageOrderArr = pageOrder != null ? pageOrder.split(",") : new String[0];
|
String[] pageOrderArr = pageOrder != null ? pageOrder.split(",") : new String[0];
|
||||||
int totalPages = document.getNumberOfPages();
|
int totalPages = document.getNumberOfPages();
|
||||||
List<Integer> newPageOrder;
|
List<Integer> newPageOrder;
|
||||||
if (sortType != null && sortType.length() > 0) {
|
if (sortType != null
|
||||||
newPageOrder = processSortTypes(sortType, totalPages);
|
&& sortType.length() > 0
|
||||||
|
&& !"custom".equals(sortType.toLowerCase())) {
|
||||||
|
newPageOrder = processSortTypes(sortType, totalPages, pageOrder);
|
||||||
} else {
|
} else {
|
||||||
newPageOrder = GeneralUtils.parsePageList(pageOrderArr, totalPages, false);
|
newPageOrder = GeneralUtils.parsePageList(pageOrderArr, totalPages, false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,6 +100,8 @@ public class SplitPdfBySectionsController {
|
|||||||
|
|
||||||
if (sectionNum == horiz * verti) pageNum++;
|
if (sectionNum == horiz * verti) pageNum++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zipOut.finish();
|
||||||
data = Files.readAllBytes(zipFile);
|
data = Files.readAllBytes(zipFile);
|
||||||
return WebResponseUtils.bytesToWebResponse(
|
return WebResponseUtils.bytesToWebResponse(
|
||||||
data, filename + "_split.zip", MediaType.APPLICATION_OCTET_STREAM);
|
data, filename + "_split.zip", MediaType.APPLICATION_OCTET_STREAM);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import io.github.pixee.security.Filenames;
|
|||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.api.converters.HTMLToPdfRequest;
|
import stirling.software.SPDF.model.api.converters.HTMLToPdfRequest;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.FileToPdf;
|
import stirling.software.SPDF.utils.FileToPdf;
|
||||||
@@ -27,19 +28,23 @@ public class ConvertHtmlToPDF {
|
|||||||
|
|
||||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ConvertHtmlToPDF(
|
public ConvertHtmlToPDF(
|
||||||
CustomPDDocumentFactory pdfDocumentFactory,
|
CustomPDDocumentFactory pdfDocumentFactory,
|
||||||
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled) {
|
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled,
|
||||||
|
ApplicationProperties applicationProperties) {
|
||||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
|
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
|
||||||
|
this.applicationProperties = applicationProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/html/pdf")
|
@PostMapping(consumes = "multipart/form-data", value = "/html/pdf")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert an HTML or ZIP (containing HTML and CSS) to PDF",
|
summary = "Convert an HTML or ZIP (containing HTML and CSS) to PDF",
|
||||||
description =
|
description =
|
||||||
"This endpoint takes an HTML or ZIP file input and converts it to a PDF format.")
|
"This endpoint takes an HTML or ZIP file input and converts it to a PDF format. Input:HTML Output:PDF Type:SISO")
|
||||||
public ResponseEntity<byte[]> HtmlToPdf(@ModelAttribute HTMLToPdfRequest request)
|
public ResponseEntity<byte[]> HtmlToPdf(@ModelAttribute HTMLToPdfRequest request)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MultipartFile fileInput = request.getFileInput();
|
MultipartFile fileInput = request.getFileInput();
|
||||||
@@ -54,12 +59,17 @@ public class ConvertHtmlToPDF {
|
|||||||
|| (!originalFilename.endsWith(".html") && !originalFilename.endsWith(".zip"))) {
|
|| (!originalFilename.endsWith(".html") && !originalFilename.endsWith(".zip"))) {
|
||||||
throw new IllegalArgumentException("File must be either .html or .zip format.");
|
throw new IllegalArgumentException("File must be either .html or .zip format.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean disableSanitize =
|
||||||
|
Boolean.TRUE.equals(applicationProperties.getSystem().getDisableSanitize());
|
||||||
|
|
||||||
byte[] pdfBytes =
|
byte[] pdfBytes =
|
||||||
FileToPdf.convertHtmlToPdf(
|
FileToPdf.convertHtmlToPdf(
|
||||||
request,
|
request,
|
||||||
fileInput.getBytes(),
|
fileInput.getBytes(),
|
||||||
originalFilename,
|
originalFilename,
|
||||||
bookAndHtmlFormatsInstalled);
|
bookAndHtmlFormatsInstalled,
|
||||||
|
disableSanitize);
|
||||||
|
|
||||||
pdfBytes = pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes);
|
pdfBytes = pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes);
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import io.github.pixee.security.Filenames;
|
|||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.api.GeneralFile;
|
import stirling.software.SPDF.model.api.GeneralFile;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.FileToPdf;
|
import stirling.software.SPDF.utils.FileToPdf;
|
||||||
@@ -37,12 +38,16 @@ public class ConvertMarkdownToPdf {
|
|||||||
|
|
||||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ConvertMarkdownToPdf(
|
public ConvertMarkdownToPdf(
|
||||||
CustomPDDocumentFactory pdfDocumentFactory,
|
CustomPDDocumentFactory pdfDocumentFactory,
|
||||||
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled) {
|
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled,
|
||||||
|
ApplicationProperties applicationProperties) {
|
||||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
|
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
|
||||||
|
this.applicationProperties = applicationProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/markdown/pdf")
|
@PostMapping(consumes = "multipart/form-data", value = "/markdown/pdf")
|
||||||
@@ -76,12 +81,16 @@ public class ConvertMarkdownToPdf {
|
|||||||
|
|
||||||
String htmlContent = renderer.render(document);
|
String htmlContent = renderer.render(document);
|
||||||
|
|
||||||
|
boolean disableSanitize =
|
||||||
|
Boolean.TRUE.equals(applicationProperties.getSystem().getDisableSanitize());
|
||||||
|
|
||||||
byte[] pdfBytes =
|
byte[] pdfBytes =
|
||||||
FileToPdf.convertHtmlToPdf(
|
FileToPdf.convertHtmlToPdf(
|
||||||
null,
|
null,
|
||||||
htmlContent.getBytes(),
|
htmlContent.getBytes(),
|
||||||
"converted.html",
|
"converted.html",
|
||||||
bookAndHtmlFormatsInstalled);
|
bookAndHtmlFormatsInstalled,
|
||||||
|
disableSanitize);
|
||||||
pdfBytes = pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes);
|
pdfBytes = pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes);
|
||||||
String outputFilename =
|
String outputFilename =
|
||||||
originalFilename.replaceFirst("[.][^.]+$", "")
|
originalFilename.replaceFirst("[.][^.]+$", "")
|
||||||
|
|||||||
@@ -61,13 +61,13 @@ public class ConvertOfficeController {
|
|||||||
List<String> command =
|
List<String> command =
|
||||||
new ArrayList<>(
|
new ArrayList<>(
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
"unoconv",
|
"/opt/venv/bin/unoconvert",
|
||||||
"-vvv",
|
"--port",
|
||||||
"-f",
|
"2003",
|
||||||
|
"--convert-to",
|
||||||
"pdf",
|
"pdf",
|
||||||
"-o",
|
tempInputFile.toString(),
|
||||||
tempOutputFile.toString(),
|
tempOutputFile.toString()));
|
||||||
tempInputFile.toString()));
|
|
||||||
ProcessExecutorResult returnCode =
|
ProcessExecutorResult returnCode =
|
||||||
ProcessExecutor.getInstance(ProcessExecutor.Processes.LIBRE_OFFICE)
|
ProcessExecutor.getInstance(ProcessExecutor.Processes.LIBRE_OFFICE)
|
||||||
.runCommandWithOutputHandling(command);
|
.runCommandWithOutputHandling(command);
|
||||||
|
|||||||
@@ -73,8 +73,8 @@ public class ConvertPDFToPDFA {
|
|||||||
// Determine PDF/A filter based on requested format
|
// Determine PDF/A filter based on requested format
|
||||||
String pdfFilter =
|
String pdfFilter =
|
||||||
"pdfa".equals(outputFormat)
|
"pdfa".equals(outputFormat)
|
||||||
? "writer_pdf_Export:{'SelectPdfVersion':{'Value':'2'}}:writer_pdf_Export"
|
? "pdf:writer_pdf_Export:{\"SelectPdfVersion\":{\"type\":\"long\",\"value\":\"2\"}}"
|
||||||
: "writer_pdf_Export:{'SelectPdfVersion':{'Value':'1'}}:writer_pdf_Export";
|
: "pdf:writer_pdf_Export:{\"SelectPdfVersion\":{\"type\":\"long\",\"value\":\"1\"}}";
|
||||||
|
|
||||||
// Prepare LibreOffice command
|
// Prepare LibreOffice command
|
||||||
List<String> command =
|
List<String> command =
|
||||||
@@ -84,7 +84,7 @@ public class ConvertPDFToPDFA {
|
|||||||
"--headless",
|
"--headless",
|
||||||
"--nologo",
|
"--nologo",
|
||||||
"--convert-to",
|
"--convert-to",
|
||||||
"pdf:" + pdfFilter,
|
pdfFilter,
|
||||||
"--outdir",
|
"--outdir",
|
||||||
tempOutputDir.toString(),
|
tempOutputDir.toString(),
|
||||||
tempInputFile.toString()));
|
tempInputFile.toString()));
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public class ConvertWebsiteToPDF {
|
|||||||
|
|
||||||
// Prepare the WeasyPrint command
|
// Prepare the WeasyPrint command
|
||||||
List<String> command = new ArrayList<>();
|
List<String> command = new ArrayList<>();
|
||||||
command.add("weasyprint");
|
command.add("/opt/venv/bin/weasyprint");
|
||||||
command.add(URL);
|
command.add(URL);
|
||||||
command.add(tempOutputFile.toString());
|
command.add(tempOutputFile.toString());
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
package stirling.software.SPDF.controller.api.converters;
|
package stirling.software.SPDF.controller.api.converters;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
import org.apache.commons.csv.CSVFormat;
|
import org.apache.commons.csv.CSVFormat;
|
||||||
import org.apache.commons.csv.QuoteMode;
|
import org.apache.commons.csv.QuoteMode;
|
||||||
@@ -18,18 +25,18 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import stirling.software.SPDF.model.api.extract.PDFFilePage;
|
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
||||||
import stirling.software.SPDF.pdf.FlexibleCSVWriter;
|
import stirling.software.SPDF.pdf.FlexibleCSVWriter;
|
||||||
import technology.tabula.ObjectExtractor;
|
import technology.tabula.ObjectExtractor;
|
||||||
import technology.tabula.Page;
|
import technology.tabula.Page;
|
||||||
import technology.tabula.Table;
|
import technology.tabula.Table;
|
||||||
import technology.tabula.extractors.SpreadsheetExtractionAlgorithm;
|
import technology.tabula.extractors.SpreadsheetExtractionAlgorithm;
|
||||||
import technology.tabula.writers.Writer;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/v1/convert")
|
@RequestMapping("/api/v1/convert")
|
||||||
@Tag(name = "Convert", description = "Convert APIs")
|
@Tag(name = "Convert", description = "Convert APIs")
|
||||||
|
@Slf4j
|
||||||
public class ExtractCSVController {
|
public class ExtractCSVController {
|
||||||
|
|
||||||
@PostMapping(value = "/pdf/csv", consumes = "multipart/form-data")
|
@PostMapping(value = "/pdf/csv", consumes = "multipart/form-data")
|
||||||
@@ -37,31 +44,80 @@ public class ExtractCSVController {
|
|||||||
summary = "Extracts a CSV document from a PDF",
|
summary = "Extracts a CSV document from a PDF",
|
||||||
description =
|
description =
|
||||||
"This operation takes an input PDF file and returns CSV file of whole page. Input:PDF Output:CSV Type:SISO")
|
"This operation takes an input PDF file and returns CSV file of whole page. Input:PDF Output:CSV Type:SISO")
|
||||||
public ResponseEntity<String> PdfToCsv(@ModelAttribute PDFFilePage form) throws Exception {
|
public ResponseEntity<?> pdfToCsv(@ModelAttribute PDFWithPageNums form) throws Exception {
|
||||||
StringWriter writer = new StringWriter();
|
String baseName = getBaseName(form.getFileInput().getOriginalFilename());
|
||||||
|
List<CsvEntry> csvEntries = new ArrayList<>();
|
||||||
|
|
||||||
try (PDDocument document = Loader.loadPDF(form.getFileInput().getBytes())) {
|
try (PDDocument document = Loader.loadPDF(form.getFileInput().getBytes())) {
|
||||||
CSVFormat format =
|
List<Integer> pages = form.getPageNumbersList(document, true);
|
||||||
CSVFormat.EXCEL.builder().setEscape('"').setQuoteMode(QuoteMode.ALL).build();
|
|
||||||
Writer csvWriter = new FlexibleCSVWriter(format);
|
|
||||||
SpreadsheetExtractionAlgorithm sea = new SpreadsheetExtractionAlgorithm();
|
SpreadsheetExtractionAlgorithm sea = new SpreadsheetExtractionAlgorithm();
|
||||||
|
CSVFormat format = CSVFormat.EXCEL.builder()
|
||||||
|
.setEscape('"')
|
||||||
|
.setQuoteMode(QuoteMode.ALL)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
for (int pageNum : pages) {
|
||||||
try (ObjectExtractor extractor = new ObjectExtractor(document)) {
|
try (ObjectExtractor extractor = new ObjectExtractor(document)) {
|
||||||
Page page = extractor.extract(form.getPageId());
|
log.info("{}",pageNum);
|
||||||
|
Page page = extractor.extract(pageNum);
|
||||||
List<Table> tables = sea.extract(page);
|
List<Table> tables = sea.extract(page);
|
||||||
csvWriter.write(writer, tables);
|
|
||||||
|
for (int i = 0; i < tables.size(); i++) {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
FlexibleCSVWriter csvWriter = new FlexibleCSVWriter(format);
|
||||||
|
csvWriter.write(sw, Collections.singletonList(tables.get(i)));
|
||||||
|
|
||||||
|
String entryName = generateEntryName(baseName, pageNum, i + 1);
|
||||||
|
csvEntries.add(new CsvEntry(entryName, sw.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (csvEntries.isEmpty()) {
|
||||||
|
return ResponseEntity.noContent().build();
|
||||||
|
} else if (csvEntries.size() == 1) {
|
||||||
|
return createCsvResponse(csvEntries.get(0), baseName);
|
||||||
|
} else {
|
||||||
|
return createZipResponse(csvEntries, baseName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResponseEntity<byte[]> createZipResponse(List<CsvEntry> entries, String baseName) throws IOException {
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
try (ZipOutputStream zipOut = new ZipOutputStream(baos)) {
|
||||||
|
for (CsvEntry entry : entries) {
|
||||||
|
ZipEntry zipEntry = new ZipEntry(entry.filename());
|
||||||
|
zipOut.putNextEntry(zipEntry);
|
||||||
|
zipOut.write(entry.content().getBytes(StandardCharsets.UTF_8));
|
||||||
|
zipOut.closeEntry();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
headers.setContentDisposition(
|
headers.setContentDisposition(ContentDisposition.builder("attachment")
|
||||||
ContentDisposition.builder("attachment")
|
.filename(baseName + "_extracted.zip").build());
|
||||||
.filename(
|
headers.setContentType(MediaType.parseMediaType("application/zip"));
|
||||||
form.getFileInput()
|
|
||||||
.getOriginalFilename()
|
return ResponseEntity.ok().headers(headers).body(baos.toByteArray());
|
||||||
.replaceFirst("[.][^.]+$", "")
|
}
|
||||||
+ "_extracted.csv")
|
|
||||||
.build());
|
private ResponseEntity<String> createCsvResponse(CsvEntry entry, String baseName) {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentDisposition(ContentDisposition.builder("attachment")
|
||||||
|
.filename(baseName + "_extracted.csv").build());
|
||||||
headers.setContentType(MediaType.parseMediaType("text/csv"));
|
headers.setContentType(MediaType.parseMediaType("text/csv"));
|
||||||
|
|
||||||
return ResponseEntity.ok().headers(headers).body(writer.toString());
|
return ResponseEntity.ok().headers(headers).body(entry.content());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String generateEntryName(String baseName, int pageNum, int tableIndex) {
|
||||||
|
return String.format("%s_p%d_t%d.csv", baseName, pageNum, tableIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getBaseName(String filename) {
|
||||||
|
return filename.replaceFirst("[.][^.]+$", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
private record CsvEntry(String filename, String content) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ import java.io.IOException;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
@@ -41,8 +43,12 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||||||
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
public class AutoSplitPdfController {
|
public class AutoSplitPdfController {
|
||||||
|
|
||||||
private static final String QR_CONTENT = "https://github.com/Stirling-Tools/Stirling-PDF";
|
private static final Set<String> VALID_QR_CONTENTS =
|
||||||
private static final String QR_CONTENT_OLD = "https://github.com/Frooodle/Stirling-PDF";
|
new HashSet<>(
|
||||||
|
Set.of(
|
||||||
|
"https://github.com/Stirling-Tools/Stirling-PDF",
|
||||||
|
"https://github.com/Frooodle/Stirling-PDF",
|
||||||
|
"https://stirlingpdf.com"));
|
||||||
|
|
||||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@@ -120,13 +126,14 @@ public class AutoSplitPdfController {
|
|||||||
for (int page = 0; page < document.getNumberOfPages(); ++page) {
|
for (int page = 0; page < document.getNumberOfPages(); ++page) {
|
||||||
BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 150);
|
BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 150);
|
||||||
String result = decodeQRCode(bim);
|
String result = decodeQRCode(bim);
|
||||||
if ((QR_CONTENT.equals(result) || QR_CONTENT_OLD.equals(result)) && page != 0) {
|
|
||||||
|
boolean isValidQrCode = VALID_QR_CONTENTS.contains(result);
|
||||||
|
log.debug("detected qr code {}, code is vale={}", result, isValidQrCode);
|
||||||
|
if (isValidQrCode && page != 0) {
|
||||||
splitDocuments.add(new PDDocument());
|
splitDocuments.add(new PDDocument());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!splitDocuments.isEmpty()
|
if (!splitDocuments.isEmpty() && !isValidQrCode) {
|
||||||
&& !QR_CONTENT.equals(result)
|
|
||||||
&& !QR_CONTENT_OLD.equals(result)) {
|
|
||||||
splitDocuments.get(splitDocuments.size() - 1).addPage(document.getPage(page));
|
splitDocuments.get(splitDocuments.size() - 1).addPage(document.getPage(page));
|
||||||
} else if (page == 0) {
|
} else if (page == 0) {
|
||||||
PDDocument firstDocument = new PDDocument();
|
PDDocument firstDocument = new PDDocument();
|
||||||
@@ -135,7 +142,7 @@ public class AutoSplitPdfController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If duplexMode is true and current page is a divider, then skip next page
|
// If duplexMode is true and current page is a divider, then skip next page
|
||||||
if (duplexMode && (QR_CONTENT.equals(result) || QR_CONTENT_OLD.equals(result))) {
|
if (duplexMode && isValidQrCode) {
|
||||||
page++;
|
page++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,6 +175,9 @@ public class AutoSplitPdfController {
|
|||||||
|
|
||||||
return WebResponseUtils.bytesToWebResponse(
|
return WebResponseUtils.bytesToWebResponse(
|
||||||
data, filename + ".zip", MediaType.APPLICATION_OCTET_STREAM);
|
data, filename + ".zip", MediaType.APPLICATION_OCTET_STREAM);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error in auto split", e);
|
||||||
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
// Clean up resources
|
// Clean up resources
|
||||||
if (document != null) {
|
if (document != null) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import java.awt.image.BufferedImage;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -94,7 +95,9 @@ public class CompressController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
doc.save(pdfFile.toString());
|
Path tempOutput = Files.createTempFile("output_", ".pdf");
|
||||||
|
doc.save(tempOutput.toString());
|
||||||
|
Files.move(tempOutput, pdfFile, StandardCopyOption.REPLACE_EXISTING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +191,7 @@ public class CompressController {
|
|||||||
optimizeLevel =
|
optimizeLevel =
|
||||||
incrementOptimizeLevel(
|
incrementOptimizeLevel(
|
||||||
optimizeLevel, outputFileSize, expectedOutputSize);
|
optimizeLevel, outputFileSize, expectedOutputSize);
|
||||||
if (autoMode && optimizeLevel > 9) {
|
if (autoMode && optimizeLevel >= 9) {
|
||||||
log.info("Maximum compression level reached in auto mode");
|
log.info("Maximum compression level reached in auto mode");
|
||||||
sizeMet = true;
|
sizeMet = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import org.springframework.web.multipart.MultipartFile;
|
|||||||
|
|
||||||
import io.github.pixee.security.BoundedLineReader;
|
import io.github.pixee.security.BoundedLineReader;
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -65,6 +66,10 @@ public class OCRController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/ocr-pdf")
|
@PostMapping(consumes = "multipart/form-data", value = "/ocr-pdf")
|
||||||
|
@Operation(
|
||||||
|
summary = "Process PDF files with OCR using Tesseract",
|
||||||
|
description =
|
||||||
|
"Takes a PDF file as input, performs OCR using specified languages and OCR type (skip-text/force-ocr), and returns the processed PDF. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<byte[]> processPdfWithOCR(
|
public ResponseEntity<byte[]> processPdfWithOCR(
|
||||||
@ModelAttribute ProcessPdfWithOcrRequest request)
|
@ModelAttribute ProcessPdfWithOcrRequest request)
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import stirling.software.SPDF.model.PipelineConfig;
|
import stirling.software.SPDF.model.PipelineConfig;
|
||||||
|
import stirling.software.SPDF.model.PipelineResult;
|
||||||
import stirling.software.SPDF.model.api.HandleDataRequest;
|
import stirling.software.SPDF.model.api.HandleDataRequest;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@@ -58,7 +59,8 @@ public class PipelineController {
|
|||||||
if (inputFiles == null || inputFiles.size() == 0) {
|
if (inputFiles == null || inputFiles.size() == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
List<Resource> outputFiles = processor.runPipelineAgainstFiles(inputFiles, config);
|
PipelineResult result = processor.runPipelineAgainstFiles(inputFiles, config);
|
||||||
|
List<Resource> outputFiles = result.getOutputFiles();
|
||||||
if (outputFiles != null && outputFiles.size() == 1) {
|
if (outputFiles != null && outputFiles.size() == 1) {
|
||||||
// If there is only one file, return it directly
|
// If there is only one file, return it directly
|
||||||
Resource singleFile = outputFiles.get(0);
|
Resource singleFile = outputFiles.get(0);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import stirling.software.SPDF.config.InstallationPathConfig;
|
import stirling.software.SPDF.config.InstallationPathConfig;
|
||||||
import stirling.software.SPDF.model.PipelineConfig;
|
import stirling.software.SPDF.model.PipelineConfig;
|
||||||
import stirling.software.SPDF.model.PipelineOperation;
|
import stirling.software.SPDF.model.PipelineOperation;
|
||||||
|
import stirling.software.SPDF.model.PipelineResult;
|
||||||
import stirling.software.SPDF.utils.FileMonitor;
|
import stirling.software.SPDF.utils.FileMonitor;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -143,19 +144,64 @@ public class PipelineDirectoryProcessor {
|
|||||||
|
|
||||||
private File[] collectFilesForProcessing(Path dir, Path jsonFile, PipelineOperation operation)
|
private File[] collectFilesForProcessing(Path dir, Path jsonFile, PipelineOperation operation)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
|
List<String> inputExtensions =
|
||||||
|
apiDocService.getExtensionTypes(false, operation.getOperation());
|
||||||
|
log.info(
|
||||||
|
"Allowed extensions for operation {}: {}",
|
||||||
|
operation.getOperation(),
|
||||||
|
inputExtensions);
|
||||||
|
|
||||||
|
boolean allowAllFiles = inputExtensions.contains("ALL");
|
||||||
|
|
||||||
try (Stream<Path> paths = Files.list(dir)) {
|
try (Stream<Path> paths = Files.list(dir)) {
|
||||||
if ("automated".equals(operation.getParameters().get("fileInput"))) {
|
File[] files =
|
||||||
return paths.filter(
|
paths.filter(
|
||||||
path ->
|
path -> {
|
||||||
!Files.isDirectory(path)
|
if (Files.isDirectory(path)) {
|
||||||
&& !path.equals(jsonFile)
|
return false;
|
||||||
&& fileMonitor.isFileReadyForProcessing(path))
|
}
|
||||||
|
if (path.equals(jsonFile)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get file extension
|
||||||
|
String filename = path.getFileName().toString();
|
||||||
|
String extension =
|
||||||
|
filename.contains(".")
|
||||||
|
? filename.substring(
|
||||||
|
filename.lastIndexOf(".")
|
||||||
|
+ 1)
|
||||||
|
.toLowerCase()
|
||||||
|
: "";
|
||||||
|
|
||||||
|
// Check against allowed extensions
|
||||||
|
boolean isAllowed =
|
||||||
|
allowAllFiles
|
||||||
|
|| inputExtensions.contains(extension);
|
||||||
|
if (!isAllowed) {
|
||||||
|
log.info(
|
||||||
|
"Skipping file with unsupported extension: {} ({})",
|
||||||
|
filename,
|
||||||
|
extension);
|
||||||
|
}
|
||||||
|
return isAllowed;
|
||||||
|
})
|
||||||
|
.filter(
|
||||||
|
path -> {
|
||||||
|
boolean isReady =
|
||||||
|
fileMonitor.isFileReadyForProcessing(path);
|
||||||
|
if (!isReady) {
|
||||||
|
log.info(
|
||||||
|
"File not ready for processing (locked/created last 5s): {}",
|
||||||
|
path);
|
||||||
|
}
|
||||||
|
return isReady;
|
||||||
|
})
|
||||||
.map(Path::toFile)
|
.map(Path::toFile)
|
||||||
.toArray(File[]::new);
|
.toArray(File[]::new);
|
||||||
} else {
|
log.info("Collected {} files for processing", files.length);
|
||||||
String fileInput = (String) operation.getParameters().get("fileInput");
|
return files;
|
||||||
return new File[] {new File(fileInput)};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,19 +244,37 @@ public class PipelineDirectoryProcessor {
|
|||||||
try {
|
try {
|
||||||
List<Resource> inputFiles =
|
List<Resource> inputFiles =
|
||||||
processor.generateInputFiles(filesToProcess.toArray(new File[0]));
|
processor.generateInputFiles(filesToProcess.toArray(new File[0]));
|
||||||
if (inputFiles == null || inputFiles.size() == 0) {
|
if (inputFiles == null || inputFiles.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<Resource> outputFiles = processor.runPipelineAgainstFiles(inputFiles, config);
|
PipelineResult result = processor.runPipelineAgainstFiles(inputFiles, config);
|
||||||
if (outputFiles == null) return;
|
|
||||||
moveAndRenameFiles(outputFiles, config, dir);
|
if (result.isHasErrors()) {
|
||||||
|
log.error("Errors occurred during processing, retaining original files");
|
||||||
|
moveToErrorDirectory(filesToProcess, dir);
|
||||||
|
} else {
|
||||||
|
moveAndRenameFiles(result.getOutputFiles(), config, dir);
|
||||||
deleteOriginalFiles(filesToProcess, processingDir);
|
deleteOriginalFiles(filesToProcess, processingDir);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("error during processing", e);
|
log.error("Error during processing", e);
|
||||||
moveFilesBack(filesToProcess, processingDir);
|
moveFilesBack(filesToProcess, processingDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void moveToErrorDirectory(List<File> files, Path originalDir) throws IOException {
|
||||||
|
Path errorDir = originalDir.resolve("error");
|
||||||
|
if (!Files.exists(errorDir)) {
|
||||||
|
Files.createDirectories(errorDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (File file : files) {
|
||||||
|
Path target = errorDir.resolve(file.getName());
|
||||||
|
Files.move(file.toPath(), target);
|
||||||
|
log.info("Moved failed file to error directory for investigation: {}", target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void moveAndRenameFiles(List<Resource> resources, PipelineConfig config, Path dir)
|
private void moveAndRenameFiles(List<Resource> resources, PipelineConfig config, Path dir)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
for (Resource resource : resources) {
|
for (Resource resource : resources) {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import stirling.software.SPDF.SPDFApplication;
|
import stirling.software.SPDF.SPDFApplication;
|
||||||
import stirling.software.SPDF.model.PipelineConfig;
|
import stirling.software.SPDF.model.PipelineConfig;
|
||||||
import stirling.software.SPDF.model.PipelineOperation;
|
import stirling.software.SPDF.model.PipelineOperation;
|
||||||
|
import stirling.software.SPDF.model.PipelineResult;
|
||||||
import stirling.software.SPDF.model.Role;
|
import stirling.software.SPDF.model.Role;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -84,8 +85,10 @@ public class PipelineProcessor {
|
|||||||
return "http://localhost:" + port + contextPath + "/";
|
return "http://localhost:" + port + contextPath + "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Resource> runPipelineAgainstFiles(List<Resource> outputFiles, PipelineConfig config)
|
PipelineResult runPipelineAgainstFiles(List<Resource> outputFiles, PipelineConfig config)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
PipelineResult result = new PipelineResult();
|
||||||
|
|
||||||
ByteArrayOutputStream logStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream logStream = new ByteArrayOutputStream();
|
||||||
PrintStream logPrintStream = new PrintStream(logStream);
|
PrintStream logPrintStream = new PrintStream(logStream);
|
||||||
boolean hasErrors = false;
|
boolean hasErrors = false;
|
||||||
@@ -130,7 +133,8 @@ public class PipelineProcessor {
|
|||||||
if (operation.startsWith("filter-")
|
if (operation.startsWith("filter-")
|
||||||
&& (response.getBody() == null
|
&& (response.getBody() == null
|
||||||
|| response.getBody().length == 0)) {
|
|| response.getBody().length == 0)) {
|
||||||
log.info("Skipping file due to failing {}", operation);
|
result.setFiltersApplied(true);
|
||||||
|
log.info("Skipping file due to filtering {}", operation);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!response.getStatusCode().equals(HttpStatus.OK)) {
|
if (!response.getStatusCode().equals(HttpStatus.OK)) {
|
||||||
@@ -208,7 +212,10 @@ public class PipelineProcessor {
|
|||||||
if (hasErrors) {
|
if (hasErrors) {
|
||||||
log.error("Errors occurred during processing. Log: {}", logStream.toString());
|
log.error("Errors occurred during processing. Log: {}", logStream.toString());
|
||||||
}
|
}
|
||||||
return outputFiles;
|
result.setHasErrors(hasErrors);
|
||||||
|
result.setFiltersApplied(hasErrors);
|
||||||
|
result.setOutputFiles(outputFiles);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseEntity<byte[]> sendWebRequest(String url, MultiValueMap<String, Object> body) {
|
private ResponseEntity<byte[]> sendWebRequest(String url, MultiValueMap<String, Object> body) {
|
||||||
|
|||||||
@@ -40,8 +40,7 @@ public class RemoveCertSignController {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "Remove digital signature from PDF",
|
summary = "Remove digital signature from PDF",
|
||||||
description =
|
description =
|
||||||
"This endpoint accepts a PDF file and returns the PDF file without the digital signature."
|
"This endpoint accepts a PDF file and returns the PDF file without the digital signature. Input:PDF, Output:PDF Type:SISO")
|
||||||
+ " Input: PDF, Output: PDF")
|
|
||||||
public ResponseEntity<byte[]> removeCertSignPDF(@ModelAttribute PDFFile request)
|
public ResponseEntity<byte[]> removeCertSignPDF(@ModelAttribute PDFFile request)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MultipartFile pdf = request.getFileInput();
|
MultipartFile pdf = request.getFileInput();
|
||||||
|
|||||||
@@ -36,8 +36,9 @@ public class DatabaseWebController {
|
|||||||
}
|
}
|
||||||
List<FileInfo> backupList = databaseService.getBackupList();
|
List<FileInfo> backupList = databaseService.getBackupList();
|
||||||
model.addAttribute("backupFiles", backupList);
|
model.addAttribute("backupFiles", backupList);
|
||||||
model.addAttribute("databaseVersion", databaseService.getH2Version());
|
String dbVersion = databaseService.getH2Version();
|
||||||
if ("Unknown".equalsIgnoreCase(databaseService.getH2Version())) {
|
model.addAttribute("databaseVersion", dbVersion);
|
||||||
|
if ("Unknown".equalsIgnoreCase(dbVersion)) {
|
||||||
model.addAttribute("infoMessage", "notSupported");
|
model.addAttribute("infoMessage", "notSupported");
|
||||||
}
|
}
|
||||||
return "database";
|
return "database";
|
||||||
|
|||||||
@@ -74,6 +74,12 @@ public class HomeWebController {
|
|||||||
return "redirect:/";
|
return "redirect:/";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/home-legacy")
|
||||||
|
public String homeLegacy(Model model) {
|
||||||
|
model.addAttribute("currentPage", "home-legacy");
|
||||||
|
return "home-legacy";
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping(value = "/robots.txt", produces = MediaType.TEXT_PLAIN_VALUE)
|
@GetMapping(value = "/robots.txt", produces = MediaType.TEXT_PLAIN_VALUE)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@Hidden
|
@Hidden
|
||||||
|
|||||||
@@ -265,7 +265,8 @@ public class ApplicationProperties {
|
|||||||
return getKeycloak();
|
return getKeycloak();
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedProviderException(
|
throw new UnsupportedProviderException(
|
||||||
"Logout from the provider is not supported? Report it at https://github.com/Stirling-Tools/Stirling-PDF/issues");
|
"Logout from the provider is not supported? Report it at"
|
||||||
|
+ " https://github.com/Stirling-Tools/Stirling-PDF/issues");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -283,6 +284,7 @@ public class ApplicationProperties {
|
|||||||
private Boolean enableAlphaFunctionality;
|
private Boolean enableAlphaFunctionality;
|
||||||
private String enableAnalytics;
|
private String enableAnalytics;
|
||||||
private Datasource datasource;
|
private Datasource datasource;
|
||||||
|
private Boolean disableSanitize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@@ -325,6 +327,7 @@ public class ApplicationProperties {
|
|||||||
private String appName;
|
private String appName;
|
||||||
private String homeDescription;
|
private String homeDescription;
|
||||||
private String appNameNavbar;
|
private String appNameNavbar;
|
||||||
|
private List<String> languages;
|
||||||
|
|
||||||
public String getAppName() {
|
public String getAppName() {
|
||||||
return appName != null && appName.trim().length() > 0 ? appName : null;
|
return appName != null && appName.trim().length() > 0 ? appName : null;
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package stirling.software.SPDF.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class PipelineResult {
|
||||||
|
private List<Resource> outputFiles;
|
||||||
|
private boolean hasErrors;
|
||||||
|
private boolean filtersApplied;
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package stirling.software.SPDF.model;
|
package stirling.software.SPDF.model;
|
||||||
|
|
||||||
public enum SortTypes {
|
public enum SortTypes {
|
||||||
|
CUSTOM,
|
||||||
REVERSE_ORDER,
|
REVERSE_ORDER,
|
||||||
DUPLEX_SORT,
|
DUPLEX_SORT,
|
||||||
BOOKLET_SORT,
|
BOOKLET_SORT,
|
||||||
@@ -10,4 +11,5 @@ public enum SortTypes {
|
|||||||
REMOVE_FIRST,
|
REMOVE_FIRST,
|
||||||
REMOVE_LAST,
|
REMOVE_LAST,
|
||||||
REMOVE_FIRST_AND_LAST,
|
REMOVE_FIRST_AND_LAST,
|
||||||
|
DUPLICATE
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Hidden;
|
import io.swagger.v3.oas.annotations.Hidden;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema.RequiredMode;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@@ -25,7 +26,9 @@ public class PDFWithPageNums extends PDFFile {
|
|||||||
description =
|
description =
|
||||||
"The pages to select, Supports ranges (e.g., '1,3,5-9'), or 'all' or functions in the"
|
"The pages to select, Supports ranges (e.g., '1,3,5-9'), or 'all' or functions in the"
|
||||||
+ " format 'an+b' where 'a' is the multiplier of the page number 'n', and 'b' is a"
|
+ " format 'an+b' where 'a' is the multiplier of the page number 'n', and 'b' is a"
|
||||||
+ " constant (e.g., '2n+1', '3n', '6n-5')\"")
|
+ " constant (e.g., '2n+1', '3n', '6n-5')\"",
|
||||||
|
defaultValue = "all",
|
||||||
|
requiredMode = RequiredMode.NOT_REQUIRED)
|
||||||
private String pageNumbers;
|
private String pageNumbers;
|
||||||
|
|
||||||
@Hidden
|
@Hidden
|
||||||
@@ -41,9 +44,9 @@ public class PDFWithPageNums extends PDFFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Hidden
|
@Hidden
|
||||||
public List<Integer> getPageNumbersList(PDDocument doc, boolean zeroCount) {
|
public List<Integer> getPageNumbersList(PDDocument doc, boolean oneBased) {
|
||||||
int pageCount = 0;
|
int pageCount = 0;
|
||||||
pageCount = doc.getNumberOfPages();
|
pageCount = doc.getNumberOfPages();
|
||||||
return GeneralUtils.parsePageList(pageNumbers, pageCount, zeroCount);
|
return GeneralUtils.parsePageList(pageNumbers, pageCount, oneBased);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
package stirling.software.SPDF.model.api.extract;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import stirling.software.SPDF.model.api.PDFFile;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
public class PDFFilePage extends PDFFile {
|
|
||||||
|
|
||||||
@Schema(description = "Number of chosen page", type = "number")
|
|
||||||
private int pageId;
|
|
||||||
}
|
|
||||||
@@ -15,6 +15,8 @@ public class RearrangePagesRequest extends PDFWithPageNums {
|
|||||||
implementation = SortTypes.class,
|
implementation = SortTypes.class,
|
||||||
description =
|
description =
|
||||||
"The custom mode for page rearrangement. Valid values are:\n"
|
"The custom mode for page rearrangement. Valid values are:\n"
|
||||||
|
+ "CUSTOM: Uses order defined in PageNums "
|
||||||
|
+ "DUPLICATE: Duplicate pages n times (if Page order defined as 4, then duplicates each page 4 times)"
|
||||||
+ "REVERSE_ORDER: Reverses the order of all pages.\n"
|
+ "REVERSE_ORDER: Reverses the order of all pages.\n"
|
||||||
+ "DUPLEX_SORT: Sorts pages as if all fronts were scanned then all backs in reverse (1, n, 2, n-1, ...). "
|
+ "DUPLEX_SORT: Sorts pages as if all fronts were scanned then all backs in reverse (1, n, 2, n-1, ...). "
|
||||||
+ "BOOKLET_SORT: Arranges pages for booklet printing (last, first, second, second last, ...).\n"
|
+ "BOOKLET_SORT: Arranges pages for booklet printing (last, first, second, second last, ...).\n"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package stirling.software.SPDF.model.api.misc;
|
package stirling.software.SPDF.model.api.misc;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema.RequiredMode;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@@ -11,24 +12,49 @@ import stirling.software.SPDF.model.api.PDFWithPageNums;
|
|||||||
public class AddPageNumbersRequest extends PDFWithPageNums {
|
public class AddPageNumbersRequest extends PDFWithPageNums {
|
||||||
|
|
||||||
@Schema(
|
@Schema(
|
||||||
description = "Custom margin: small/medium/large",
|
description = "Custom margin: small/medium/large/x-large",
|
||||||
allowableValues = {"small", "medium", "large"})
|
allowableValues = {"small", "medium", "large", "x-large"},
|
||||||
|
defaultValue = "medium",
|
||||||
|
requiredMode = RequiredMode.NOT_REQUIRED)
|
||||||
private String customMargin;
|
private String customMargin;
|
||||||
|
|
||||||
|
@Schema(
|
||||||
|
description = "Font size for page numbers",
|
||||||
|
minimum = "1",
|
||||||
|
requiredMode = RequiredMode.REQUIRED)
|
||||||
private float fontSize;
|
private float fontSize;
|
||||||
|
|
||||||
|
@Schema(
|
||||||
|
description = "Font type for page numbers",
|
||||||
|
allowableValues = {"helvetica", "courier", "times"},
|
||||||
|
requiredMode = RequiredMode.REQUIRED)
|
||||||
private String fontType;
|
private String fontType;
|
||||||
|
|
||||||
@Schema(description = "Position: 1 of 9 positions", minimum = "1", maximum = "9")
|
@Schema(
|
||||||
|
description =
|
||||||
|
"Position: 1-9 representing positions on the page (1=top-left, 5=center, 9=bottom-right)",
|
||||||
|
minimum = "1",
|
||||||
|
maximum = "9",
|
||||||
|
requiredMode = RequiredMode.REQUIRED)
|
||||||
private int position;
|
private int position;
|
||||||
|
|
||||||
@Schema(description = "Starting number", minimum = "1")
|
@Schema(
|
||||||
|
description = "Starting number for page numbering",
|
||||||
|
minimum = "1",
|
||||||
|
requiredMode = RequiredMode.REQUIRED)
|
||||||
private int startingNumber;
|
private int startingNumber;
|
||||||
|
|
||||||
@Schema(description = "Which pages to number, default all")
|
@Schema(
|
||||||
|
description = "Which pages to number (e.g. '1,3-5,7' or 'all')",
|
||||||
|
defaultValue = "all",
|
||||||
|
requiredMode = RequiredMode.NOT_REQUIRED)
|
||||||
private String pagesToNumber;
|
private String pagesToNumber;
|
||||||
|
|
||||||
@Schema(
|
@Schema(
|
||||||
description =
|
description =
|
||||||
"Custom text: defaults to just number but can have things like \"Page {n} of {p}\"")
|
"Custom text pattern. Available variables: {n}=current page number, {total}=total pages, {filename}=original filename",
|
||||||
|
example = "Page {n} of {total}",
|
||||||
|
defaultValue = "{n}",
|
||||||
|
requiredMode = RequiredMode.NOT_REQUIRED)
|
||||||
private String customText;
|
private String customText;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,41 +1,56 @@
|
|||||||
package stirling.software.SPDF.service;
|
package stirling.software.SPDF.service;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@Slf4j
|
||||||
public class LanguageService {
|
public class LanguageService {
|
||||||
|
|
||||||
|
private final ApplicationProperties applicationProperties;
|
||||||
private final PathMatchingResourcePatternResolver resourcePatternResolver =
|
private final PathMatchingResourcePatternResolver resourcePatternResolver =
|
||||||
new PathMatchingResourcePatternResolver();
|
new PathMatchingResourcePatternResolver();
|
||||||
|
|
||||||
public List<String> getSupportedLanguages() {
|
public LanguageService(ApplicationProperties applicationProperties) {
|
||||||
List<String> supportedLanguages = new ArrayList<>();
|
this.applicationProperties = applicationProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getSupportedLanguages() {
|
||||||
try {
|
try {
|
||||||
Resource[] resources =
|
Resource[] resources =
|
||||||
resourcePatternResolver.getResources("classpath*:messages_*.properties");
|
resourcePatternResolver.getResources("classpath*:messages_*.properties");
|
||||||
for (Resource resource : resources) {
|
|
||||||
if (resource.exists() && resource.isReadable()) {
|
|
||||||
String filename = resource.getFilename();
|
|
||||||
if (filename != null
|
|
||||||
&& filename.startsWith("messages_")
|
|
||||||
&& filename.endsWith(".properties")) {
|
|
||||||
String languageCode =
|
|
||||||
filename.replace("messages_", "").replace(".properties", "");
|
|
||||||
supportedLanguages.add(languageCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return supportedLanguages;
|
return Arrays.stream(resources)
|
||||||
|
.map(Resource::getFilename)
|
||||||
|
.filter(
|
||||||
|
filename ->
|
||||||
|
filename != null
|
||||||
|
&& filename.startsWith("messages_")
|
||||||
|
&& filename.endsWith(".properties"))
|
||||||
|
.map(filename -> filename.replace("messages_", "").replace(".properties", ""))
|
||||||
|
.filter(
|
||||||
|
languageCode -> {
|
||||||
|
Set<String> allowedLanguages =
|
||||||
|
new HashSet<>(applicationProperties.getUi().getLanguages());
|
||||||
|
return allowedLanguages.isEmpty()
|
||||||
|
|| allowedLanguages.contains(languageCode)
|
||||||
|
|| "en_GB".equals(languageCode);
|
||||||
|
})
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Error retrieving supported languages", e);
|
||||||
|
return new HashSet<>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ public class FileToPdf {
|
|||||||
HTMLToPdfRequest request,
|
HTMLToPdfRequest request,
|
||||||
byte[] fileBytes,
|
byte[] fileBytes,
|
||||||
String fileName,
|
String fileName,
|
||||||
boolean htmlFormatsInstalled)
|
boolean htmlFormatsInstalled,
|
||||||
|
boolean disableSanitize)
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
|
|
||||||
Path tempOutputFile = Files.createTempFile("output_", ".pdf");
|
Path tempOutputFile = Files.createTempFile("output_", ".pdf");
|
||||||
@@ -36,19 +37,20 @@ public class FileToPdf {
|
|||||||
if (fileName.endsWith(".html")) {
|
if (fileName.endsWith(".html")) {
|
||||||
tempInputFile = Files.createTempFile("input_", ".html");
|
tempInputFile = Files.createTempFile("input_", ".html");
|
||||||
String sanitizedHtml =
|
String sanitizedHtml =
|
||||||
sanitizeHtmlContent(new String(fileBytes, StandardCharsets.UTF_8));
|
sanitizeHtmlContent(
|
||||||
|
new String(fileBytes, StandardCharsets.UTF_8), disableSanitize);
|
||||||
Files.write(tempInputFile, sanitizedHtml.getBytes(StandardCharsets.UTF_8));
|
Files.write(tempInputFile, sanitizedHtml.getBytes(StandardCharsets.UTF_8));
|
||||||
} else if (fileName.endsWith(".zip")) {
|
} else if (fileName.endsWith(".zip")) {
|
||||||
tempInputFile = Files.createTempFile("input_", ".zip");
|
tempInputFile = Files.createTempFile("input_", ".zip");
|
||||||
Files.write(tempInputFile, fileBytes);
|
Files.write(tempInputFile, fileBytes);
|
||||||
sanitizeHtmlFilesInZip(tempInputFile);
|
sanitizeHtmlFilesInZip(tempInputFile, disableSanitize);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unsupported file format: " + fileName);
|
throw new IllegalArgumentException("Unsupported file format: " + fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> command = new ArrayList<>();
|
List<String> command = new ArrayList<>();
|
||||||
if (!htmlFormatsInstalled) {
|
if (!htmlFormatsInstalled) {
|
||||||
command.add("weasyprint");
|
command.add("/opt/venv/bin/weasyprint");
|
||||||
command.add("-e");
|
command.add("-e");
|
||||||
command.add("utf-8");
|
command.add("utf-8");
|
||||||
command.add("-v");
|
command.add("-v");
|
||||||
@@ -89,11 +91,12 @@ public class FileToPdf {
|
|||||||
return pdfBytes;
|
return pdfBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String sanitizeHtmlContent(String htmlContent) {
|
private static String sanitizeHtmlContent(String htmlContent, boolean disableSanitize) {
|
||||||
return CustomHtmlSanitizer.sanitize(htmlContent);
|
return (!disableSanitize) ? CustomHtmlSanitizer.sanitize(htmlContent) : htmlContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void sanitizeHtmlFilesInZip(Path zipFilePath) throws IOException {
|
private static void sanitizeHtmlFilesInZip(Path zipFilePath, boolean disableSanitize)
|
||||||
|
throws IOException {
|
||||||
Path tempUnzippedDir = Files.createTempDirectory("unzipped_");
|
Path tempUnzippedDir = Files.createTempDirectory("unzipped_");
|
||||||
try (ZipInputStream zipIn =
|
try (ZipInputStream zipIn =
|
||||||
ZipSecurity.createHardenedInputStream(
|
ZipSecurity.createHardenedInputStream(
|
||||||
@@ -106,7 +109,7 @@ public class FileToPdf {
|
|||||||
if (entry.getName().toLowerCase().endsWith(".html")
|
if (entry.getName().toLowerCase().endsWith(".html")
|
||||||
|| entry.getName().toLowerCase().endsWith(".htm")) {
|
|| entry.getName().toLowerCase().endsWith(".htm")) {
|
||||||
String content = new String(zipIn.readAllBytes(), StandardCharsets.UTF_8);
|
String content = new String(zipIn.readAllBytes(), StandardCharsets.UTF_8);
|
||||||
String sanitizedContent = sanitizeHtmlContent(content);
|
String sanitizedContent = sanitizeHtmlContent(content, disableSanitize);
|
||||||
Files.write(filePath, sanitizedContent.getBytes(StandardCharsets.UTF_8));
|
Files.write(filePath, sanitizedContent.getBytes(StandardCharsets.UTF_8));
|
||||||
} else {
|
} else {
|
||||||
Files.copy(zipIn, filePath);
|
Files.copy(zipIn, filePath);
|
||||||
|
|||||||
@@ -9,15 +9,17 @@ import java.nio.charset.StandardCharsets;
|
|||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Deque;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.simpleyaml.configuration.file.YamlFile;
|
|
||||||
import org.simpleyaml.configuration.file.YamlFileWrapper;
|
|
||||||
import org.simpleyaml.configuration.implementation.SimpleYamlImplementation;
|
|
||||||
import org.simpleyaml.configuration.implementation.snakeyaml.lib.DumperOptions;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import com.fathzer.soft.javaluator.DoubleEvaluator;
|
import com.fathzer.soft.javaluator.DoubleEvaluator;
|
||||||
@@ -208,8 +210,7 @@ public class GeneralUtils {
|
|||||||
result.addAll(handlePart(page, totalPages, offset));
|
result.addAll(handlePart(page, totalPages, offset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ArrayList<>(
|
return result;
|
||||||
new java.util.LinkedHashSet<>(result)); // Remove duplicates and maintain order
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Integer> evaluateNFunc(String expression, int maxValue) {
|
public static List<Integer> evaluateNFunc(String expression, int maxValue) {
|
||||||
@@ -285,7 +286,10 @@ public class GeneralUtils {
|
|||||||
String[] rangeParts = part.split("-");
|
String[] rangeParts = part.split("-");
|
||||||
try {
|
try {
|
||||||
int start = Integer.parseInt(rangeParts[0]);
|
int start = Integer.parseInt(rangeParts[0]);
|
||||||
int end = Integer.parseInt(rangeParts[1]);
|
int end =
|
||||||
|
(rangeParts.length > 1 && !rangeParts[1].isEmpty())
|
||||||
|
? Integer.parseInt(rangeParts[1])
|
||||||
|
: totalPages;
|
||||||
for (int i = start; i <= end; i++) {
|
for (int i = start; i <= end; i++) {
|
||||||
if (i >= 1 && i <= totalPages) {
|
if (i >= 1 && i <= totalPages) {
|
||||||
partResult.add(i - 1 + offset);
|
partResult.add(i - 1 + offset);
|
||||||
@@ -343,41 +347,208 @@ public class GeneralUtils {
|
|||||||
|
|
||||||
public static void saveKeyToConfig(String id, String key, boolean autoGenerated)
|
public static void saveKeyToConfig(String id, String key, boolean autoGenerated)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
Path path =
|
doSaveKeyToConfig(id, (key == null ? "" : key), autoGenerated);
|
||||||
Paths.get(
|
|
||||||
InstallationPathConfig
|
|
||||||
.getSettingsPath()); // Target the configs/settings.yml
|
|
||||||
|
|
||||||
final YamlFile settingsYml = new YamlFile(path.toFile());
|
|
||||||
DumperOptions yamlOptionssettingsYml =
|
|
||||||
((SimpleYamlImplementation) settingsYml.getImplementation()).getDumperOptions();
|
|
||||||
yamlOptionssettingsYml.setSplitLines(false);
|
|
||||||
|
|
||||||
settingsYml.loadWithComments();
|
|
||||||
|
|
||||||
YamlFileWrapper writer = settingsYml.path(id).set(key);
|
|
||||||
if (autoGenerated) {
|
|
||||||
writer.comment("# Automatically Generated Settings (Do Not Edit Directly)");
|
|
||||||
}
|
|
||||||
settingsYml.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void saveKeyToConfig(String id, boolean key, boolean autoGenerated)
|
public static void saveKeyToConfig(String id, boolean key, boolean autoGenerated)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
Path path = Paths.get(InstallationPathConfig.getSettingsPath());
|
doSaveKeyToConfig(id, String.valueOf(key), autoGenerated);
|
||||||
|
|
||||||
final YamlFile settingsYml = new YamlFile(path.toFile());
|
|
||||||
DumperOptions yamlOptionssettingsYml =
|
|
||||||
((SimpleYamlImplementation) settingsYml.getImplementation()).getDumperOptions();
|
|
||||||
yamlOptionssettingsYml.setSplitLines(false);
|
|
||||||
|
|
||||||
settingsYml.loadWithComments();
|
|
||||||
|
|
||||||
YamlFileWrapper writer = settingsYml.path(id).set(key);
|
|
||||||
if (autoGenerated) {
|
|
||||||
writer.comment("# Automatically Generated Settings (Do Not Edit Directly)");
|
|
||||||
}
|
}
|
||||||
settingsYml.save();
|
|
||||||
|
/*------------------------------------------------------------------------*
|
||||||
|
* Internal Implementation Details *
|
||||||
|
*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actually performs the line-based update for the given path (e.g. "security.csrfDisabled") to
|
||||||
|
* a new string value (e.g. "true"), possibly marking it as auto-generated.
|
||||||
|
*/
|
||||||
|
private static void doSaveKeyToConfig(String fullPath, String newValue, boolean autoGenerated)
|
||||||
|
throws IOException {
|
||||||
|
// 1) Load the file (settings.yml)
|
||||||
|
Path settingsPath = Paths.get(InstallationPathConfig.getSettingsPath());
|
||||||
|
if (!Files.exists(settingsPath)) {
|
||||||
|
log.warn("Settings file not found at {}, creating a new empty file...", settingsPath);
|
||||||
|
Files.createDirectories(settingsPath.getParent());
|
||||||
|
Files.createFile(settingsPath);
|
||||||
|
}
|
||||||
|
List<String> lines = Files.readAllLines(settingsPath);
|
||||||
|
|
||||||
|
// 2) Build a map of "nestedKeyPath -> lineIndex" by parsing indentation
|
||||||
|
// Also track each line's indentation so we can preserve it when rewriting.
|
||||||
|
Map<String, LineInfo> pathToLine = parseNestedYamlKeys(lines);
|
||||||
|
|
||||||
|
// 3) If the path is found, rewrite its line. Else, append at the bottom (no indentation).
|
||||||
|
boolean changed = false;
|
||||||
|
if (pathToLine.containsKey(fullPath)) {
|
||||||
|
// Rewrite existing line
|
||||||
|
LineInfo info = pathToLine.get(fullPath);
|
||||||
|
String oldLine = lines.get(info.lineIndex);
|
||||||
|
String newLine =
|
||||||
|
rewriteLine(oldLine, info.indentSpaces, fullPath, newValue, autoGenerated);
|
||||||
|
if (!newLine.equals(oldLine)) {
|
||||||
|
lines.set(info.lineIndex, newLine);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Append a new line at the bottom, with zero indentation
|
||||||
|
String appended = fullPath + ": " + newValue;
|
||||||
|
if (autoGenerated) {
|
||||||
|
appended += " # Automatically Generated Settings (Do Not Edit Directly)";
|
||||||
|
}
|
||||||
|
lines.add(appended);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4) If changed, write back to file
|
||||||
|
if (changed) {
|
||||||
|
Files.write(settingsPath, lines);
|
||||||
|
log.info(
|
||||||
|
"Updated '{}' to '{}' (autoGenerated={}) in {}",
|
||||||
|
fullPath,
|
||||||
|
newValue,
|
||||||
|
autoGenerated,
|
||||||
|
settingsPath);
|
||||||
|
} else {
|
||||||
|
log.info("No changes for '{}' (already set to '{}').", fullPath, newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A small record-like class that holds: - lineIndex - indentSpaces */
|
||||||
|
private static class LineInfo {
|
||||||
|
int lineIndex;
|
||||||
|
int indentSpaces;
|
||||||
|
|
||||||
|
public LineInfo(int lineIndex, int indentSpaces) {
|
||||||
|
this.lineIndex = lineIndex;
|
||||||
|
this.indentSpaces = indentSpaces;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the YAML lines to build a map: "full.nested.key" -> (lineIndex, indentSpaces). We do a
|
||||||
|
* naive indentation-based path stacking: - 2 spaces = 1 indent level - lines that start with
|
||||||
|
* fewer or equal indentation pop the stack - lines that look like "key:" or "key: value" cause
|
||||||
|
* a push
|
||||||
|
*/
|
||||||
|
private static Map<String, LineInfo> parseNestedYamlKeys(List<String> lines) {
|
||||||
|
Map<String, LineInfo> result = new HashMap<>();
|
||||||
|
|
||||||
|
// We'll maintain a stack of (keyName, indentLevel).
|
||||||
|
// Each line that looks like "myKey:" or "myKey: value" is a new "child" of the top of the
|
||||||
|
// stack if indent is deeper.
|
||||||
|
Deque<String> pathStack = new ArrayDeque<>();
|
||||||
|
Deque<Integer> indentStack = new ArrayDeque<>();
|
||||||
|
indentStack.push(-1); // sentinel
|
||||||
|
|
||||||
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
|
String line = lines.get(i);
|
||||||
|
String trimmed = line.trim();
|
||||||
|
|
||||||
|
// skip blank lines, comment lines, or list items
|
||||||
|
if (trimmed.isEmpty() || trimmed.startsWith("#") || trimmed.startsWith("-")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// check if there's a colon
|
||||||
|
int colonIdx = trimmed.indexOf(':');
|
||||||
|
if (colonIdx <= 0) { // must have at least one char before ':'
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// parse out key
|
||||||
|
String keyPart = trimmed.substring(0, colonIdx).trim();
|
||||||
|
if (keyPart.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// count leading spaces for indentation
|
||||||
|
int leadingSpaces = countLeadingSpaces(line);
|
||||||
|
int indentLevel = leadingSpaces / 2; // assume 2 spaces per level
|
||||||
|
|
||||||
|
// pop from stack until we get to a shallower indentation
|
||||||
|
while (indentStack.peek() != null && indentStack.peek() >= indentLevel) {
|
||||||
|
indentStack.pop();
|
||||||
|
pathStack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// push the new key
|
||||||
|
pathStack.push(keyPart);
|
||||||
|
indentStack.push(indentLevel);
|
||||||
|
|
||||||
|
// build the full path
|
||||||
|
String[] arr = pathStack.toArray(new String[0]);
|
||||||
|
List<String> reversed = Arrays.asList(arr);
|
||||||
|
Collections.reverse(reversed);
|
||||||
|
String fullPath = String.join(".", reversed);
|
||||||
|
|
||||||
|
// store line info
|
||||||
|
result.put(fullPath, new LineInfo(i, leadingSpaces));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rewrite a single line to set a new value, preserving indentation and (optionally) the
|
||||||
|
* existing or auto-generated inline comment.
|
||||||
|
*
|
||||||
|
* <p>For example, oldLine might be: " csrfDisabled: false # set to 'true' to disable CSRF
|
||||||
|
* protection" newValue = "true" autoGenerated = false
|
||||||
|
*
|
||||||
|
* <p>We'll produce something like: " csrfDisabled: true # set to 'true' to disable CSRF
|
||||||
|
* protection"
|
||||||
|
*/
|
||||||
|
private static String rewriteLine(
|
||||||
|
String oldLine, int indentSpaces, String path, String newValue, boolean autoGenerated) {
|
||||||
|
// We'll keep the exact leading indentation (indentSpaces).
|
||||||
|
// Then "key: newValue". We'll try to preserve any existing inline comment unless
|
||||||
|
// autoGenerated is true.
|
||||||
|
|
||||||
|
// 1) Extract leading spaces from the old line (just in case they differ from indentSpaces).
|
||||||
|
int actualLeadingSpaces = countLeadingSpaces(oldLine);
|
||||||
|
String leading = oldLine.substring(0, actualLeadingSpaces);
|
||||||
|
|
||||||
|
// 2) Remove leading spaces from the rest
|
||||||
|
String trimmed = oldLine.substring(actualLeadingSpaces);
|
||||||
|
|
||||||
|
// 3) Check for existing comment
|
||||||
|
int hashIndex = trimmed.indexOf('#');
|
||||||
|
String lineWithoutComment =
|
||||||
|
(hashIndex >= 0) ? trimmed.substring(0, hashIndex).trim() : trimmed.trim();
|
||||||
|
String oldComment = (hashIndex >= 0) ? trimmed.substring(hashIndex).trim() : "";
|
||||||
|
|
||||||
|
// 4) Rebuild "key: newValue"
|
||||||
|
// The "key" here is everything before ':' in lineWithoutComment
|
||||||
|
int colonIdx = lineWithoutComment.indexOf(':');
|
||||||
|
String existingKey =
|
||||||
|
(colonIdx >= 0)
|
||||||
|
? lineWithoutComment.substring(0, colonIdx).trim()
|
||||||
|
: path; // fallback if line is malformed
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(leading); // restore original leading spaces
|
||||||
|
|
||||||
|
// "key: newValue"
|
||||||
|
sb.append(existingKey).append(": ").append(newValue);
|
||||||
|
|
||||||
|
// 5) If autoGenerated, add/replace comment
|
||||||
|
if (autoGenerated) {
|
||||||
|
sb.append(" # Automatically Generated Settings (Do Not Edit Directly)");
|
||||||
|
} else {
|
||||||
|
// preserve the old comment if it exists
|
||||||
|
if (!oldComment.isEmpty()) {
|
||||||
|
sb.append(" ").append(oldComment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int countLeadingSpaces(String line) {
|
||||||
|
int count = 0;
|
||||||
|
for (char c : line.toCharArray()) {
|
||||||
|
if (c == ' ') count++;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String generateMachineFingerprint() {
|
public static String generateMachineFingerprint() {
|
||||||
@@ -415,9 +586,7 @@ public class GeneralUtils {
|
|||||||
for (byte b : hash) {
|
for (byte b : hash) {
|
||||||
fingerprint.append(String.format("%02x", b));
|
fingerprint.append(String.format("%02x", b));
|
||||||
}
|
}
|
||||||
|
|
||||||
return fingerprint.toString();
|
return fingerprint.toString();
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return "GenericID";
|
return "GenericID";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -218,6 +218,9 @@ public class ProcessExecutor {
|
|||||||
errorReaderThread.join();
|
errorReaderThread.join();
|
||||||
outputReaderThread.join();
|
outputReaderThread.join();
|
||||||
|
|
||||||
|
boolean isQpdf =
|
||||||
|
command != null && !command.isEmpty() && command.get(0).contains("qpdf");
|
||||||
|
|
||||||
if (outputLines.size() > 0) {
|
if (outputLines.size() > 0) {
|
||||||
String outputMessage = String.join("\n", outputLines);
|
String outputMessage = String.join("\n", outputLines);
|
||||||
messages += outputMessage;
|
messages += outputMessage;
|
||||||
@@ -233,6 +236,9 @@ public class ProcessExecutor {
|
|||||||
log.warn("Command error output:\n" + errorMessage);
|
log.warn("Command error output:\n" + errorMessage);
|
||||||
}
|
}
|
||||||
if (exitCode != 0) {
|
if (exitCode != 0) {
|
||||||
|
if (isQpdf && exitCode == 3) {
|
||||||
|
log.warn("qpdf succeeded with warnings: {}", messages);
|
||||||
|
} else {
|
||||||
throw new IOException(
|
throw new IOException(
|
||||||
"Command process failed with exit code "
|
"Command process failed with exit code "
|
||||||
+ exitCode
|
+ exitCode
|
||||||
@@ -240,14 +246,19 @@ public class ProcessExecutor {
|
|||||||
+ errorMessage);
|
+ errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (exitCode != 0) {
|
if (exitCode != 0) {
|
||||||
|
if (isQpdf && exitCode == 3) {
|
||||||
|
log.warn("qpdf succeeded with warnings: {}", messages);
|
||||||
|
} else {
|
||||||
throw new IOException(
|
throw new IOException(
|
||||||
"Command process failed with exit code "
|
"Command process failed with exit code "
|
||||||
+ exitCode
|
+ exitCode
|
||||||
+ "\nLogs: "
|
+ "\nLogs: "
|
||||||
+ messages);
|
+ messages);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
semaphore.release();
|
semaphore.release();
|
||||||
}
|
}
|
||||||
|
|||||||
67
src/main/java/stirling/software/SPDF/utils/UIScaling.java
Normal file
67
src/main/java/stirling/software/SPDF/utils/UIScaling.java
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
package stirling.software.SPDF.utils;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
public class UIScaling {
|
||||||
|
private static final double BASE_RESOLUTION_WIDTH = 1920.0;
|
||||||
|
private static final double BASE_RESOLUTION_HEIGHT = 1080.0;
|
||||||
|
|
||||||
|
public static double getWidthScaleFactor() {
|
||||||
|
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||||
|
return screenSize.getWidth() / BASE_RESOLUTION_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double getHeightScaleFactor() {
|
||||||
|
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||||
|
return screenSize.getHeight() / BASE_RESOLUTION_HEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int scaleWidth(int value) {
|
||||||
|
return (int) Math.round(value * getWidthScaleFactor());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int scaleHeight(int value) {
|
||||||
|
return (int) Math.round(value * getHeightScaleFactor());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dimension scale(Dimension dim) {
|
||||||
|
return new Dimension(scaleWidth(dim.width), scaleHeight(dim.height));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Insets scale(Insets insets) {
|
||||||
|
return new Insets(
|
||||||
|
scaleHeight(insets.top),
|
||||||
|
scaleWidth(insets.left),
|
||||||
|
scaleHeight(insets.bottom),
|
||||||
|
scaleWidth(insets.right));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Font scaleFont(Font font) {
|
||||||
|
// For fonts, we'll use the smaller scale factor to ensure readability
|
||||||
|
double scaleFactor = Math.min(getWidthScaleFactor(), getHeightScaleFactor());
|
||||||
|
return font.deriveFont((float) (font.getSize() * scaleFactor));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility method for aspect ratio aware icon scaling
|
||||||
|
public static Image scaleIcon(Image icon, int targetWidth, int targetHeight) {
|
||||||
|
if (icon == null) return null;
|
||||||
|
|
||||||
|
double widthScale = getWidthScaleFactor();
|
||||||
|
double heightScale = getHeightScaleFactor();
|
||||||
|
|
||||||
|
int scaledWidth = (int) Math.round(targetWidth * widthScale);
|
||||||
|
int scaledHeight = (int) Math.round(targetHeight * heightScale);
|
||||||
|
|
||||||
|
// Maintain aspect ratio for icons
|
||||||
|
double aspectRatio = (double) icon.getWidth(null) / icon.getHeight(null);
|
||||||
|
if (scaledWidth / scaledHeight > aspectRatio) {
|
||||||
|
scaledWidth = (int) (scaledHeight * aspectRatio);
|
||||||
|
} else {
|
||||||
|
scaledHeight = (int) (scaledWidth / aspectRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
return icon.getScaledInstance(scaledWidth, scaledHeight, Image.SCALE_SMOOTH);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,8 +30,10 @@ public class InvertFullColorStrategy extends ReplaceAndInvertColorStrategy {
|
|||||||
@Override
|
@Override
|
||||||
public InputStreamResource replace() throws IOException {
|
public InputStreamResource replace() throws IOException {
|
||||||
|
|
||||||
|
File file = null;
|
||||||
|
try {
|
||||||
// Create a temporary file, with the original filename from the multipart file
|
// Create a temporary file, with the original filename from the multipart file
|
||||||
File file = Files.createTempFile("temp", getFileInput().getOriginalFilename()).toFile();
|
file = Files.createTempFile("temp", getFileInput().getOriginalFilename()).toFile();
|
||||||
|
|
||||||
// Transfer the content of the multipart file to the file
|
// Transfer the content of the multipart file to the file
|
||||||
getFileInput().transferTo(file);
|
getFileInput().transferTo(file);
|
||||||
@@ -50,13 +52,18 @@ public class InvertFullColorStrategy extends ReplaceAndInvertColorStrategy {
|
|||||||
|
|
||||||
// Create a new PDPage from the inverted image
|
// Create a new PDPage from the inverted image
|
||||||
PDPage pdPage = document.getPage(page);
|
PDPage pdPage = document.getPage(page);
|
||||||
|
File tempImageFile = null;
|
||||||
|
try {
|
||||||
|
tempImageFile = convertToBufferedImageTpFile(image);
|
||||||
PDImageXObject pdImage =
|
PDImageXObject pdImage =
|
||||||
PDImageXObject.createFromFileByContent(
|
PDImageXObject.createFromFileByContent(tempImageFile, document);
|
||||||
convertToBufferedImageTpFile(image), document);
|
|
||||||
|
|
||||||
PDPageContentStream contentStream =
|
PDPageContentStream contentStream =
|
||||||
new PDPageContentStream(
|
new PDPageContentStream(
|
||||||
document, pdPage, PDPageContentStream.AppendMode.OVERWRITE, true);
|
document,
|
||||||
|
pdPage,
|
||||||
|
PDPageContentStream.AppendMode.OVERWRITE,
|
||||||
|
true);
|
||||||
contentStream.drawImage(
|
contentStream.drawImage(
|
||||||
pdImage,
|
pdImage,
|
||||||
0,
|
0,
|
||||||
@@ -64,6 +71,11 @@ public class InvertFullColorStrategy extends ReplaceAndInvertColorStrategy {
|
|||||||
pdPage.getMediaBox().getWidth(),
|
pdPage.getMediaBox().getWidth(),
|
||||||
pdPage.getMediaBox().getHeight());
|
pdPage.getMediaBox().getHeight());
|
||||||
contentStream.close();
|
contentStream.close();
|
||||||
|
} finally {
|
||||||
|
if (tempImageFile != null && tempImageFile.exists()) {
|
||||||
|
Files.delete(tempImageFile.toPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the modified PDF to a ByteArrayOutputStream
|
// Save the modified PDF to a ByteArrayOutputStream
|
||||||
@@ -76,6 +88,11 @@ public class InvertFullColorStrategy extends ReplaceAndInvertColorStrategy {
|
|||||||
new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
|
new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
|
||||||
InputStreamResource resource = new InputStreamResource(inputStream);
|
InputStreamResource resource = new InputStreamResource(inputStream);
|
||||||
return resource;
|
return resource;
|
||||||
|
} finally {
|
||||||
|
if (file != null && file.exists()) {
|
||||||
|
Files.delete(file.toPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method to invert image colors
|
// Method to invert image colors
|
||||||
@@ -98,7 +115,7 @@ public class InvertFullColorStrategy extends ReplaceAndInvertColorStrategy {
|
|||||||
|
|
||||||
// Helper method to convert BufferedImage to InputStream
|
// Helper method to convert BufferedImage to InputStream
|
||||||
private File convertToBufferedImageTpFile(BufferedImage image) throws IOException {
|
private File convertToBufferedImageTpFile(BufferedImage image) throws IOException {
|
||||||
File file = new File("image.png");
|
File file = File.createTempFile("image", ".png");
|
||||||
ImageIO.write(image, "png", file);
|
ImageIO.write(image, "png", file);
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=يمكنك تغيير إعدادات الإحصائيات ف
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=المفضلة
|
navbar.favorite=المفضلة
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=الوضع الداكن
|
navbar.darkmode=الوضع الداكن
|
||||||
navbar.language=اللغات
|
navbar.language=اللغات
|
||||||
navbar.settings=إعدادات
|
navbar.settings=إعدادات
|
||||||
@@ -261,10 +262,19 @@ home.desc=متجرك الشامل المستضاف محليًا لجميع اح
|
|||||||
home.searchBar=البحث عن الميزات...
|
home.searchBar=البحث عن الميزات...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=عرض PDF
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=عرض وتعليق وإضافة نص أو صور
|
home.viewPdf.desc=عرض وتعليق وإضافة نص أو صور
|
||||||
viewPdf.tags=عرض,قراءة,تعليق,نص,صورة
|
viewPdf.tags=عرض,قراءة,تعليق,نص,صورة
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=أداة متعددة PDF
|
home.multiTool.title=أداة متعددة PDF
|
||||||
home.multiTool.desc=دمج الصفحات وتدويرها وإعادة ترتيبها وإزالتها
|
home.multiTool.desc=دمج الصفحات وتدويرها وإعادة ترتيبها وإزالتها
|
||||||
multiTool.tags=أداة متعددة,عملية متعددة,واجهة مستخدم,النقر والسحب,واجهة أمامية,جانب العميل
|
multiTool.tags=أداة متعددة,عملية متعددة,واجهة مستخدم,النقر والسحب,واجهة أمامية,جانب العميل
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Show Attachments
|
|||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
||||||
redact.colourPicker=Colour Picker
|
redact.colourPicker=Colour Picker
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
redact.findCurrentOutlineItem=Find current outline item
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=إظهار جافا سكريبت
|
showJS.title=إظهار جافا سكريبت
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=ارفع ملف PDF الممسوح ضوئيًا الك
|
|||||||
autoSplitPDF.selectText.4=يتم اكتشاف صفحات الفاصل تلقائيًا وإزالتها، مما يضمن مستندًا نهائيًا نظيفًا.
|
autoSplitPDF.selectText.4=يتم اكتشاف صفحات الفاصل تلقائيًا وإزالتها، مما يضمن مستندًا نهائيًا نظيفًا.
|
||||||
autoSplitPDF.formPrompt=أرسل ملف PDF يحتوي على فواصل صفحات Stirling-PDF:
|
autoSplitPDF.formPrompt=أرسل ملف PDF يحتوي على فواصل صفحات Stirling-PDF:
|
||||||
autoSplitPDF.duplexMode=وضع الطباعة على الوجهين (المسح الضوئي للوجه الأمامي والخلفي)
|
autoSplitPDF.duplexMode=وضع الطباعة على الوجهين (المسح الضوئي للوجه الأمامي والخلفي)
|
||||||
autoSplitPDF.dividerDownload1=تنزيل 'فاصل التقسيم التلقائي (الحد الأدنى).pdf'
|
|
||||||
autoSplitPDF.dividerDownload2=تنزيل 'فاصل التقسيم التلقائي (مع التعليمات).pdf'
|
autoSplitPDF.dividerDownload2=تنزيل 'فاصل التقسيم التلقائي (مع التعليمات).pdf'
|
||||||
autoSplitPDF.submit=إرسال
|
autoSplitPDF.submit=إرسال
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=إزالة الأول
|
|||||||
pdfOrganiser.mode.8=إزالة الأخير
|
pdfOrganiser.mode.8=إزالة الأخير
|
||||||
pdfOrganiser.mode.9=إزالة
|
pdfOrganiser.mode.9=إزالة
|
||||||
pdfOrganiser.mode.10=دمج فردي-زوجي
|
pdfOrganiser.mode.10=دمج فردي-زوجي
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(مثال: 1,3,2 أو 4-8,2,10-12 أو 2n-1)
|
pdfOrganiser.placeholder=(مثال: 1,3,2 أو 4-8,2,10-12 أو 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=File decrypted successfully.
|
|||||||
multiTool-advert.message=هذه الميزة متوفرة في <a href="{0}">صفحة الأدوات المتعددة</a> لدينا. اطلع عليها للحصول على واجهة مستخدم محسّنة لكل صفحة وميزات إضافية!
|
multiTool-advert.message=هذه الميزة متوفرة في <a href="{0}">صفحة الأدوات المتعددة</a> لدينا. اطلع عليها للحصول على واجهة مستخدم محسّنة لكل صفحة وميزات إضافية!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=عرض PDF
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=عرض PDF
|
viewPdf.header=عرض PDF
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=تغيير
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF إلى PDF/A
|
pdfToPDFA.title=PDF إلى PDF/A
|
||||||
pdfToPDFA.header=PDF إلى PDF/A
|
pdfToPDFA.header=PDF إلى PDF/A
|
||||||
pdfToPDFA.credit=تستخدم هذه الخدمة qpdf لتحويل PDF/A.
|
pdfToPDFA.credit=تستخدم هذه الخدمة libreoffice لتحويل PDF/A.
|
||||||
pdfToPDFA.submit=تحويل
|
pdfToPDFA.submit=تحويل
|
||||||
pdfToPDFA.tip=لا يعمل حاليًا لمدخلات متعددة في وقت واحد
|
pdfToPDFA.tip=لا يعمل حاليًا لمدخلات متعددة في وقت واحد
|
||||||
pdfToPDFA.outputFormat=تنسيق الإخراج
|
pdfToPDFA.outputFormat=تنسيق الإخراج
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=Analitikanın parametrlərini config/settings.yml faylından
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Sevimlilər
|
navbar.favorite=Sevimlilər
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=Qaranlıq Tema
|
navbar.darkmode=Qaranlıq Tema
|
||||||
navbar.language=Dillər
|
navbar.language=Dillər
|
||||||
navbar.settings=Parametrlər
|
navbar.settings=Parametrlər
|
||||||
@@ -261,10 +262,19 @@ home.desc=Bütün PDF ehtiyaclarınız üçün lokal-host edilən biraddımlıq
|
|||||||
home.searchBar=Xüsusiyyətləri axtar...
|
home.searchBar=Xüsusiyyətləri axtar...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=PDF-ə bax
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=Bax, sitat götür, mətn və ya şəkil əlavə et
|
home.viewPdf.desc=Bax, sitat götür, mətn və ya şəkil əlavə et
|
||||||
viewPdf.tags=bax,oxu,sitat götür,mətn,şəkil
|
viewPdf.tags=bax,oxu,sitat götür,mətn,şəkil
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Multi-alət
|
home.multiTool.title=PDF Multi-alət
|
||||||
home.multiTool.desc=Səhifələri Birləşdir, Çevir, Yenidən Sırala, Böl və Sil
|
home.multiTool.desc=Səhifələri Birləşdir, Çevir, Yenidən Sırala, Böl və Sil
|
||||||
multiTool.tags=Multi-alət,Çoxlu əməliyyat,UI,tut-sürüşdür,front end,istifadəçi-tərəf,interaktiv,qarşılıqlı,yerini dəyiş,sil,köçür,böl
|
multiTool.tags=Multi-alət,Çoxlu əməliyyat,UI,tut-sürüşdür,front end,istifadəçi-tərəf,interaktiv,qarşılıqlı,yerini dəyiş,sil,köçür,böl
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Show Attachments
|
|||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
||||||
redact.colourPicker=Colour Picker
|
redact.colourPicker=Colour Picker
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
redact.findCurrentOutlineItem=Find current outline item
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Javascripti Göstər
|
showJS.title=Javascripti Göstər
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=Tək böyük skan edilmiş PDF faylını yükləyin v
|
|||||||
autoSplitPDF.selectText.4=Ayırıcı səhifələr avtomatik aşkarlanır və silinir, səliqəli yekun sənədə zəmanət verir.
|
autoSplitPDF.selectText.4=Ayırıcı səhifələr avtomatik aşkarlanır və silinir, səliqəli yekun sənədə zəmanət verir.
|
||||||
autoSplitPDF.formPrompt=Stirling-PDF ə Səhifə bölücüləri olan PDF-i təqdim edin:
|
autoSplitPDF.formPrompt=Stirling-PDF ə Səhifə bölücüləri olan PDF-i təqdim edin:
|
||||||
autoSplitPDF.duplexMode=Dupleks rejimi (Ön və arxa skanlama)
|
autoSplitPDF.duplexMode=Dupleks rejimi (Ön və arxa skanlama)
|
||||||
autoSplitPDF.dividerDownload1='Auto Splitter Divider (minimal).pdf'-ı yükləyin
|
|
||||||
autoSplitPDF.dividerDownload2='Auto Splitter Divider (with instructions).pdf'-ı yükləyin
|
autoSplitPDF.dividerDownload2='Auto Splitter Divider (with instructions).pdf'-ı yükləyin
|
||||||
autoSplitPDF.submit=Təsdiq edin
|
autoSplitPDF.submit=Təsdiq edin
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=Birincini Sil
|
|||||||
pdfOrganiser.mode.8=Sonuncunu Sil
|
pdfOrganiser.mode.8=Sonuncunu Sil
|
||||||
pdfOrganiser.mode.9=Birinci və Sonuncunu Sil
|
pdfOrganiser.mode.9=Birinci və Sonuncunu Sil
|
||||||
pdfOrganiser.mode.10=Tək-Cüt Birləşdirmə
|
pdfOrganiser.mode.10=Tək-Cüt Birləşdirmə
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(məs., 1,3,2 və ya 4-8,2,10-12 və ya 2n-1)
|
pdfOrganiser.placeholder=(məs., 1,3,2 və ya 4-8,2,10-12 və ya 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=File decrypted successfully.
|
|||||||
multiTool-advert.message=Bu xüsusiyyət bizim <a href="{0}">multi-alət səhifə</a>mizdə də mövcuddur. Əlavə xüsusiyyətlər və səhifə-səhifə interfeys üçün sınaqdan keçirin!
|
multiTool-advert.message=Bu xüsusiyyət bizim <a href="{0}">multi-alət səhifə</a>mizdə də mövcuddur. Əlavə xüsusiyyətlər və səhifə-səhifə interfeys üçün sınaqdan keçirin!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=PDF-ə baxın
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=PDF-ə baxın
|
viewPdf.header=PDF-ə baxın
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=Dəyiş
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF-i PDF/A-ya
|
pdfToPDFA.title=PDF-i PDF/A-ya
|
||||||
pdfToPDFA.header=PDF-i PDF/A-ya
|
pdfToPDFA.header=PDF-i PDF/A-ya
|
||||||
pdfToPDFA.credit=Bu Servis PDF/A Çevirmək Üçün ghostscript İşlədir
|
pdfToPDFA.credit=Bu Servis PDF/A Çevirmək Üçün libreoffice İşlədir
|
||||||
pdfToPDFA.submit=Çevir
|
pdfToPDFA.submit=Çevir
|
||||||
pdfToPDFA.tip=Hazırda Birdən Çox Giriş Üçün İşləmir
|
pdfToPDFA.tip=Hazırda Birdən Çox Giriş Üçün İşləmir
|
||||||
pdfToPDFA.outputFormat=Çıxış Formatı
|
pdfToPDFA.outputFormat=Çıxış Formatı
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=Можете да промените настройките
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Любими
|
navbar.favorite=Любими
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=Тъмна тема
|
navbar.darkmode=Тъмна тема
|
||||||
navbar.language=Езици
|
navbar.language=Езици
|
||||||
navbar.settings=Настройки
|
navbar.settings=Настройки
|
||||||
@@ -261,10 +262,19 @@ home.desc=Вашето локално хоствано обслужване на
|
|||||||
home.searchBar=Търсене на функции...
|
home.searchBar=Търсене на функции...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=Преглед на PDF
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=Преглеждайте, коментирайте, добавяйте текст или изображения
|
home.viewPdf.desc=Преглеждайте, коментирайте, добавяйте текст или изображения
|
||||||
viewPdf.tags=преглед,четене,анотиране,текст,изображение
|
viewPdf.tags=преглед,четене,анотиране,текст,изображение
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Мулти инструмент
|
home.multiTool.title=PDF Мулти инструмент
|
||||||
home.multiTool.desc=Обединяване, завъртане, пренареждане и премахване на страници
|
home.multiTool.desc=Обединяване, завъртане, пренареждане и премахване на страници
|
||||||
multiTool.tags=Мултиинструмент,Мулти операции,UI,плъзгане с щракване,потребителска част,страна на клиента,интерактивен,неразрешим,преместване
|
multiTool.tags=Мултиинструмент,Мулти операции,UI,плъзгане с щракване,потребителска част,страна на клиента,интерактивен,неразрешим,преместване
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Show Attachments
|
|||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
||||||
redact.colourPicker=Colour Picker
|
redact.colourPicker=Colour Picker
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
redact.findCurrentOutlineItem=Find current outline item
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Покажи Javascript
|
showJS.title=Покажи Javascript
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=Качете единствения голям ска
|
|||||||
autoSplitPDF.selectText.4=Разделителните страници се откриват и премахват автоматично, което гарантира чист краен документ.
|
autoSplitPDF.selectText.4=Разделителните страници се откриват и премахват автоматично, което гарантира чист краен документ.
|
||||||
autoSplitPDF.formPrompt=Изпратете PDF, съдържащ разделители на страници на Stirling-PDF:
|
autoSplitPDF.formPrompt=Изпратете PDF, съдържащ разделители на страници на Stirling-PDF:
|
||||||
autoSplitPDF.duplexMode=Дуплексен режим (сканиране отпред и отзад)
|
autoSplitPDF.duplexMode=Дуплексен режим (сканиране отпред и отзад)
|
||||||
autoSplitPDF.dividerDownload1=Изтеглете 'Автоматичен сплитер разделител (минимален).pdf'
|
|
||||||
autoSplitPDF.dividerDownload2=Изтеглете 'Автоматичен сплитер разделител (с инструкции).pdf'
|
autoSplitPDF.dividerDownload2=Изтеглете 'Автоматичен сплитер разделител (с инструкции).pdf'
|
||||||
autoSplitPDF.submit=Подайте
|
autoSplitPDF.submit=Подайте
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=Премахни първо
|
|||||||
pdfOrganiser.mode.8=Премахване на последния
|
pdfOrganiser.mode.8=Премахване на последния
|
||||||
pdfOrganiser.mode.9=Премахване на първия и последния
|
pdfOrganiser.mode.9=Премахване на първия и последния
|
||||||
pdfOrganiser.mode.10=Обединяване на четно и нечетно
|
pdfOrganiser.mode.10=Обединяване на четно и нечетно
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(напр. 1,3,2 или 4-8,2,10-12 или 2n-1)
|
pdfOrganiser.placeholder=(напр. 1,3,2 или 4-8,2,10-12 или 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=File decrypted successfully.
|
|||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=Преглед на PDF
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=Преглед на PDF
|
viewPdf.header=Преглед на PDF
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=Промени
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF към PDF/A
|
pdfToPDFA.title=PDF към PDF/A
|
||||||
pdfToPDFA.header=PDF към PDF/A
|
pdfToPDFA.header=PDF към PDF/A
|
||||||
pdfToPDFA.credit=Тази услуга използва qpdf за PDF/A преобразуване.
|
pdfToPDFA.credit=Тази услуга използва libreoffice за PDF/A преобразуване.
|
||||||
pdfToPDFA.submit=Преобразуване
|
pdfToPDFA.submit=Преобразуване
|
||||||
pdfToPDFA.tip=В момента не работи за няколко входа наведнъж
|
pdfToPDFA.tip=В момента не работи за няколко входа наведнъж
|
||||||
pdfToPDFA.outputFormat=Изходен формат
|
pdfToPDFA.outputFormat=Изходен формат
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=Pots canviar la configuració de les analítiques al fitxer c
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Favorits
|
navbar.favorite=Favorits
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=Mode Fosc
|
navbar.darkmode=Mode Fosc
|
||||||
navbar.language=Idiomes
|
navbar.language=Idiomes
|
||||||
navbar.settings=Opcions
|
navbar.settings=Opcions
|
||||||
@@ -261,10 +262,19 @@ home.desc=L'eina allotjada localment per a necessitats de PDF.
|
|||||||
home.searchBar=Cerca funcions...
|
home.searchBar=Cerca funcions...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=Visualitza PDF
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=Visualitza, anota, afegeix text o imatges
|
home.viewPdf.desc=Visualitza, anota, afegeix text o imatges
|
||||||
viewPdf.tags=view,read,annotate,text,image
|
viewPdf.tags=view,read,annotate,text,image
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Eina Multifunció de PDF
|
home.multiTool.title=Eina Multifunció de PDF
|
||||||
home.multiTool.desc=Fusiona, Rota, Reorganitza i Esborra pàgines
|
home.multiTool.desc=Fusiona, Rota, Reorganitza i Esborra pàgines
|
||||||
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
|
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Show Attachments
|
|||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
||||||
redact.colourPicker=Colour Picker
|
redact.colourPicker=Colour Picker
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
redact.findCurrentOutlineItem=Find current outline item
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Mostra Javascript
|
showJS.title=Mostra Javascript
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=Puja el fitxer PDF escanejat gran i deixa que Stirling
|
|||||||
autoSplitPDF.selectText.4=Les pàgines divisòries es detecten i eliminen automàticament, garantint un document final ordenat.
|
autoSplitPDF.selectText.4=Les pàgines divisòries es detecten i eliminen automàticament, garantint un document final ordenat.
|
||||||
autoSplitPDF.formPrompt=Envia un PDF que contingui les pàgines divisòries de Stirling-PDF:
|
autoSplitPDF.formPrompt=Envia un PDF que contingui les pàgines divisòries de Stirling-PDF:
|
||||||
autoSplitPDF.duplexMode=Mode Dúplex (Escaneig de davant i darrere)
|
autoSplitPDF.duplexMode=Mode Dúplex (Escaneig de davant i darrere)
|
||||||
autoSplitPDF.dividerDownload1=Descarrega 'Divisor Automàtic (mínim).pdf'
|
|
||||||
autoSplitPDF.dividerDownload2=Descarrega 'Divisor Automàtic (amb instruccions).pdf'
|
autoSplitPDF.dividerDownload2=Descarrega 'Divisor Automàtic (amb instruccions).pdf'
|
||||||
autoSplitPDF.submit=Envia
|
autoSplitPDF.submit=Envia
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=Eliminar Primer
|
|||||||
pdfOrganiser.mode.8=Eliminar Últim
|
pdfOrganiser.mode.8=Eliminar Últim
|
||||||
pdfOrganiser.mode.9=Eliminar Primer i Últim
|
pdfOrganiser.mode.9=Eliminar Primer i Últim
|
||||||
pdfOrganiser.mode.10=Fusionar Parells-Senars
|
pdfOrganiser.mode.10=Fusionar Parells-Senars
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(p. ex. 1,3,2 o 4-8,2,10-12 o 2n-1)
|
pdfOrganiser.placeholder=(p. ex. 1,3,2 o 4-8,2,10-12 o 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=File decrypted successfully.
|
|||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=Visualitza PDF
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=Visualitza PDF
|
viewPdf.header=Visualitza PDF
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=Canvia
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF a PDF/A
|
pdfToPDFA.title=PDF a PDF/A
|
||||||
pdfToPDFA.header=PDF a PDF/A
|
pdfToPDFA.header=PDF a PDF/A
|
||||||
pdfToPDFA.credit=Utilitza qpdf per a la conversió a PDF/A
|
pdfToPDFA.credit=Utilitza libreoffice per a la conversió a PDF/A
|
||||||
pdfToPDFA.submit=Converteix
|
pdfToPDFA.submit=Converteix
|
||||||
pdfToPDFA.tip=Actualment no funciona per a múltiples entrades al mateix temps
|
pdfToPDFA.tip=Actualment no funciona per a múltiples entrades al mateix temps
|
||||||
pdfToPDFA.outputFormat=Format de sortida
|
pdfToPDFA.outputFormat=Format de sortida
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=Nastavení analytiky můžete změnit v souboru config/settin
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Oblíbené
|
navbar.favorite=Oblíbené
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=Tmavý režim
|
navbar.darkmode=Tmavý režim
|
||||||
navbar.language=Jazyky
|
navbar.language=Jazyky
|
||||||
navbar.settings=Nastavení
|
navbar.settings=Nastavení
|
||||||
@@ -261,10 +262,19 @@ home.desc=Vaše lokálně hostované řešení pro všechny vaše potřeby PDF.
|
|||||||
home.searchBar=Hledat funkce...
|
home.searchBar=Hledat funkce...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=Zobrazit PDF
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=Zobrazit, anotovat, přidat text nebo obrázky
|
home.viewPdf.desc=Zobrazit, anotovat, přidat text nebo obrázky
|
||||||
viewPdf.tags=zobrazit,číst,anotovat,text,obrázek
|
viewPdf.tags=zobrazit,číst,anotovat,text,obrázek
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Multi nástroj
|
home.multiTool.title=PDF Multi nástroj
|
||||||
home.multiTool.desc=Sloučit, otočit, přeuspořádat, rozdělit a odstranit stránky
|
home.multiTool.desc=Sloučit, otočit, přeuspořádat, rozdělit a odstranit stránky
|
||||||
multiTool.tags=Multi nástroj,Více operací,UI,kliknutí a přetažení,přední strana,klientská strana,interaktivní,pohyb,smazat,přesunout,rozdělit
|
multiTool.tags=Multi nástroj,Více operací,UI,kliknutí a přetažení,přední strana,klientská strana,interaktivní,pohyb,smazat,přesunout,rozdělit
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Zobrazit přílohy
|
|||||||
redact.showLayers=Zobrazit vrstvy (dvojklik pro obnovení všech vrstev do výchozího stavu)
|
redact.showLayers=Zobrazit vrstvy (dvojklik pro obnovení všech vrstev do výchozího stavu)
|
||||||
redact.colourPicker=Výběr barvy
|
redact.colourPicker=Výběr barvy
|
||||||
redact.findCurrentOutlineItem=Najít aktuální položku osnovy
|
redact.findCurrentOutlineItem=Najít aktuální položku osnovy
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Zobrazit Javascript
|
showJS.title=Zobrazit Javascript
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=Nahrajte jediný velký naskenovaný PDF soubor a nech
|
|||||||
autoSplitPDF.selectText.4=Oddělovací stránky jsou automaticky detekovány a odstraněny, což zaručuje čistý finální dokument.
|
autoSplitPDF.selectText.4=Oddělovací stránky jsou automaticky detekovány a odstraněny, což zaručuje čistý finální dokument.
|
||||||
autoSplitPDF.formPrompt=Odeslat PDF obsahující Stirling-PDF oddělovače stránek:
|
autoSplitPDF.formPrompt=Odeslat PDF obsahující Stirling-PDF oddělovače stránek:
|
||||||
autoSplitPDF.duplexMode=Duplexní režim (skenování přední a zadní strany)
|
autoSplitPDF.duplexMode=Duplexní režim (skenování přední a zadní strany)
|
||||||
autoSplitPDF.dividerDownload1=Stáhnout 'Automatický oddělovač (minimální).pdf'
|
|
||||||
autoSplitPDF.dividerDownload2=Stáhnout 'Automatický oddělovač (s instrukcemi).pdf'
|
autoSplitPDF.dividerDownload2=Stáhnout 'Automatický oddělovač (s instrukcemi).pdf'
|
||||||
autoSplitPDF.submit=Odeslat
|
autoSplitPDF.submit=Odeslat
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=Odstranit první
|
|||||||
pdfOrganiser.mode.8=Odstranit poslední
|
pdfOrganiser.mode.8=Odstranit poslední
|
||||||
pdfOrganiser.mode.9=Odstranit první a poslední
|
pdfOrganiser.mode.9=Odstranit první a poslední
|
||||||
pdfOrganiser.mode.10=Sloučení sudé-liché
|
pdfOrganiser.mode.10=Sloučení sudé-liché
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(např. 1,3,2 nebo 4-8,2,10-12 nebo 2n-1)
|
pdfOrganiser.placeholder=(např. 1,3,2 nebo 4-8,2,10-12 nebo 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=Soubor byl úspěšně dešifrován.
|
|||||||
multiTool-advert.message=Tato funkce je také k dispozici na naší <a href="{0}">stránce multi-nástroje</a>. Podívejte se na ni pro vylepšené rozhraní pro práci se stránkami a další funkce!
|
multiTool-advert.message=Tato funkce je také k dispozici na naší <a href="{0}">stránce multi-nástroje</a>. Podívejte se na ni pro vylepšené rozhraní pro práci se stránkami a další funkce!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=Zobrazit PDF
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=Zobrazit PDF
|
viewPdf.header=Zobrazit PDF
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=Změnit
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF na PDF/A
|
pdfToPDFA.title=PDF na PDF/A
|
||||||
pdfToPDFA.header=PDF na PDF/A
|
pdfToPDFA.header=PDF na PDF/A
|
||||||
pdfToPDFA.credit=Tato služba používá qpdf pro konverzi do PDF/A
|
pdfToPDFA.credit=Tato služba používá libreoffice pro konverzi do PDF/A
|
||||||
pdfToPDFA.submit=Převést
|
pdfToPDFA.submit=Převést
|
||||||
pdfToPDFA.tip=Momentálně nefunguje pro více vstupů najednou
|
pdfToPDFA.tip=Momentálně nefunguje pro více vstupů najednou
|
||||||
pdfToPDFA.outputFormat=Výstupní formát
|
pdfToPDFA.outputFormat=Výstupní formát
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=Du kan ændre analytics-indstillingerne i config/settings.yml
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Favoritter
|
navbar.favorite=Favoritter
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=Mørk Tilstand
|
navbar.darkmode=Mørk Tilstand
|
||||||
navbar.language=Sprog
|
navbar.language=Sprog
|
||||||
navbar.settings=Indstillinger
|
navbar.settings=Indstillinger
|
||||||
@@ -261,10 +262,19 @@ home.desc=Dit lokalt hostede one-stop-shop for alle dine PDF-behov.
|
|||||||
home.searchBar=Søg efter funktioner...
|
home.searchBar=Søg efter funktioner...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=Se PDF
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=Se, annotér, tilføj tekst eller billeder
|
home.viewPdf.desc=Se, annotér, tilføj tekst eller billeder
|
||||||
viewPdf.tags=se,læs,annotér,tekst,billede
|
viewPdf.tags=se,læs,annotér,tekst,billede
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Multi Værktøj
|
home.multiTool.title=PDF Multi Værktøj
|
||||||
home.multiTool.desc=Flet, Rotér, Omarrangér og Fjern sider
|
home.multiTool.desc=Flet, Rotér, Omarrangér og Fjern sider
|
||||||
multiTool.tags=Multi Værktøj,Multi operation,UI,klik træk,front end,klient side,interaktiv,interagerbar,flyt
|
multiTool.tags=Multi Værktøj,Multi operation,UI,klik træk,front end,klient side,interaktiv,interagerbar,flyt
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Show Attachments
|
|||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
||||||
redact.colourPicker=Colour Picker
|
redact.colourPicker=Colour Picker
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
redact.findCurrentOutlineItem=Find current outline item
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Vis Javascript
|
showJS.title=Vis Javascript
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=Upload den enkelte store scannede PDF-fil og lad Stirl
|
|||||||
autoSplitPDF.selectText.4=Skillesider detekteres automatisk og fjernes, hvilket garanterer et pænt endeligt dokument.
|
autoSplitPDF.selectText.4=Skillesider detekteres automatisk og fjernes, hvilket garanterer et pænt endeligt dokument.
|
||||||
autoSplitPDF.formPrompt=Indsend PDF indeholdende Stirling-PDF Sideopdelere:
|
autoSplitPDF.formPrompt=Indsend PDF indeholdende Stirling-PDF Sideopdelere:
|
||||||
autoSplitPDF.duplexMode=Duplex-tilstand (For- og bagside scanning)
|
autoSplitPDF.duplexMode=Duplex-tilstand (For- og bagside scanning)
|
||||||
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
|
|
||||||
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (med instruktioner).pdf'
|
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (med instruktioner).pdf'
|
||||||
autoSplitPDF.submit=Indsend
|
autoSplitPDF.submit=Indsend
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=Fjern Første
|
|||||||
pdfOrganiser.mode.8=Fjern Sidste
|
pdfOrganiser.mode.8=Fjern Sidste
|
||||||
pdfOrganiser.mode.9=Fjern Første og Sidste
|
pdfOrganiser.mode.9=Fjern Første og Sidste
|
||||||
pdfOrganiser.mode.10=Ulige-Lige Sammenføjning
|
pdfOrganiser.mode.10=Ulige-Lige Sammenføjning
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(f.eks. 1,3,2 eller 4-8,2,10-12 eller 2n-1)
|
pdfOrganiser.placeholder=(f.eks. 1,3,2 eller 4-8,2,10-12 eller 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=File decrypted successfully.
|
|||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=Se PDF
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=Se PDF
|
viewPdf.header=Se PDF
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=Ændre
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF Til PDF/A
|
pdfToPDFA.title=PDF Til PDF/A
|
||||||
pdfToPDFA.header=PDF Til PDF/A
|
pdfToPDFA.header=PDF Til PDF/A
|
||||||
pdfToPDFA.credit=Denne tjeneste bruger qpdf til PDF/A-konvertering
|
pdfToPDFA.credit=Denne tjeneste bruger libreoffice til PDF/A-konvertering
|
||||||
pdfToPDFA.submit=Konvertér
|
pdfToPDFA.submit=Konvertér
|
||||||
pdfToPDFA.tip=Fungerer i øjeblikket ikke for flere input på én gang
|
pdfToPDFA.tip=Fungerer i øjeblikket ikke for flere input på én gang
|
||||||
pdfToPDFA.outputFormat=Outputformat
|
pdfToPDFA.outputFormat=Outputformat
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=Sie können die Einstellungen für die Analytics in der confi
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Favoriten
|
navbar.favorite=Favoriten
|
||||||
|
navbar.recent=Neu und kürzlich aktualisiert
|
||||||
navbar.darkmode=Dunkler Modus
|
navbar.darkmode=Dunkler Modus
|
||||||
navbar.language=Sprachen
|
navbar.language=Sprachen
|
||||||
navbar.settings=Einstellungen
|
navbar.settings=Einstellungen
|
||||||
@@ -261,10 +262,19 @@ home.desc=Ihr lokal gehosteter One-Stop-Shop für alle Ihre PDF-Anforderungen.
|
|||||||
home.searchBar=Suche nach Funktionen...
|
home.searchBar=Suche nach Funktionen...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=PDF anzeigen
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=Anzeigen, Kommentieren, Text oder Bilder hinzufügen
|
home.viewPdf.desc=Anzeigen, Kommentieren, Text oder Bilder hinzufügen
|
||||||
viewPdf.tags=anzeigen,lesen,kommentieren,text,bild
|
viewPdf.tags=anzeigen,lesen,kommentieren,text,bild
|
||||||
|
|
||||||
|
home.setFavorites=Favoriten festlegen
|
||||||
|
home.hideFavorites=Favoriten ausblenden
|
||||||
|
home.showFavorites=Favoriten anzeigen
|
||||||
|
home.legacyHomepage=Alte Homepage
|
||||||
|
home.newHomePage=Probieren Sie unsere neue Homepage aus!
|
||||||
|
home.alphabetical=Alphabetisch
|
||||||
|
home.globalPopularity=Beliebtheit
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF-Multitool
|
home.multiTool.title=PDF-Multitool
|
||||||
home.multiTool.desc=Seiten zusammenführen, drehen, neu anordnen und entfernen
|
home.multiTool.desc=Seiten zusammenführen, drehen, neu anordnen und entfernen
|
||||||
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
|
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Zeige Anhänge
|
|||||||
redact.showLayers=Ebenen anzeigen (Doppelklick, um alle Ebenen auf den Standardzustand zurückzusetzen)
|
redact.showLayers=Ebenen anzeigen (Doppelklick, um alle Ebenen auf den Standardzustand zurückzusetzen)
|
||||||
redact.colourPicker=Farbauswahl
|
redact.colourPicker=Farbauswahl
|
||||||
redact.findCurrentOutlineItem=Aktuell gewähltes Element finden
|
redact.findCurrentOutlineItem=Aktuell gewähltes Element finden
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Javascript anzeigen
|
showJS.title=Javascript anzeigen
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=Laden Sie die einzelne große gescannte PDF-Datei hoch
|
|||||||
autoSplitPDF.selectText.4=Trennseiten werden automatisch erkannt und entfernt, so dass ein sauberes Enddokument garantiert ist.
|
autoSplitPDF.selectText.4=Trennseiten werden automatisch erkannt und entfernt, so dass ein sauberes Enddokument garantiert ist.
|
||||||
autoSplitPDF.formPrompt=PDF mit Stirling-PDF Seitentrennern hochladen:
|
autoSplitPDF.formPrompt=PDF mit Stirling-PDF Seitentrennern hochladen:
|
||||||
autoSplitPDF.duplexMode=Duplex-Modus (Scannen von Vorder- und Rückseite)
|
autoSplitPDF.duplexMode=Duplex-Modus (Scannen von Vorder- und Rückseite)
|
||||||
autoSplitPDF.dividerDownload1=Herunterladen 'Auto Splitter Divider (minimal).pdf'
|
|
||||||
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (mit Anleitung).pdf'
|
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (mit Anleitung).pdf'
|
||||||
autoSplitPDF.submit=Aufteilen
|
autoSplitPDF.submit=Aufteilen
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=Erste entfernen
|
|||||||
pdfOrganiser.mode.8=Letzte entfernen
|
pdfOrganiser.mode.8=Letzte entfernen
|
||||||
pdfOrganiser.mode.9=Erste und letzte entfernen
|
pdfOrganiser.mode.9=Erste und letzte entfernen
|
||||||
pdfOrganiser.mode.10=Ungerade-Gerade-Zusammenführung
|
pdfOrganiser.mode.10=Ungerade-Gerade-Zusammenführung
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(z.B. 1,3,2 oder 4-8,2,10-12 oder 2n-1)
|
pdfOrganiser.placeholder=(z.B. 1,3,2 oder 4-8,2,10-12 oder 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=Datei erfolgreich entschlüsselt.
|
|||||||
multiTool-advert.message=Diese Funktion ist auch auf unserer <a href="{0}">PDF-Multitool-Seite</a> verfügbar. Probieren Sie sie aus, denn sie bietet eine verbesserte Benutzeroberfläche und zusätzliche Funktionen!
|
multiTool-advert.message=Diese Funktion ist auch auf unserer <a href="{0}">PDF-Multitool-Seite</a> verfügbar. Probieren Sie sie aus, denn sie bietet eine verbesserte Benutzeroberfläche und zusätzliche Funktionen!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=PDF anzeigen
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=PDF anzeigen
|
viewPdf.header=PDF anzeigen
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=Ändern
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF zu PDF/A
|
pdfToPDFA.title=PDF zu PDF/A
|
||||||
pdfToPDFA.header=PDF zu PDF/A
|
pdfToPDFA.header=PDF zu PDF/A
|
||||||
pdfToPDFA.credit=Dieser Dienst verwendet qpdf für die PDF/A-Konvertierung
|
pdfToPDFA.credit=Dieser Dienst verwendet libreoffice für die PDF/A-Konvertierung
|
||||||
pdfToPDFA.submit=Konvertieren
|
pdfToPDFA.submit=Konvertieren
|
||||||
pdfToPDFA.tip=Dieser Dienst kann nur einzelne Eingangsdateien verarbeiten.
|
pdfToPDFA.tip=Dieser Dienst kann nur einzelne Eingangsdateien verarbeiten.
|
||||||
pdfToPDFA.outputFormat=Ausgabeformat
|
pdfToPDFA.outputFormat=Ausgabeformat
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=Μπορείτε να αλλάξετε τις ρυθμίσε
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Αγαπημένα
|
navbar.favorite=Αγαπημένα
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=Σκοτεινή λειτουργία
|
navbar.darkmode=Σκοτεινή λειτουργία
|
||||||
navbar.language=Γλώσσες
|
navbar.language=Γλώσσες
|
||||||
navbar.settings=Ρυθμίσεις
|
navbar.settings=Ρυθμίσεις
|
||||||
@@ -261,10 +262,19 @@ home.desc=Ο τοπικά φιλοξενούμενος προορισμός σα
|
|||||||
home.searchBar=Αναζήτηση λειτουργιών...
|
home.searchBar=Αναζήτηση λειτουργιών...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=Προβολή PDF
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=Προβολή, σχολιασμός, προσθήκη κειμένου ή εικόνων
|
home.viewPdf.desc=Προβολή, σχολιασμός, προσθήκη κειμένου ή εικόνων
|
||||||
viewPdf.tags=προβολή,ανάγνωση,σχολιασμός,κείμενο,εικόνα
|
viewPdf.tags=προβολή,ανάγνωση,σχολιασμός,κείμενο,εικόνα
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Πολυεργαλείο PDF
|
home.multiTool.title=Πολυεργαλείο PDF
|
||||||
home.multiTool.desc=Συγχώνευση, Περιστροφή, Αναδιάταξη, Διαχωρισμός και Αφαίρεση σελίδων
|
home.multiTool.desc=Συγχώνευση, Περιστροφή, Αναδιάταξη, Διαχωρισμός και Αφαίρεση σελίδων
|
||||||
multiTool.tags=Πολυεργαλείο,Πολλαπλές λειτουργίες,UI,κλικ και σύρσιμο,frontend,πλευρά πελάτη,διαδραστικό,διαχειρίσιμο,μετακίνηση,διαγραφή,μετανάστευση,διαίρεση
|
multiTool.tags=Πολυεργαλείο,Πολλαπλές λειτουργίες,UI,κλικ και σύρσιμο,frontend,πλευρά πελάτη,διαδραστικό,διαχειρίσιμο,μετακίνηση,διαγραφή,μετανάστευση,διαίρεση
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Εμφάνιση συνημμένων
|
|||||||
redact.showLayers=Εμφάνιση επιπέδων (διπλό κλικ για επαναφορά όλων των επιπέδων στην προεπιλεγμένη κατάσταση)
|
redact.showLayers=Εμφάνιση επιπέδων (διπλό κλικ για επαναφορά όλων των επιπέδων στην προεπιλεγμένη κατάσταση)
|
||||||
redact.colourPicker=Επιλογέας χρώματος
|
redact.colourPicker=Επιλογέας χρώματος
|
||||||
redact.findCurrentOutlineItem=Εύρεση τρέχοντος στοιχείου περιγράμματος
|
redact.findCurrentOutlineItem=Εύρεση τρέχοντος στοιχείου περιγράμματος
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Εμφάνιση Javascript
|
showJS.title=Εμφάνιση Javascript
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=Μεταφορτώστε το ενιαίο μεγάλ
|
|||||||
autoSplitPDF.selectText.4=Οι σελίδες διαχωρισμού ανιχνεύονται και αφαιρούνται αυτόματα, εξασφαλίζοντας ένα καθαρό τελικό έγγραφο.
|
autoSplitPDF.selectText.4=Οι σελίδες διαχωρισμού ανιχνεύονται και αφαιρούνται αυτόματα, εξασφαλίζοντας ένα καθαρό τελικό έγγραφο.
|
||||||
autoSplitPDF.formPrompt=Υποβολή PDF που περιέχει διαχωριστές σελίδων Stirling-PDF:
|
autoSplitPDF.formPrompt=Υποβολή PDF που περιέχει διαχωριστές σελίδων Stirling-PDF:
|
||||||
autoSplitPDF.duplexMode=Λειτουργία διπλής όψης (Σάρωση μπρος και πίσω)
|
autoSplitPDF.duplexMode=Λειτουργία διπλής όψης (Σάρωση μπρος και πίσω)
|
||||||
autoSplitPDF.dividerDownload1=Λήψη 'Αυτόματος διαχωριστής (ελάχιστος).pdf'
|
|
||||||
autoSplitPDF.dividerDownload2=Λήψη 'Αυτόματος διαχωριστής (με οδηγίες).pdf'
|
autoSplitPDF.dividerDownload2=Λήψη 'Αυτόματος διαχωριστής (με οδηγίες).pdf'
|
||||||
autoSplitPDF.submit=Υποβολή
|
autoSplitPDF.submit=Υποβολή
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=Αφαίρεση πρώτης
|
|||||||
pdfOrganiser.mode.8=Αφαίρεση τελευταίας
|
pdfOrganiser.mode.8=Αφαίρεση τελευταίας
|
||||||
pdfOrganiser.mode.9=Αφαίρεση πρώτης και τελευταίας
|
pdfOrganiser.mode.9=Αφαίρεση πρώτης και τελευταίας
|
||||||
pdfOrganiser.mode.10=Συγχώνευση μονών-ζυγών
|
pdfOrganiser.mode.10=Συγχώνευση μονών-ζυγών
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(π.χ. 1,3,2 ή 4-8,2,10-12 ή 2n-1)
|
pdfOrganiser.placeholder=(π.χ. 1,3,2 ή 4-8,2,10-12 ή 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=Το αρχείο αποκρυπτογραφήθηκε με επ
|
|||||||
multiTool-advert.message=Αυτή η λειτουργία είναι επίσης διαθέσιμη στη <a href="{0}">σελίδα πολυεργαλείου</a> μας. Δείτε την για βελτιωμένο περιβάλλον χρήστη σελίδα-προς-σελίδα και επιπλέον λειτουργίες!
|
multiTool-advert.message=Αυτή η λειτουργία είναι επίσης διαθέσιμη στη <a href="{0}">σελίδα πολυεργαλείου</a> μας. Δείτε την για βελτιωμένο περιβάλλον χρήστη σελίδα-προς-σελίδα και επιπλέον λειτουργίες!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=Προβολή PDF
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=Προβολή PDF
|
viewPdf.header=Προβολή PDF
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=Αλλαγή
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF σε PDF/A
|
pdfToPDFA.title=PDF σε PDF/A
|
||||||
pdfToPDFA.header=PDF σε PDF/A
|
pdfToPDFA.header=PDF σε PDF/A
|
||||||
pdfToPDFA.credit=Αυτή η υπηρεσία χρησιμοποιεί qpdf για μετατροπή PDF/A
|
pdfToPDFA.credit=Αυτή η υπηρεσία χρησιμοποιεί libreoffice για μετατροπή PDF/A
|
||||||
pdfToPDFA.submit=Μετατροπή
|
pdfToPDFA.submit=Μετατροπή
|
||||||
pdfToPDFA.tip=Προς το παρόν δεν λειτουργεί για πολλαπλές εισόδους ταυτόχρονα
|
pdfToPDFA.tip=Προς το παρόν δεν λειτουργεί για πολλαπλές εισόδους ταυτόχρονα
|
||||||
pdfToPDFA.outputFormat=Μορφή εξόδου
|
pdfToPDFA.outputFormat=Μορφή εξόδου
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=You can change the settings for analytics in the config/setti
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Favorites
|
navbar.favorite=Favorites
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=Dark Mode
|
navbar.darkmode=Dark Mode
|
||||||
navbar.language=Languages
|
navbar.language=Languages
|
||||||
navbar.settings=Settings
|
navbar.settings=Settings
|
||||||
@@ -261,9 +262,18 @@ home.desc=Your locally hosted one-stop-shop for all your PDF needs.
|
|||||||
home.searchBar=Search for features...
|
home.searchBar=Search for features...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=View PDF
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=View, annotate, add text or images
|
home.viewPdf.desc=View, annotate, draw, add text or images
|
||||||
viewPdf.tags=view,read,annotate,text,image
|
viewPdf.tags=view,read,annotate,text,image,highlight,edit
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Multi Tool
|
home.multiTool.title=PDF Multi Tool
|
||||||
home.multiTool.desc=Merge, Rotate, Rearrange, Split, and Remove pages
|
home.multiTool.desc=Merge, Rotate, Rearrange, Split, and Remove pages
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Show Attachments
|
|||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
||||||
redact.colourPicker=Colour Picker
|
redact.colourPicker=Colour Picker
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
redact.findCurrentOutlineItem=Find current outline item
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Show Javascript
|
showJS.title=Show Javascript
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirl
|
|||||||
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
|
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
|
||||||
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
|
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
|
||||||
autoSplitPDF.duplexMode=Duplex Mode (Front and back scanning)
|
autoSplitPDF.duplexMode=Duplex Mode (Front and back scanning)
|
||||||
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
|
|
||||||
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
|
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
|
||||||
autoSplitPDF.submit=Submit
|
autoSplitPDF.submit=Submit
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=Remove First
|
|||||||
pdfOrganiser.mode.8=Remove Last
|
pdfOrganiser.mode.8=Remove Last
|
||||||
pdfOrganiser.mode.9=Remove First and Last
|
pdfOrganiser.mode.9=Remove First and Last
|
||||||
pdfOrganiser.mode.10=Odd-Even Merge
|
pdfOrganiser.mode.10=Odd-Even Merge
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1)
|
pdfOrganiser.placeholder=(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1007,8 +1018,8 @@ multiTool.moveLeft=Move Left
|
|||||||
multiTool.moveRight=Move Right
|
multiTool.moveRight=Move Right
|
||||||
multiTool.delete=Delete
|
multiTool.delete=Delete
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
multiTool.dragDropMessage=Page(s) Selected
|
||||||
multiTool.undo=Undo
|
multiTool.undo=Undo (CTRL + Z)
|
||||||
multiTool.redo=Redo
|
multiTool.redo=Redo (CTRL + Y)
|
||||||
|
|
||||||
#decrypt
|
#decrypt
|
||||||
decrypt.passwordPrompt=This file is password-protected. Please enter the password:
|
decrypt.passwordPrompt=This file is password-protected. Please enter the password:
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=File decrypted successfully.
|
|||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=View PDF
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=View PDF
|
viewPdf.header=View PDF
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=Change
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF To PDF/A
|
pdfToPDFA.title=PDF To PDF/A
|
||||||
pdfToPDFA.header=PDF To PDF/A
|
pdfToPDFA.header=PDF To PDF/A
|
||||||
pdfToPDFA.credit=This service uses qpdf for PDF/A conversion
|
pdfToPDFA.credit=This service uses libreoffice for PDF/A conversion
|
||||||
pdfToPDFA.submit=Convert
|
pdfToPDFA.submit=Convert
|
||||||
pdfToPDFA.tip=Currently does not work for multiple inputs at once
|
pdfToPDFA.tip=Currently does not work for multiple inputs at once
|
||||||
pdfToPDFA.outputFormat=Output format
|
pdfToPDFA.outputFormat=Output format
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=You can change the settings for analytics in the config/setti
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Favorites
|
navbar.favorite=Favorites
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=Dark Mode
|
navbar.darkmode=Dark Mode
|
||||||
navbar.language=Languages
|
navbar.language=Languages
|
||||||
navbar.settings=Settings
|
navbar.settings=Settings
|
||||||
@@ -261,9 +262,18 @@ home.desc=Your locally hosted one-stop-shop for all your PDF needs.
|
|||||||
home.searchBar=Search for features...
|
home.searchBar=Search for features...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=View PDF
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=View, annotate, add text or images
|
home.viewPdf.desc=View, annotate, draw, add text or images
|
||||||
viewPdf.tags=view,read,annotate,text,image
|
viewPdf.tags=view,read,annotate,text,image,highlight,edit
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Multi Tool
|
home.multiTool.title=PDF Multi Tool
|
||||||
home.multiTool.desc=Merge, Rotate, Rearrange, Split, and Remove pages
|
home.multiTool.desc=Merge, Rotate, Rearrange, Split, and Remove pages
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Show Attachments
|
|||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
||||||
redact.colourPicker=Colour Picker
|
redact.colourPicker=Colour Picker
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
redact.findCurrentOutlineItem=Find current outline item
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Show Javascript
|
showJS.title=Show Javascript
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=Upload the single large scanned PDF file and let Stirl
|
|||||||
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
|
autoSplitPDF.selectText.4=Divider pages are automatically detected and removed, guaranteeing a neat final document.
|
||||||
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
|
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
|
||||||
autoSplitPDF.duplexMode=Duplex Mode (Front and back scanning)
|
autoSplitPDF.duplexMode=Duplex Mode (Front and back scanning)
|
||||||
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
|
|
||||||
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
|
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
|
||||||
autoSplitPDF.submit=Submit
|
autoSplitPDF.submit=Submit
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=Remove First
|
|||||||
pdfOrganiser.mode.8=Remove Last
|
pdfOrganiser.mode.8=Remove Last
|
||||||
pdfOrganiser.mode.9=Remove First and Last
|
pdfOrganiser.mode.9=Remove First and Last
|
||||||
pdfOrganiser.mode.10=Odd-Even Merge
|
pdfOrganiser.mode.10=Odd-Even Merge
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1)
|
pdfOrganiser.placeholder=(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=File decrypted successfully.
|
|||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=View PDF
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=View PDF
|
viewPdf.header=View PDF
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=Change
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF To PDF/A
|
pdfToPDFA.title=PDF To PDF/A
|
||||||
pdfToPDFA.header=PDF To PDF/A
|
pdfToPDFA.header=PDF To PDF/A
|
||||||
pdfToPDFA.credit=This service uses qpdf for PDF/A conversion
|
pdfToPDFA.credit=This service uses libreoffice for PDF/A conversion
|
||||||
pdfToPDFA.submit=Convert
|
pdfToPDFA.submit=Convert
|
||||||
pdfToPDFA.tip=Currently does not work for multiple inputs at once
|
pdfToPDFA.tip=Currently does not work for multiple inputs at once
|
||||||
pdfToPDFA.outputFormat=Output format
|
pdfToPDFA.outputFormat=Output format
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=Puede cambiar la configuración de analíticas en el archivo
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Favoritos
|
navbar.favorite=Favoritos
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=Modo oscuro
|
navbar.darkmode=Modo oscuro
|
||||||
navbar.language=Idiomas
|
navbar.language=Idiomas
|
||||||
navbar.settings=Configuración
|
navbar.settings=Configuración
|
||||||
@@ -261,10 +262,19 @@ home.desc=Su ventanilla única autohospedada para todas sus necesidades PDF
|
|||||||
home.searchBar=Buscar características...
|
home.searchBar=Buscar características...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=Ver PDF
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=Ver, anotar, añadir texto o imágenes
|
home.viewPdf.desc=Ver, anotar, añadir texto o imágenes
|
||||||
viewPdf.tags=ver,leer,anotar,texto,imagen
|
viewPdf.tags=ver,leer,anotar,texto,imagen
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Multi-herramienta PDF
|
home.multiTool.title=Multi-herramienta PDF
|
||||||
home.multiTool.desc=Combinar, rotar, reorganizar y eliminar páginas
|
home.multiTool.desc=Combinar, rotar, reorganizar y eliminar páginas
|
||||||
multiTool.tags=Multi-herramienta,Multi-operación,Interfaz de usuario,Arrastrar con un click,front end,lado del cliente
|
multiTool.tags=Multi-herramienta,Multi-operación,Interfaz de usuario,Arrastrar con un click,front end,lado del cliente
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Show Attachments
|
|||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
||||||
redact.colourPicker=Colour Picker
|
redact.colourPicker=Colour Picker
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
redact.findCurrentOutlineItem=Find current outline item
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Mostrar Javascript
|
showJS.title=Mostrar Javascript
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=Cargue un único archivo PDF escaneado de gran tamaño
|
|||||||
autoSplitPDF.selectText.4=Las páginas divisorias son automáticamente detectadas y eliminadas, garantizando un buen documento final.
|
autoSplitPDF.selectText.4=Las páginas divisorias son automáticamente detectadas y eliminadas, garantizando un buen documento final.
|
||||||
autoSplitPDF.formPrompt=Entregar PDF conteniendo divisores de página de Stirling-PDF:
|
autoSplitPDF.formPrompt=Entregar PDF conteniendo divisores de página de Stirling-PDF:
|
||||||
autoSplitPDF.duplexMode=Modo Dúplex (Escaneado de ambas caras)
|
autoSplitPDF.duplexMode=Modo Dúplex (Escaneado de ambas caras)
|
||||||
autoSplitPDF.dividerDownload1=Descargar 'Divisor automático (mínima).pdf'
|
|
||||||
autoSplitPDF.dividerDownload2=Descargar 'Divisor automático (con instrucciones).pdf'
|
autoSplitPDF.dividerDownload2=Descargar 'Divisor automático (con instrucciones).pdf'
|
||||||
autoSplitPDF.submit=Entregar
|
autoSplitPDF.submit=Entregar
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=Quitar primera
|
|||||||
pdfOrganiser.mode.8=Quitar última
|
pdfOrganiser.mode.8=Quitar última
|
||||||
pdfOrganiser.mode.9=Quitar primera y última
|
pdfOrganiser.mode.9=Quitar primera y última
|
||||||
pdfOrganiser.mode.10=Unir impar-par
|
pdfOrganiser.mode.10=Unir impar-par
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(por ej., 1,3,2 o 4-8,2,10-12 o 2n-1)
|
pdfOrganiser.placeholder=(por ej., 1,3,2 o 4-8,2,10-12 o 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=File decrypted successfully.
|
|||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=Ver PDF
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=Ver PDF
|
viewPdf.header=Ver PDF
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=Cambiar
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF a PDF/A
|
pdfToPDFA.title=PDF a PDF/A
|
||||||
pdfToPDFA.header=PDF a PDF/A
|
pdfToPDFA.header=PDF a PDF/A
|
||||||
pdfToPDFA.credit=Este servicio usa qpdf para la conversión a PDF/A
|
pdfToPDFA.credit=Este servicio usa libreoffice para la conversión a PDF/A
|
||||||
pdfToPDFA.submit=Convertir
|
pdfToPDFA.submit=Convertir
|
||||||
pdfToPDFA.tip=Actualmente no funciona para múltiples entrada a la vez
|
pdfToPDFA.tip=Actualmente no funciona para múltiples entrada a la vez
|
||||||
pdfToPDFA.outputFormat=Formato de salida
|
pdfToPDFA.outputFormat=Formato de salida
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=You can change the settings for analytics in the config/setti
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Favorites
|
navbar.favorite=Favorites
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=Modu iluna
|
navbar.darkmode=Modu iluna
|
||||||
navbar.language=Languages
|
navbar.language=Languages
|
||||||
navbar.settings=Ezarpenak
|
navbar.settings=Ezarpenak
|
||||||
@@ -261,10 +262,19 @@ home.desc=Zure leihatila bakarra autoostatatua zure PDF behar guztietarako
|
|||||||
home.searchBar=Search for features...
|
home.searchBar=Search for features...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=View PDF
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=View, annotate, add text or images
|
home.viewPdf.desc=View, annotate, add text or images
|
||||||
viewPdf.tags=view,read,annotate,text,image
|
viewPdf.tags=view,read,annotate,text,image
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Erabilera anitzeko tresna PDF
|
home.multiTool.title=Erabilera anitzeko tresna PDF
|
||||||
home.multiTool.desc=Orriak konbinatu, biratu, berrantolatu eta ezabatu
|
home.multiTool.desc=Orriak konbinatu, biratu, berrantolatu eta ezabatu
|
||||||
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
|
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Show Attachments
|
|||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
||||||
redact.colourPicker=Colour Picker
|
redact.colourPicker=Colour Picker
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
redact.findCurrentOutlineItem=Find current outline item
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Javascript erakutsi
|
showJS.title=Javascript erakutsi
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=Igo eskaneatutako PDF artxibo handia, eta utzi Stirlin
|
|||||||
autoSplitPDF.selectText.4=Orrialde zatitzaileak automatikoki detektatu eta kentzen dira, eta azken dokumentu ordenatua bermatzen da.
|
autoSplitPDF.selectText.4=Orrialde zatitzaileak automatikoki detektatu eta kentzen dira, eta azken dokumentu ordenatua bermatzen da.
|
||||||
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
|
autoSplitPDF.formPrompt=Submit PDF containing Stirling-PDF Page dividers:
|
||||||
autoSplitPDF.duplexMode=Duplex Mode (Front and back scanning)Duplex modua (aurreko eta atzeko azterketa)
|
autoSplitPDF.duplexMode=Duplex Mode (Front and back scanning)Duplex modua (aurreko eta atzeko azterketa)
|
||||||
autoSplitPDF.dividerDownload1=Deskargatu 'Auto Splitter Divider (minimal).pdf'
|
|
||||||
autoSplitPDF.dividerDownload2=Deskargatu 'Auto Splitter Divider (with instructions).pdf'
|
autoSplitPDF.dividerDownload2=Deskargatu 'Auto Splitter Divider (with instructions).pdf'
|
||||||
autoSplitPDF.submit=Bidali
|
autoSplitPDF.submit=Bidali
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=Remove First
|
|||||||
pdfOrganiser.mode.8=Remove Last
|
pdfOrganiser.mode.8=Remove Last
|
||||||
pdfOrganiser.mode.9=Remove First and Last
|
pdfOrganiser.mode.9=Remove First and Last
|
||||||
pdfOrganiser.mode.10=Odd-Even Merge
|
pdfOrganiser.mode.10=Odd-Even Merge
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1)
|
pdfOrganiser.placeholder=(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=File decrypted successfully.
|
|||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=View PDF
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=View PDF
|
viewPdf.header=View PDF
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=Aldatu
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDFa PDF/A bihurtu
|
pdfToPDFA.title=PDFa PDF/A bihurtu
|
||||||
pdfToPDFA.header=PDFa PDF/A bihurtu
|
pdfToPDFA.header=PDFa PDF/A bihurtu
|
||||||
pdfToPDFA.credit=Zerbitzu honek qpdf erabiltzen du PDFak PDF/A bihurtzeko
|
pdfToPDFA.credit=Zerbitzu honek libreoffice erabiltzen du PDFak PDF/A bihurtzeko
|
||||||
pdfToPDFA.submit=Bihurtu
|
pdfToPDFA.submit=Bihurtu
|
||||||
pdfToPDFA.tip=Currently does not work for multiple inputs at once
|
pdfToPDFA.tip=Currently does not work for multiple inputs at once
|
||||||
pdfToPDFA.outputFormat=Output format
|
pdfToPDFA.outputFormat=Output format
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=میتوانید تنظیمات مربوط به تحلیل
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=علاقهمندیها
|
navbar.favorite=علاقهمندیها
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=حالت تاریک
|
navbar.darkmode=حالت تاریک
|
||||||
navbar.language=زبانها
|
navbar.language=زبانها
|
||||||
navbar.settings=تنظیمات
|
navbar.settings=تنظیمات
|
||||||
@@ -261,10 +262,19 @@ home.desc=مغازه همهکاره میزبانیشده به صورت
|
|||||||
home.searchBar=جستجو برای ویژگیها...
|
home.searchBar=جستجو برای ویژگیها...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=مشاهده PDF
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=مشاهده، حاشیهنویسی، افزودن متن یا تصاویر
|
home.viewPdf.desc=مشاهده، حاشیهنویسی، افزودن متن یا تصاویر
|
||||||
viewPdf.tags=مشاهده،خواندن،حاشیهنویسی،متن،تصویر
|
viewPdf.tags=مشاهده،خواندن،حاشیهنویسی،متن،تصویر
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=ابزار چندگانه PDF
|
home.multiTool.title=ابزار چندگانه PDF
|
||||||
home.multiTool.desc=ترکیب، چرخش، بازآرایی، تقسیم و حذف صفحات
|
home.multiTool.desc=ترکیب، چرخش، بازآرایی، تقسیم و حذف صفحات
|
||||||
multiTool.tags=ابزار چندگانه،عملیات چندگانه،واسط کاربری،کلیک و کشیدن،فرانتاند،کاربردی،قابل تعامل،جابجایی،حذف،تقسیم
|
multiTool.tags=ابزار چندگانه،عملیات چندگانه،واسط کاربری،کلیک و کشیدن،فرانتاند،کاربردی،قابل تعامل،جابجایی،حذف،تقسیم
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Show Attachments
|
|||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
||||||
redact.colourPicker=Colour Picker
|
redact.colourPicker=Colour Picker
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
redact.findCurrentOutlineItem=Find current outline item
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=نمایش جاوااسکریپت
|
showJS.title=نمایش جاوااسکریپت
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=فایل PDF بزرگ اسکن شده را بارگذ
|
|||||||
autoSplitPDF.selectText.4=صفحات جداکننده به طور خودکار تشخیص داده و حذف میشوند، تضمینکننده یک سند نهایی منظم.
|
autoSplitPDF.selectText.4=صفحات جداکننده به طور خودکار تشخیص داده و حذف میشوند، تضمینکننده یک سند نهایی منظم.
|
||||||
autoSplitPDF.formPrompt=PDF حاوی جداکنندههای Stirling-PDF را ارسال کنید:
|
autoSplitPDF.formPrompt=PDF حاوی جداکنندههای Stirling-PDF را ارسال کنید:
|
||||||
autoSplitPDF.duplexMode=حالت دوبلکس (اسکن جلو و عقب)
|
autoSplitPDF.duplexMode=حالت دوبلکس (اسکن جلو و عقب)
|
||||||
autoSplitPDF.dividerDownload1=دانلود 'Auto Splitter Divider (minimal).pdf'
|
|
||||||
autoSplitPDF.dividerDownload2=دانلود 'Auto Splitter Divider (with instructions).pdf'
|
autoSplitPDF.dividerDownload2=دانلود 'Auto Splitter Divider (with instructions).pdf'
|
||||||
autoSplitPDF.submit=ارسال
|
autoSplitPDF.submit=ارسال
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=حذف اولین
|
|||||||
pdfOrganiser.mode.8=حذف آخرین
|
pdfOrganiser.mode.8=حذف آخرین
|
||||||
pdfOrganiser.mode.9=حذف اول و آخر
|
pdfOrganiser.mode.9=حذف اول و آخر
|
||||||
pdfOrganiser.mode.10=ادغام فرد-زوج
|
pdfOrganiser.mode.10=ادغام فرد-زوج
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(مثال: ۱,۳,۲ یا ۴-۸,۲,۱۰-۱۲ یا 2n-1)
|
pdfOrganiser.placeholder=(مثال: ۱,۳,۲ یا ۴-۸,۲,۱۰-۱۲ یا 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=File decrypted successfully.
|
|||||||
multiTool-advert.message=این ویژگی همچنین در <a href="{0}">صفحه ابزار چندگانه ما</a> موجود است. برای رابط کاربری صفحه به صفحه پیشرفته و ویژگیهای اضافی بررسی کنید!
|
multiTool-advert.message=این ویژگی همچنین در <a href="{0}">صفحه ابزار چندگانه ما</a> موجود است. برای رابط کاربری صفحه به صفحه پیشرفته و ویژگیهای اضافی بررسی کنید!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=مشاهده PDF
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=مشاهده PDF
|
viewPdf.header=مشاهده PDF
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=تغییر
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF به PDF/A
|
pdfToPDFA.title=PDF به PDF/A
|
||||||
pdfToPDFA.header=PDF به PDF/A
|
pdfToPDFA.header=PDF به PDF/A
|
||||||
pdfToPDFA.credit=این سرویس از qpdf برای تبدیل PDF/A استفاده میکند
|
pdfToPDFA.credit=این سرویس از libreoffice برای تبدیل PDF/A استفاده میکند
|
||||||
pdfToPDFA.submit=تبدیل
|
pdfToPDFA.submit=تبدیل
|
||||||
pdfToPDFA.tip=در حال حاضر برای چندین ورودی به طور همزمان کار نمیکند
|
pdfToPDFA.tip=در حال حاضر برای چندین ورودی به طور همزمان کار نمیکند
|
||||||
pdfToPDFA.outputFormat=فرمت خروجی
|
pdfToPDFA.outputFormat=فرمت خروجی
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=Vous pouvez modifier les paramètres des analyses dans le fic
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Favoris
|
navbar.favorite=Favoris
|
||||||
|
navbar.recent=Nouveau et mise à jour
|
||||||
navbar.darkmode=Mode sombre
|
navbar.darkmode=Mode sombre
|
||||||
navbar.language=Langues
|
navbar.language=Langues
|
||||||
navbar.settings=Paramètres
|
navbar.settings=Paramètres
|
||||||
@@ -261,10 +262,19 @@ home.desc=Votre application Web hébergée localement pour répondre à tous vos
|
|||||||
home.searchBar=Rechercher des fonctionnalités...
|
home.searchBar=Rechercher des fonctionnalités...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=Visionner le PDF
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=Visionner, annoter, ajouter du texte ou des images.
|
home.viewPdf.desc=Visionner, annoter, ajouter du texte ou des images.
|
||||||
viewPdf.tags=visualiser,lire,annoter,texte,image
|
viewPdf.tags=visualiser,lire,annoter,texte,image
|
||||||
|
|
||||||
|
home.setFavorites=Ajouter des favoris
|
||||||
|
home.hideFavorites=Cacher les favoris
|
||||||
|
home.showFavorites=Montrer les favoris
|
||||||
|
home.legacyHomepage=Ancienne Homepage
|
||||||
|
home.newHomePage=Essayez notre nouvelle Homepage !
|
||||||
|
home.alphabetical=Alphabétique
|
||||||
|
home.globalPopularity=Popularité globale
|
||||||
|
home.sortBy=Trier par :
|
||||||
|
|
||||||
home.multiTool.title=Outil multifonction PDF
|
home.multiTool.title=Outil multifonction PDF
|
||||||
home.multiTool.desc=Fusionnez, faites pivoter, réorganisez et supprimez des pages.
|
home.multiTool.desc=Fusionnez, faites pivoter, réorganisez et supprimez des pages.
|
||||||
multiTool.tags=outil multifonction,opération multifonction,interface utilisateur,glisser déposer,front-end,client side,interactif,intransigeant,déplacer,multi tool
|
multiTool.tags=outil multifonction,opération multifonction,interface utilisateur,glisser déposer,front-end,client side,interactif,intransigeant,déplacer,multi tool
|
||||||
@@ -475,13 +485,13 @@ home.showJS.title=Afficher le JavaScript
|
|||||||
home.showJS.desc=Recherche et affiche tout JavaScript injecté dans un PDF.
|
home.showJS.desc=Recherche et affiche tout JavaScript injecté dans un PDF.
|
||||||
showJS.tags=JS
|
showJS.tags=JS
|
||||||
|
|
||||||
home.autoRedact.title=Caviarder automatiquement
|
home.autoRedact.title=Censure automatique
|
||||||
home.autoRedact.desc=Caviardez automatiquement les informations sensibles d'un PDF.
|
home.autoRedact.desc=Censurer automatiquement les informations sensibles d'un PDF.
|
||||||
autoRedact.tags=caviarder,redact,auto
|
autoRedact.tags=caviarder,rédiger,censurer,redact,auto
|
||||||
|
|
||||||
home.redact.title=Rédaction manuelle
|
home.redact.title=Censure manuelle
|
||||||
home.redact.desc=Rédiger un PDF en fonction de texte sélectionné, formes dessinées et/ou des pages sélectionnées.
|
home.redact.desc=Censurer un PDF en fonction de texte sélectionné, formes dessinées et/ou des pages sélectionnées.
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
redact.tags=Redact,Hide,black out,black,marker,hidden,manual,caviarder,rédiger,censurer
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF en CSV
|
home.tableExtraxt.title=PDF en CSV
|
||||||
home.tableExtraxt.desc=Extrait les tableaux d'un PDF et les transforme en CSV.
|
home.tableExtraxt.desc=Extrait les tableaux d'un PDF et les transforme en CSV.
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Montrer les éléments attachés
|
|||||||
redact.showLayers=Montrer les calques (double-click pour réinitialiser tous les calques à l'état par défaut)
|
redact.showLayers=Montrer les calques (double-click pour réinitialiser tous les calques à l'état par défaut)
|
||||||
redact.colourPicker=Sélection de couleur
|
redact.colourPicker=Sélection de couleur
|
||||||
redact.findCurrentOutlineItem=Trouver l'élément de contour courrant
|
redact.findCurrentOutlineItem=Trouver l'élément de contour courrant
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Afficher le JavaScript
|
showJS.title=Afficher le JavaScript
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=Téléchargez le fichier PDF numérisé et laissez Sti
|
|||||||
autoSplitPDF.selectText.4=Les feuilles de séparation sont automatiquement détectées et supprimées, garantissant un document final soigné.
|
autoSplitPDF.selectText.4=Les feuilles de séparation sont automatiquement détectées et supprimées, garantissant un document final soigné.
|
||||||
autoSplitPDF.formPrompt=PDF contenant des feuilles de séparation de Stirling PDF :
|
autoSplitPDF.formPrompt=PDF contenant des feuilles de séparation de Stirling PDF :
|
||||||
autoSplitPDF.duplexMode=Mode recto-verso
|
autoSplitPDF.duplexMode=Mode recto-verso
|
||||||
autoSplitPDF.dividerDownload1=Auto Splitter Divider (minimal).pdf
|
|
||||||
autoSplitPDF.dividerDownload2=Auto Splitter Divider (with instructions).pdf
|
autoSplitPDF.dividerDownload2=Auto Splitter Divider (with instructions).pdf
|
||||||
autoSplitPDF.submit=Séparer
|
autoSplitPDF.submit=Séparer
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=Supprimer le premier
|
|||||||
pdfOrganiser.mode.8=Supprimer le dernier
|
pdfOrganiser.mode.8=Supprimer le dernier
|
||||||
pdfOrganiser.mode.9=Supprimer le premier et le dernier
|
pdfOrganiser.mode.9=Supprimer le premier et le dernier
|
||||||
pdfOrganiser.mode.10=Méger Impair-Pair
|
pdfOrganiser.mode.10=Méger Impair-Pair
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(par exemple 1,3,2 ou 4-8,2,10-12 ou 2n-1)
|
pdfOrganiser.placeholder=(par exemple 1,3,2 ou 4-8,2,10-12 ou 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=Fichier déchiffré avec succès.
|
|||||||
multiTool-advert.message=Cette fonctionnalité est aussi disponible dans la <a href="{0}">page de l'outil multifonction</a>. Allez-y pour une interface page par page améliorée et des fonctionnalités additionnelles !
|
multiTool-advert.message=Cette fonctionnalité est aussi disponible dans la <a href="{0}">page de l'outil multifonction</a>. Allez-y pour une interface page par page améliorée et des fonctionnalités additionnelles !
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=Visualiser un PDF
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=Visualiser un PDF
|
viewPdf.header=Visualiser un PDF
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=Modifier
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF en PDF/A
|
pdfToPDFA.title=PDF en PDF/A
|
||||||
pdfToPDFA.header=PDF en PDF/A
|
pdfToPDFA.header=PDF en PDF/A
|
||||||
pdfToPDFA.credit=Ce service utilise qpdf pour la conversion en PDF/A.
|
pdfToPDFA.credit=Ce service utilise libreoffice pour la conversion en PDF/A.
|
||||||
pdfToPDFA.submit=Convertir
|
pdfToPDFA.submit=Convertir
|
||||||
pdfToPDFA.tip=Ne fonctionne actuellement pas pour plusieurs entrées à la fois
|
pdfToPDFA.tip=Ne fonctionne actuellement pas pour plusieurs entrées à la fois
|
||||||
pdfToPDFA.outputFormat=Format de sortie
|
pdfToPDFA.outputFormat=Format de sortie
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
###########
|
###########
|
||||||
# the direction that the language is written (ltr = left to right, rtl = right to left)
|
# the direction that the language is written (ltr = left to right, rtl = right to left)
|
||||||
language.direction=ltr
|
language.direction=ltr
|
||||||
addPageNumbers.fontSize=Font Size
|
addPageNumbers.fontSize=Méid an Chló
|
||||||
addPageNumbers.fontName=Font Name
|
addPageNumbers.fontName=Ainm Cló
|
||||||
pdfPrompt=Roghnaigh PDF(s)
|
pdfPrompt=Roghnaigh PDF(anna)
|
||||||
multiPdfPrompt=Roghnaigh PDFs (2+)
|
multiPdfPrompt=Roghnaigh PDFs (2+)
|
||||||
multiPdfDropPrompt=Roghnaigh (nó tarraing & scaoil) gach PDF atá uait
|
multiPdfDropPrompt=Roghnaigh (nó tarraing & scaoil) gach PDF atá uait
|
||||||
imgPrompt=Roghnaigh Íomhá(í)
|
imgPrompt=Roghnaigh Íomhá(í)
|
||||||
@@ -56,12 +56,12 @@ userNotFoundMessage=Úsáideoir gan aimsiú.
|
|||||||
incorrectPasswordMessage=Tá an pasfhocal reatha mícheart.
|
incorrectPasswordMessage=Tá an pasfhocal reatha mícheart.
|
||||||
usernameExistsMessage=Tá Ainm Úsáideora Nua ann cheana féin.
|
usernameExistsMessage=Tá Ainm Úsáideora Nua ann cheana féin.
|
||||||
invalidUsernameMessage=Ainm úsáideora neamhbhailí, ní féidir ach litreacha, uimhreacha agus na carachtair speisialta seo a leanas @._+- a bheith san ainm úsáideora nó ní mór gur seoladh ríomhphoist bailí é.
|
invalidUsernameMessage=Ainm úsáideora neamhbhailí, ní féidir ach litreacha, uimhreacha agus na carachtair speisialta seo a leanas @._+- a bheith san ainm úsáideora nó ní mór gur seoladh ríomhphoist bailí é.
|
||||||
invalidPasswordMessage=The password must not be empty and must not have spaces at the beginning or end.
|
invalidPasswordMessage=Níor cheart go mbeadh an pasfhocal folamh agus níor cheart go mbeadh spásanna ag an tús nó ag an deireadh.
|
||||||
confirmPasswordErrorMessage=Ní mór Pasfhocal Nua agus Deimhnigh Pasfhocal Nua a bheith ag teacht leis.
|
confirmPasswordErrorMessage=Ní mór Pasfhocal Nua agus Deimhnigh Pasfhocal Nua a bheith ag teacht leis.
|
||||||
deleteCurrentUserMessage=Ní féidir an t-úsáideoir atá logáilte isteach faoi láthair a scriosadh.
|
deleteCurrentUserMessage=Ní féidir an t-úsáideoir atá logáilte isteach faoi láthair a scriosadh.
|
||||||
deleteUsernameExistsMessage=Níl an t-ainm úsáideora ann agus ní féidir é a scriosadh.
|
deleteUsernameExistsMessage=Níl an t-ainm úsáideora ann agus ní féidir é a scriosadh.
|
||||||
downgradeCurrentUserMessage=Ní féidir ról an úsáideora reatha a íosghrádú
|
downgradeCurrentUserMessage=Ní féidir ról an úsáideora reatha a íosghrádú
|
||||||
disabledCurrentUserMessage=The current user cannot be disabled
|
disabledCurrentUserMessage=Ní féidir an t-úsáideoir reatha a dhíchumasú
|
||||||
downgradeCurrentUserLongMessage=Ní féidir ról an úsáideora reatha a íosghrádú. Mar sin, ní thaispeánfar an t-úsáideoir reatha.
|
downgradeCurrentUserLongMessage=Ní féidir ról an úsáideora reatha a íosghrádú. Mar sin, ní thaispeánfar an t-úsáideoir reatha.
|
||||||
userAlreadyExistsOAuthMessage=Tá an t-úsáideoir ann cheana mar úsáideoir OAuth2.
|
userAlreadyExistsOAuthMessage=Tá an t-úsáideoir ann cheana mar úsáideoir OAuth2.
|
||||||
userAlreadyExistsWebMessage=Tá an t-úsáideoir ann cheana féin mar úsáideoir gréasáin.
|
userAlreadyExistsWebMessage=Tá an t-úsáideoir ann cheana féin mar úsáideoir gréasáin.
|
||||||
@@ -77,17 +77,17 @@ color=Dath
|
|||||||
sponsor=Urraitheoir
|
sponsor=Urraitheoir
|
||||||
info=Eolas
|
info=Eolas
|
||||||
pro=Pro
|
pro=Pro
|
||||||
page=Page
|
page=Leathanach
|
||||||
pages=Pages
|
pages=Leathanaigh
|
||||||
loading=Loading...
|
loading=Á lódáil...
|
||||||
addToDoc=Add to Document
|
addToDoc=Cuir le Doiciméad
|
||||||
reset=Reset
|
reset=Athshocraigh
|
||||||
apply=Apply
|
apply=Cuir i bhFeidhm
|
||||||
|
|
||||||
legal.privacy=Privacy Policy
|
legal.privacy=Polasaí Príobháideachta
|
||||||
legal.terms=Terms and Conditions
|
legal.terms=Téarmaí agus Coinníollacha
|
||||||
legal.accessibility=Accessibility
|
legal.accessibility=Inrochtaineacht
|
||||||
legal.cookie=Cookie Policy
|
legal.cookie=Polasaí Fianán
|
||||||
legal.impressum=Impressum
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
@@ -118,39 +118,40 @@ pipelineOptions.validateButton=Bailíochtaigh
|
|||||||
########################
|
########################
|
||||||
# ENTERPRISE EDITION #
|
# ENTERPRISE EDITION #
|
||||||
########################
|
########################
|
||||||
enterpriseEdition.button=Upgrade to Pro
|
enterpriseEdition.button=Uasghrádú go Pro
|
||||||
enterpriseEdition.warning=This feature is only available to Pro users.
|
enterpriseEdition.warning=Níl an ghné seo ar fáil ach d'úsáideoirí Pro.
|
||||||
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
|
enterpriseEdition.yamlAdvert=Tacaíonn Stirling PDF Pro le comhaid cumraíochta YAML agus gnéithe SSO eile.
|
||||||
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
|
enterpriseEdition.ssoAdvert=Tá tuilleadh gnéithe bainistíochta úsáideoirí á lorg? Seiceáil Stirling PDF Pro
|
||||||
|
|
||||||
|
|
||||||
#################
|
#################
|
||||||
# Analytics #
|
# Analytics #
|
||||||
#################
|
#################
|
||||||
analytics.title=Do you want make Stirling PDF better?
|
analytics.title=An bhfuil fonn ort PDF Stirling a fheabhsú?
|
||||||
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
|
analytics.paragraph1=Tá rogha an diúltaithe ag PDF Stirling chun cabhrú linn an táirge a fheabhsú. Ní rianaimid aon fhaisnéis phearsanta nó ábhar comhaid.
|
||||||
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
|
analytics.paragraph2=Smaoinigh le do thoil ar anailísíocht a chumasú chun cabhrú le Stirling-PDF fás agus chun ligean dúinn ár n-úsáideoirí a thuiscint níos fearr.
|
||||||
analytics.enable=Enable analytics
|
analytics.enable=Cumasaigh anailísíocht
|
||||||
analytics.disable=Disable analytics
|
analytics.disable=Díchumasaigh anailísíocht
|
||||||
analytics.settings=You can change the settings for analytics in the config/settings.yml file
|
analytics.settings=Is féidir leat na socruithe don anailísíocht a athrú sa chomhad config/settings.yml
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Ceanáin
|
navbar.favorite=Ceanáin
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=Mód Dorcha
|
navbar.darkmode=Mód Dorcha
|
||||||
navbar.language=Teangacha
|
navbar.language=Teangacha
|
||||||
navbar.settings=Socruithe
|
navbar.settings=Socruithe
|
||||||
navbar.allTools=Uirlisí
|
navbar.allTools=Uirlisí
|
||||||
navbar.multiTool=Uirlisí Il
|
navbar.multiTool=Uirlisí Il
|
||||||
navbar.search=Search
|
navbar.search=Cuardach
|
||||||
navbar.sections.organize=Eagraigh
|
navbar.sections.organize=Eagraigh
|
||||||
navbar.sections.convertTo=Tiontaigh go PDF
|
navbar.sections.convertTo=Tiontaigh go PDF
|
||||||
navbar.sections.convertFrom=Tiontaigh ó PDF
|
navbar.sections.convertFrom=Tiontaigh ó PDF
|
||||||
navbar.sections.security=Comhartha & Slándáil
|
navbar.sections.security=Comhartha & Slándáil
|
||||||
navbar.sections.advance=Casta
|
navbar.sections.advance=Casta
|
||||||
navbar.sections.edit=Féach ar & Cuir in Eagar
|
navbar.sections.edit=Féach ar & Cuir in Eagar
|
||||||
navbar.sections.popular=Popular
|
navbar.sections.popular=Coitianta
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# SETTINGS #
|
# SETTINGS #
|
||||||
@@ -209,7 +210,7 @@ adminUserSettings.user=Úsáideoir
|
|||||||
adminUserSettings.addUser=Cuir Úsáideoir Nua leis
|
adminUserSettings.addUser=Cuir Úsáideoir Nua leis
|
||||||
adminUserSettings.deleteUser=Scrios Úsáideoir
|
adminUserSettings.deleteUser=Scrios Úsáideoir
|
||||||
adminUserSettings.confirmDeleteUser=Ar cheart an t-úsáideoir a scriosadh?
|
adminUserSettings.confirmDeleteUser=Ar cheart an t-úsáideoir a scriosadh?
|
||||||
adminUserSettings.confirmChangeUserStatus=Should the user be disabled/enabled?
|
adminUserSettings.confirmChangeUserStatus=Ar cheart an t-úsáideoir a dhíchumasú/a chumasú?
|
||||||
adminUserSettings.usernameInfo=Ní féidir ach litreacha, uimhreacha agus na carachtair speisialta seo a leanas @._+- a bheith san ainm úsáideora nó ní mór gur seoladh ríomhphoist bailí é.
|
adminUserSettings.usernameInfo=Ní féidir ach litreacha, uimhreacha agus na carachtair speisialta seo a leanas @._+- a bheith san ainm úsáideora nó ní mór gur seoladh ríomhphoist bailí é.
|
||||||
adminUserSettings.roles=Róil
|
adminUserSettings.roles=Róil
|
||||||
adminUserSettings.role=Ról
|
adminUserSettings.role=Ról
|
||||||
@@ -223,13 +224,13 @@ adminUserSettings.forceChange=Cuir iallach ar an úsáideoir pasfhocal a athrú
|
|||||||
adminUserSettings.submit=Sábháil Úsáideoir
|
adminUserSettings.submit=Sábháil Úsáideoir
|
||||||
adminUserSettings.changeUserRole=Athraigh Ról an Úsáideora
|
adminUserSettings.changeUserRole=Athraigh Ról an Úsáideora
|
||||||
adminUserSettings.authenticated=Fíordheimhnithe
|
adminUserSettings.authenticated=Fíordheimhnithe
|
||||||
adminUserSettings.editOwnProfil=Edit own profile
|
adminUserSettings.editOwnProfil=Cuir a phróifíl féin in eagar
|
||||||
adminUserSettings.enabledUser=enabled user
|
adminUserSettings.enabledUser=úsáideoir cumasaithe
|
||||||
adminUserSettings.disabledUser=disabled user
|
adminUserSettings.disabledUser=úsáideoir faoi mhíchumas
|
||||||
adminUserSettings.activeUsers=Active Users:
|
adminUserSettings.activeUsers=Úsáideoirí Gníomhacha:
|
||||||
adminUserSettings.disabledUsers=Disabled Users:
|
adminUserSettings.disabledUsers=Úsáideoirí faoi mhíchumas:
|
||||||
adminUserSettings.totalUsers=Total Users:
|
adminUserSettings.totalUsers=Úsáideoirí Iomlán:
|
||||||
adminUserSettings.lastRequest=Last Request
|
adminUserSettings.lastRequest=Iarratas Deiridh
|
||||||
|
|
||||||
|
|
||||||
database.title=Iompórtáil/Easpórtáil Bunachar Sonraí
|
database.title=Iompórtáil/Easpórtáil Bunachar Sonraí
|
||||||
@@ -239,20 +240,20 @@ database.creationDate=Dáta Cruthaithe
|
|||||||
database.fileSize=Méid an Chomhaid
|
database.fileSize=Méid an Chomhaid
|
||||||
database.deleteBackupFile=Scrios Comhad Cúltaca
|
database.deleteBackupFile=Scrios Comhad Cúltaca
|
||||||
database.importBackupFile=Iompórtáil Comhad Cúltaca
|
database.importBackupFile=Iompórtáil Comhad Cúltaca
|
||||||
database.createBackupFile=Create Backup File
|
database.createBackupFile=Cruthaigh Comhad Cúltaca
|
||||||
database.downloadBackupFile=Íoslódáil an comhad cúltaca
|
database.downloadBackupFile=Íoslódáil an comhad cúltaca
|
||||||
database.info_1=Agus sonraí á n-allmhairiú, tá sé ríthábhachtach an struchtúr ceart a chinntiú. Mura bhfuil tú cinnte faoina bhfuil ar siúl agat, iarr comhairle agus tacaíocht ó ghairmí. Féadfaidh earráid sa struchtúr a bheith ina chúis le mífheidhmeanna iarratais, suas go dtí agus lena n-áirítear an neamhábaltacht iomlán an t-iarratas a rith.
|
database.info_1=Agus sonraí á n-allmhairiú, tá sé ríthábhachtach an struchtúr ceart a chinntiú. Mura bhfuil tú cinnte faoina bhfuil ar siúl agat, iarr comhairle agus tacaíocht ó ghairmí. Féadfaidh earráid sa struchtúr a bheith ina chúis le mífheidhmeanna iarratais, suas go dtí agus lena n-áirítear an neamhábaltacht iomlán an t-iarratas a rith.
|
||||||
database.info_2=Ní hionann ainm an chomhaid agus é á uaslódáil. Déanfar é a athainmniú ina dhiaidh sin chun an fhormáid backup_user_yyyyMMddHHmm.sql a leanúint, ag cinntiú go bhfuil coinbhinsiún ainmniúcháin comhsheasmhach ann.
|
database.info_2=Ní hionann ainm an chomhaid agus é á uaslódáil. Déanfar é a athainmniú ina dhiaidh sin chun an fhormáid backup_user_yyyyMMddHHmm.sql a leanúint, ag cinntiú go bhfuil coinbhinsiún ainmniúcháin comhsheasmhach ann.
|
||||||
database.submit=Iompórtáil Cúltaca
|
database.submit=Iompórtáil Cúltaca
|
||||||
database.importIntoDatabaseSuccessed=D'éirigh leis an allmhairiú isteach sa bhunachar sonraí
|
database.importIntoDatabaseSuccessed=D'éirigh leis an allmhairiú isteach sa bhunachar sonraí
|
||||||
database.backupCreated=Database backup successful
|
database.backupCreated=D'éirigh le cúltaca bunachar sonraí
|
||||||
database.fileNotFound=Comhad gan aimsiú
|
database.fileNotFound=Comhad gan aimsiú
|
||||||
database.fileNullOrEmpty=Níor cheart go mbeadh an comhad ar neamhní nó folamh
|
database.fileNullOrEmpty=Níor cheart go mbeadh an comhad ar neamhní nó folamh
|
||||||
database.failedImportFile=Theip ar iompórtáil an chomhaid
|
database.failedImportFile=Theip ar iompórtáil an chomhaid
|
||||||
database.notSupported=This function is not available for your database connection.
|
database.notSupported=Níl an fheidhm seo ar fáil do nasc bunachar sonraí.
|
||||||
|
|
||||||
session.expired=Your session has expired. Please refresh the page and try again.
|
session.expired=Tá do sheisiún imithe in éag. Athnuaigh an leathanach agus bain triail eile as.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Athnuaigh an Leathanach
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# HOME-PAGE #
|
# HOME-PAGE #
|
||||||
@@ -261,10 +262,19 @@ home.desc=Do shiopa ilfhreastail arna óstáil go háitiúil do do riachtanais P
|
|||||||
home.searchBar=Cuardaigh gnéithe...
|
home.searchBar=Cuardaigh gnéithe...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=Féach PDF
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=Féach ar, nótáil, cuir téacs nó íomhánna leis
|
home.viewPdf.desc=Féach ar, nótáil, cuir téacs nó íomhánna leis
|
||||||
viewPdf.tags=amharc, léamh, anótáil, téacs, íomhá
|
viewPdf.tags=amharc, léamh, anótáil, téacs, íomhá
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Il-uirlis PDF
|
home.multiTool.title=Il-uirlis PDF
|
||||||
home.multiTool.desc=Cumaisc, Rothlaigh, Atheagraigh, agus Bain leathanaigh
|
home.multiTool.desc=Cumaisc, Rothlaigh, Atheagraigh, agus Bain leathanaigh
|
||||||
multiTool.tags=Il-Uirlis, Iloibríocht, Chomhéadain, cliceáil tarraing, ceann tosaigh, taobh an chliaint, idirghníomhach, intractable, bog
|
multiTool.tags=Il-Uirlis, Iloibríocht, Chomhéadain, cliceáil tarraing, ceann tosaigh, taobh an chliaint, idirghníomhach, intractable, bog
|
||||||
@@ -278,7 +288,7 @@ home.split.desc=Scoilt comhaid PDF isteach i ndoiciméid iolracha
|
|||||||
split.tags=Oibríochtaí leathanach, roinnt, Leathanach Il, gearrtha, taobh freastalaí
|
split.tags=Oibríochtaí leathanach, roinnt, Leathanach Il, gearrtha, taobh freastalaí
|
||||||
|
|
||||||
home.rotate.title=Rothlaigh
|
home.rotate.title=Rothlaigh
|
||||||
home.rotate.desc=Rothlaigh do PDFs go héasca.
|
home.rotate.desc=Rothlaigh do PDFanna go héasca.
|
||||||
rotate.tags=taobh freastalaí
|
rotate.tags=taobh freastalaí
|
||||||
|
|
||||||
|
|
||||||
@@ -327,13 +337,13 @@ compressPdfs.tags=squish, beag, beag bídeach
|
|||||||
|
|
||||||
home.changeMetadata.title=Athraigh Meiteashonraí
|
home.changeMetadata.title=Athraigh Meiteashonraí
|
||||||
home.changeMetadata.desc=Athraigh/Bain/Cuir meiteashonraí ó dhoiciméad PDF
|
home.changeMetadata.desc=Athraigh/Bain/Cuir meiteashonraí ó dhoiciméad PDF
|
||||||
changeMetadata.tags=Title,author,date,creation,time,publisher,producer,stats
|
changeMetadata.tags=Teideal,údar, dáta, cruthú, am, foilsitheoir, léiritheoir, staitisticí
|
||||||
|
|
||||||
home.fileToPDF.title=Comhad a thiontú go PDF
|
home.fileToPDF.title=Comhad a thiontú go PDF
|
||||||
home.fileToPDF.desc=Tiontaigh beagnach aon chomhad go PDF (DOCX, PNG, XLS, PPT, TXT agus go leor eile)
|
home.fileToPDF.desc=Tiontaigh beagnach aon chomhad go PDF (DOCX, PNG, XLS, PPT, TXT agus go leor eile)
|
||||||
fileToPDF.tags=claochlú, formáid, doiciméad, pictiúr, sleamhnán, téacs, comhshó, oifig, docs, focal, excel, powerpoint
|
fileToPDF.tags=claochlú, formáid, doiciméad, pictiúr, sleamhnán, téacs, comhshó, oifig, docs, focal, excel, powerpoint
|
||||||
|
|
||||||
home.ocr.title=Scananna OCR / Glanta
|
home.ocr.title=OCR / Scananna glanta
|
||||||
home.ocr.desc=Scanann glantachán agus aimsíonn sé téacs ó íomhánna laistigh de PDF agus cuireann sé isteach arís é mar théacs.
|
home.ocr.desc=Scanann glantachán agus aimsíonn sé téacs ó íomhánna laistigh de PDF agus cuireann sé isteach arís é mar théacs.
|
||||||
ocr.tags=aithint, téacs, íomhá, scanadh, léamh, a aithint, a bhrath, in eagar
|
ocr.tags=aithint, téacs, íomhá, scanadh, léamh, a aithint, a bhrath, in eagar
|
||||||
|
|
||||||
@@ -452,9 +462,9 @@ home.MarkdownToPDF.title=Marcáil síos go PDF
|
|||||||
home.MarkdownToPDF.desc=Tiontaíonn aon chomhad Markdown go PDF
|
home.MarkdownToPDF.desc=Tiontaíonn aon chomhad Markdown go PDF
|
||||||
MarkdownToPDF.tags=marcáil, ábhar gréasáin, claochlú, tiontú
|
MarkdownToPDF.tags=marcáil, ábhar gréasáin, claochlú, tiontú
|
||||||
|
|
||||||
home.PDFToMarkdown.title=PDF to Markdown
|
home.PDFToMarkdown.title=PDF chuig Markdown
|
||||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
home.PDFToMarkdown.desc=Tiontaíonn PDF ar bith go Markdown
|
||||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
PDFToMarkdown.tags=marcáil, ábhar Gréasáin, claochlú, tiontú, md
|
||||||
|
|
||||||
home.getPdfInfo.title=Faigh GACH Eolas ar PDF
|
home.getPdfInfo.title=Faigh GACH Eolas ar PDF
|
||||||
home.getPdfInfo.desc=Grab aon fhaisnéis agus is féidir ar PDFs
|
home.getPdfInfo.desc=Grab aon fhaisnéis agus is féidir ar PDFs
|
||||||
@@ -479,9 +489,9 @@ home.autoRedact.title=Auto Redact
|
|||||||
home.autoRedact.desc=Auto Redacts (Blacks out) téacs i PDF bunaithe ar an téacs ionchuir
|
home.autoRedact.desc=Auto Redacts (Blacks out) téacs i PDF bunaithe ar an téacs ionchuir
|
||||||
autoRedact.tags=Dearg, Folaigh, dubh amach, dubh, marcóir, i bhfolach
|
autoRedact.tags=Dearg, Folaigh, dubh amach, dubh, marcóir, i bhfolach
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
home.redact.title=Athchóiriú de Láimh
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
home.redact.desc=Réiteann sé PDF bunaithe ar théacs roghnaithe, cruthanna tarraingthe agus/nó leathanaigh roghnaithe
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
redact.tags=Réiteach, Folaigh, dubh amach, dubh, marcóir, i bhfolach, lámhleabhar
|
||||||
|
|
||||||
home.tableExtraxt.title=Ó CSV go PDF
|
home.tableExtraxt.title=Ó CSV go PDF
|
||||||
home.tableExtraxt.desc=Sleachta Táblaí ó PDF agus é a thiontú go CSV
|
home.tableExtraxt.desc=Sleachta Táblaí ó PDF agus é a thiontú go CSV
|
||||||
@@ -514,37 +524,37 @@ home.BookToPDF.title=Leabhar a thiontú go PDF
|
|||||||
home.BookToPDF.desc=Tiontaíonn sé formáidí Leabhair/Comics go PDF ag baint úsáide as calibre
|
home.BookToPDF.desc=Tiontaíonn sé formáidí Leabhair/Comics go PDF ag baint úsáide as calibre
|
||||||
BookToPDF.tags=Leabhar, Comic, Calibre, Tiontaigh, manga, amazon, kindle, epub, mobi, azw3, docx, rtf, txt, html, lit, fb2, pdb, lrf
|
BookToPDF.tags=Leabhar, Comic, Calibre, Tiontaigh, manga, amazon, kindle, epub, mobi, azw3, docx, rtf, txt, html, lit, fb2, pdb, lrf
|
||||||
|
|
||||||
home.removeImagePdf.title=Remove image
|
home.removeImagePdf.title=Bain íomhá
|
||||||
home.removeImagePdf.desc=Remove image from PDF to reduce file size
|
home.removeImagePdf.desc=Bain íomhá de PDF chun méid comhaid a laghdú
|
||||||
removeImagePdf.tags=Remove Image,Page operations,Back end,server side
|
removeImagePdf.tags=Bain Íomhá, Oibríochtaí Leathanaigh, Cúl, taobh an fhreastalaí
|
||||||
|
|
||||||
|
|
||||||
home.splitPdfByChapters.title=Split PDF by Chapters
|
home.splitPdfByChapters.title=Scoil PDF ar Chaibidlí
|
||||||
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
|
home.splitPdfByChapters.desc=Scoilt PDF ina chomhaid iolracha bunaithe ar a struchtúr caibidle.
|
||||||
splitPdfByChapters.tags=split,chapters,bookmarks,organize
|
splitPdfByChapters.tags=scoilt, caibidlí, leabharmharcanna, eagraigh
|
||||||
|
|
||||||
home.validateSignature.title=Validate PDF Signature
|
home.validateSignature.title=Bailíochtaigh Síniú PDF
|
||||||
home.validateSignature.desc=Verify digital signatures and certificates in PDF documents
|
home.validateSignature.desc=Fíoraigh sínithe digiteacha agus teastais i gcáipéisí PDF
|
||||||
validateSignature.tags=signature,verify,validate,pdf,certificate,digital signature,Validate Signature,Validate certificate
|
validateSignature.tags=síniú, fíoraigh, deimhnigh, pdf, teastas, síniú digiteach, Síniú Bailíochtaigh, Bailíochtaigh teastas
|
||||||
|
|
||||||
#replace-invert-color
|
#replace-invert-color
|
||||||
replace-color.title=Replace-Invert-Color
|
replace-color.title=Athchuir-Inbhéartaigh-Dath
|
||||||
replace-color.header=Replace-Invert Color PDF
|
replace-color.header=Athchuir-Inbhéartaigh Dath PDF
|
||||||
home.replaceColorPdf.title=Replace and Invert Color
|
home.replaceColorPdf.title=Athchuir agus Inbhéartaigh Dath
|
||||||
home.replaceColorPdf.desc=Replace color for text and background in PDF and invert full color of pdf to reduce file size
|
home.replaceColorPdf.desc=Athchuir dath an téacs agus an chúlra i bhformáid PDF agus inbhéartaigh dath iomlán pdf chun méid comhaid a laghdú
|
||||||
replaceColorPdf.tags=Replace Color,Page operations,Back end,server side
|
replaceColorPdf.tags=Athchuir Dath,Oibríochtaí Leathanaigh,Cúl,taobh an fhreastalaí
|
||||||
replace-color.selectText.1=Replace or Invert color Options
|
replace-color.selectText.1=Athchuir nó Inbhéartaigh Roghanna datha
|
||||||
replace-color.selectText.2=Default(Default high contrast colors)
|
replace-color.selectText.2=Réamhshocrú(Réamhshocrú dathanna ardchodarsnachta)
|
||||||
replace-color.selectText.3=Custom(Customized colors)
|
replace-color.selectText.3=Saincheaptha(dathanna saincheaptha)
|
||||||
replace-color.selectText.4=Full-Invert(Invert all colors)
|
replace-color.selectText.4=Iompaithe Lán(Inbhéartaigh gach dath)
|
||||||
replace-color.selectText.5=High contrast color options
|
replace-color.selectText.5=Roghanna dathanna ardchodarsnachta
|
||||||
replace-color.selectText.6=white text on black background
|
replace-color.selectText.6=téacs bán ar chúlra dubh
|
||||||
replace-color.selectText.7=Black text on white background
|
replace-color.selectText.7=Téacs dubh ar chúlra bán
|
||||||
replace-color.selectText.8=Yellow text on black background
|
replace-color.selectText.8=Téacs buí ar chúlra dubh
|
||||||
replace-color.selectText.9=Green text on black background
|
replace-color.selectText.9=Téacs glas ar chúlra dubh
|
||||||
replace-color.selectText.10=Choose text Color
|
replace-color.selectText.10=Roghnaigh Dath an téacs
|
||||||
replace-color.selectText.11=Choose background Color
|
replace-color.selectText.11=Roghnaigh Dath an Chúlra
|
||||||
replace-color.submit=Replace
|
replace-color.submit=Ionadaigh
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -563,18 +573,18 @@ login.locked=Tá do chuntas glasáilte.
|
|||||||
login.signinTitle=Sínigh isteach le do thoil
|
login.signinTitle=Sínigh isteach le do thoil
|
||||||
login.ssoSignIn=Logáil isteach trí Chlárú Aonair
|
login.ssoSignIn=Logáil isteach trí Chlárú Aonair
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 Uath-Chruthaigh Úsáideoir faoi Mhíchumas
|
login.oauth2AutoCreateDisabled=OAUTH2 Uath-Chruthaigh Úsáideoir faoi Mhíchumas
|
||||||
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
login.oauth2AdminBlockedUser=Tá bac faoi láthair ar chlárú nó logáil isteach úsáideoirí neamhchláraithe. Déan teagmháil leis an riarthóir le do thoil.
|
||||||
login.oauth2RequestNotFound=Níor aimsíodh iarratas údaraithe
|
login.oauth2RequestNotFound=Níor aimsíodh iarratas údaraithe
|
||||||
login.oauth2InvalidUserInfoResponse=Freagra Neamhbhailí Faisnéise Úsáideora
|
login.oauth2InvalidUserInfoResponse=Freagra Neamhbhailí Faisnéise Úsáideora
|
||||||
login.oauth2invalidRequest=Iarratas Neamhbhailí
|
login.oauth2invalidRequest=Iarratas Neamhbhailí
|
||||||
login.oauth2AccessDenied=Rochtain Diúltaithe
|
login.oauth2AccessDenied=Rochtain Diúltaithe
|
||||||
login.oauth2InvalidTokenResponse=Freagra Comhartha Neamhbhailí
|
login.oauth2InvalidTokenResponse=Freagra Comhartha Neamhbhailí
|
||||||
login.oauth2InvalidIdToken=Comhartha Aitheantais Neamhbhailí
|
login.oauth2InvalidIdToken=Comhartha Aitheantais Neamhbhailí
|
||||||
login.relyingPartyRegistrationNotFound=No relying party registration found
|
login.relyingPartyRegistrationNotFound=Níor aimsíodh clárú páirtí spleách
|
||||||
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
|
login.userIsDisabled=Úsáideoir díghníomhachtaithe, tá bac ar logáil isteach leis an ainm úsáideora seo faoi láthair. Déan teagmháil leis an riarthóir le do thoil.
|
||||||
login.alreadyLoggedIn=You are already logged in to
|
login.alreadyLoggedIn=Tá tú logáilte isteach cheana
|
||||||
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
|
login.alreadyLoggedIn2=gléasanna. Logáil amach as na gléasanna agus bain triail eile as.
|
||||||
login.toManySessions=You have too many active sessions
|
login.toManySessions=Tá an iomarca seisiún gníomhach agat
|
||||||
|
|
||||||
#auto-redact
|
#auto-redact
|
||||||
autoRedact.title=Auto Redact
|
autoRedact.title=Auto Redact
|
||||||
@@ -589,35 +599,36 @@ autoRedact.convertPDFToImageLabel=Tiontaigh PDF go PDF-Image (Úsáidte chun té
|
|||||||
autoRedact.submitButton=Cuir isteach
|
autoRedact.submitButton=Cuir isteach
|
||||||
|
|
||||||
#redact
|
#redact
|
||||||
redact.title=Manual Redaction
|
redact.title=Athchóiriú de Láimh
|
||||||
redact.header=Manual Redaction
|
redact.header=Athchóiriú de Láimh
|
||||||
redact.submit=Redact
|
redact.submit=Réiteach
|
||||||
redact.textBasedRedaction=Text based Redaction
|
redact.textBasedRedaction=Athrú Téacsbhunaithe
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
redact.pageBasedRedaction=Athrú bunaithe ar Leathanaigh
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
redact.convertPDFToImageLabel=Tiontaigh PDF go PDF-Image (Úsáidte chun téacs a bhaint taobh thiar den bhosca)
|
||||||
redact.pageRedactionNumbers.title=Pages
|
redact.pageRedactionNumbers.title=Leathanaigh
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
redact.pageRedactionNumbers.placeholder=(m.sh. 1,2,8 nó 4,7,12-16 nó 2n-1)
|
||||||
redact.redactionColor.title=Redaction Color
|
redact.redactionColor.title=Dath Athbhreithnithe
|
||||||
redact.export=Export
|
redact.export=Easpórtáil
|
||||||
redact.upload=Upload
|
redact.upload=Uaslódáil
|
||||||
redact.boxRedaction=Box draw redaction
|
redact.boxRedaction=dearadh tarraingthe an bhosca
|
||||||
redact.zoom=Zoom
|
redact.zoom=Súmáil
|
||||||
redact.zoomIn=Zoom in
|
redact.zoomIn=Súmáil isteach
|
||||||
redact.zoomOut=Zoom out
|
redact.zoomOut=Súmáil amach
|
||||||
redact.nextPage=Next Page
|
redact.nextPage=An Chéad Leathanach Eile
|
||||||
redact.previousPage=Previous Page
|
redact.previousPage=Leathanach Roimhe Seo
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
redact.toggleSidebar=Scoránaigh an Barra Taoibh
|
||||||
redact.showThumbnails=Show Thumbnails
|
redact.showThumbnails=Taispeáin Mionsamhlacha
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
redact.showDocumentOutline=Taispeáin Imlíne an Doiciméid (cliceáil faoi dhó chun gach mír a leathnú/laghdú)
|
||||||
redact.showAttatchments=Show Attachments
|
redact.showAttatchments=Taispeáin Ceangaltáin
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
redact.showLayers=Taispeáin Sraitheanna (cliceáil faoi dhó chun gach sraith a athshocrú go dtí an staid réamhshocraithe)
|
||||||
redact.colourPicker=Colour Picker
|
redact.colourPicker=Roghnóir Dathanna
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
redact.findCurrentOutlineItem=Faigh imlíne reatha
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Taispeáin Javascript
|
showJS.title=Taispeáin Javascript
|
||||||
showJS.header=Taispeáin Javascript
|
showJS.header=Taispeáin Javascript
|
||||||
showJS.downloadJS=Íosluchtaigh leabhar javascript
|
showJS.downloadJS=Íosluchtaigh Javascript
|
||||||
showJS.submit=Taispeáin
|
showJS.submit=Taispeáin
|
||||||
|
|
||||||
|
|
||||||
@@ -650,9 +661,9 @@ MarkdownToPDF.credit=Úsáideann WeasyPrint
|
|||||||
|
|
||||||
|
|
||||||
#pdf-to-markdown
|
#pdf-to-markdown
|
||||||
PDFToMarkdown.title=PDF To Markdown
|
PDFToMarkdown.title=PDF Chuig Marcáil
|
||||||
PDFToMarkdown.header=PDF To Markdown
|
PDFToMarkdown.header=PDF Go Marcáil
|
||||||
PDFToMarkdown.submit=Convert
|
PDFToMarkdown.submit=Tiontaigh
|
||||||
|
|
||||||
|
|
||||||
#url-to-pdf
|
#url-to-pdf
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=Uaslódáil an comhad PDF mór scanta amháin agus lig
|
|||||||
autoSplitPDF.selectText.4=Déantar leathanaigh roinnteoirí a bhrath agus a bhaint go huathoibríoch, rud a ráthaíonn doiciméad deiridh néata.
|
autoSplitPDF.selectText.4=Déantar leathanaigh roinnteoirí a bhrath agus a bhaint go huathoibríoch, rud a ráthaíonn doiciméad deiridh néata.
|
||||||
autoSplitPDF.formPrompt=Cuir PDF isteach ina bhfuil roinnteoirí Leathanaigh Stirling-PDF:
|
autoSplitPDF.formPrompt=Cuir PDF isteach ina bhfuil roinnteoirí Leathanaigh Stirling-PDF:
|
||||||
autoSplitPDF.duplexMode=Mód Duplex (scanadh tosaigh agus cúil)
|
autoSplitPDF.duplexMode=Mód Duplex (scanadh tosaigh agus cúil)
|
||||||
autoSplitPDF.dividerDownload1=Íoslódáil 'Auto Scoilteoir Roinnteoir (íosmhéid).pdf'
|
|
||||||
autoSplitPDF.dividerDownload2=Íoslódáil 'Auto Splitter Divider (le treoracha).pdf'
|
autoSplitPDF.dividerDownload2=Íoslódáil 'Auto Splitter Divider (le treoracha).pdf'
|
||||||
autoSplitPDF.submit=Cuir isteach
|
autoSplitPDF.submit=Cuir isteach
|
||||||
|
|
||||||
@@ -779,7 +789,7 @@ pageLayout.submit=Cuir isteach
|
|||||||
scalePages.title=Coigeartaigh scála an leathanaigh
|
scalePages.title=Coigeartaigh scála an leathanaigh
|
||||||
scalePages.header=Coigeartaigh scála an leathanaigh
|
scalePages.header=Coigeartaigh scála an leathanaigh
|
||||||
scalePages.pageSize=Méid leathanach den doiciméad.
|
scalePages.pageSize=Méid leathanach den doiciméad.
|
||||||
scalePages.keepPageSize=Original Size
|
scalePages.keepPageSize=Méid Bunaidh
|
||||||
scalePages.scaleFactor=Leibhéal súmáil (barr) de leathanach.
|
scalePages.scaleFactor=Leibhéal súmáil (barr) de leathanach.
|
||||||
scalePages.submit=Cuir isteach
|
scalePages.submit=Cuir isteach
|
||||||
|
|
||||||
@@ -799,7 +809,7 @@ certSign.showSig=Taispeáin Síniú
|
|||||||
certSign.reason=Cúis
|
certSign.reason=Cúis
|
||||||
certSign.location=Suíomh
|
certSign.location=Suíomh
|
||||||
certSign.name=Ainm
|
certSign.name=Ainm
|
||||||
certSign.showLogo=Show Logo
|
certSign.showLogo=Taispeáin Lógó
|
||||||
certSign.submit=Sínigh PDF
|
certSign.submit=Sínigh PDF
|
||||||
|
|
||||||
|
|
||||||
@@ -834,9 +844,9 @@ compare.highlightColor.2=Dath Aibhsithe 2:
|
|||||||
compare.document.1=Doiciméad 1
|
compare.document.1=Doiciméad 1
|
||||||
compare.document.2=Doiciméad 2
|
compare.document.2=Doiciméad 2
|
||||||
compare.submit=Déan comparáid idir
|
compare.submit=Déan comparáid idir
|
||||||
compare.complex.message=One or both of the provided documents are large files, accuracy of comparison may be reduced
|
compare.complex.message=Is comhaid mhóra ceann amháin nó an dá cheann de na doiciméid a soláthraíodh, d'fhéadfaí cruinneas na comparáide a laghdú
|
||||||
compare.large.file.message=One or Both of the provided documents are too large to process
|
compare.large.file.message=Tá ceann amháin de na doiciméid nó an dá cheann rómhór le próiseáil
|
||||||
compare.no.text.message=One or both of the selected PDFs have no text content. Please choose PDFs with text for comparison.
|
compare.no.text.message=Níl aon ábhar téacs i gceann amháin nó sa dá cheann de na PDF roghnaithe. Roghnaigh PDF le do thoil le téacs chun comparáid a dhéanamh.
|
||||||
|
|
||||||
#BookToPDF
|
#BookToPDF
|
||||||
BookToPDF.title=Leabhair agus comics a PDF
|
BookToPDF.title=Leabhair agus comics a PDF
|
||||||
@@ -859,18 +869,18 @@ sign.draw=Tarraing Síniú
|
|||||||
sign.text=Ionchur Téacs
|
sign.text=Ionchur Téacs
|
||||||
sign.clear=Glan
|
sign.clear=Glan
|
||||||
sign.add=Cuir
|
sign.add=Cuir
|
||||||
sign.saved=Saved Signatures
|
sign.saved=Sínithe Sínithe
|
||||||
sign.save=Save Signature
|
sign.save=Sábháil an Síniú
|
||||||
sign.personalSigs=Personal Signatures
|
sign.personalSigs=Sínithe Pearsanta
|
||||||
sign.sharedSigs=Shared Signatures
|
sign.sharedSigs=Sínithe Roinnte
|
||||||
sign.noSavedSigs=No saved signatures found
|
sign.noSavedSigs=Níor aimsíodh aon síniú sábháilte
|
||||||
sign.addToAll=Add to all pages
|
sign.addToAll=Cuir le gach leathanach
|
||||||
sign.delete=Delete
|
sign.delete=Scrios
|
||||||
sign.first=First page
|
sign.first=An chéad leathanach
|
||||||
sign.last=Last page
|
sign.last=An leathanach deiridh
|
||||||
sign.next=Next page
|
sign.next=An chéad leathanach eile
|
||||||
sign.previous=Previous page
|
sign.previous=Leathanach roimhe seo
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Scoránaigh, coinnigh an cóimheas gné
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
@@ -897,7 +907,7 @@ ScannerImageSplit.selectText.7=Íos-Limistéar Comhrianta:
|
|||||||
ScannerImageSplit.selectText.8=Socraíonn sé an tairseach íosta achar comhrianta le haghaidh grianghraf
|
ScannerImageSplit.selectText.8=Socraíonn sé an tairseach íosta achar comhrianta le haghaidh grianghraf
|
||||||
ScannerImageSplit.selectText.9=Méid na Teorann:
|
ScannerImageSplit.selectText.9=Méid na Teorann:
|
||||||
ScannerImageSplit.selectText.10=Socraíonn sé méid na teorann a chuirtear leis agus a bhaintear chun teorainneacha bán a chosc san aschur (réamhshocraithe: 1).
|
ScannerImageSplit.selectText.10=Socraíonn sé méid na teorann a chuirtear leis agus a bhaintear chun teorainneacha bán a chosc san aschur (réamhshocraithe: 1).
|
||||||
ScannerImageSplit.info=Python is not installed. It is required to run.
|
ScannerImageSplit.info=Níl Python suiteáilte. Tá sé ag teastáil a rith.
|
||||||
|
|
||||||
|
|
||||||
#OCR
|
#OCR
|
||||||
@@ -924,7 +934,7 @@ ocr.submit=Próiseáil PDF le OCR
|
|||||||
extractImages.title=Sliocht Íomhánna
|
extractImages.title=Sliocht Íomhánna
|
||||||
extractImages.header=Sliocht Íomhánna
|
extractImages.header=Sliocht Íomhánna
|
||||||
extractImages.selectText=Roghnaigh formáid íomhá chun íomhánna bainte a thiontú go
|
extractImages.selectText=Roghnaigh formáid íomhá chun íomhánna bainte a thiontú go
|
||||||
extractImages.allowDuplicates=Save duplicate images
|
extractImages.allowDuplicates=Sábháil íomhánna dúblacha
|
||||||
extractImages.submit=Sliocht
|
extractImages.submit=Sliocht
|
||||||
|
|
||||||
|
|
||||||
@@ -942,7 +952,7 @@ compress.title=Comhbhrúigh
|
|||||||
compress.header=Comhbhrúigh PDF
|
compress.header=Comhbhrúigh PDF
|
||||||
compress.credit=Úsáideann an tseirbhís seo qpdf le haghaidh Comhbhrú/Optimization PDF.
|
compress.credit=Úsáideann an tseirbhís seo qpdf le haghaidh Comhbhrú/Optimization PDF.
|
||||||
compress.selectText.1=Mód Láimhe - Ó 1 go 5
|
compress.selectText.1=Mód Láimhe - Ó 1 go 5
|
||||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
compress.selectText.1.1=I leibhéil optamaithe 6 go 9, chomh maith le comhbhrú ginearálta PDF, déantar réiteach íomhá a laghdú de réir scála chun méid comhaid a laghdú tuilleadh. Mar thoradh ar leibhéil níos airde tá comhbhrú íomhá níos láidre (suas le 50% den mhéid bunaidh), ag baint amach laghdú méide níos mó ach le caillteanas cáilíochta féideartha in íomhánna.
|
||||||
compress.selectText.2=Leibhéal optamaithe:
|
compress.selectText.2=Leibhéal optamaithe:
|
||||||
compress.selectText.3=4 (Uafásach le haghaidh íomhánna téacs)
|
compress.selectText.3=4 (Uafásach le haghaidh íomhánna téacs)
|
||||||
compress.selectText.4=Mód uathoibríoch - Coigeartaíonn Auto cáilíocht chun PDF a fháil go dtí an méid cruinn
|
compress.selectText.4=Mód uathoibríoch - Coigeartaíonn Auto cáilíocht chun PDF a fháil go dtí an méid cruinn
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=Bain Ar dtús
|
|||||||
pdfOrganiser.mode.8=Bain Last
|
pdfOrganiser.mode.8=Bain Last
|
||||||
pdfOrganiser.mode.9=Bain An Chéad agus an Deireadh
|
pdfOrganiser.mode.9=Bain An Chéad agus an Deireadh
|
||||||
pdfOrganiser.mode.10=Corr-Fiú Cumaisc
|
pdfOrganiser.mode.10=Corr-Fiú Cumaisc
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(m.sh. 1,3,2 nó 4-8,2,10-12 nó 2n-1)
|
pdfOrganiser.placeholder=(m.sh. 1,3,2 nó 4-8,2,10-12 nó 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -989,42 +1000,42 @@ pdfOrganiser.placeholder=(m.sh. 1,3,2 nó 4-8,2,10-12 nó 2n-1)
|
|||||||
multiTool.title=Il-uirlis PDF
|
multiTool.title=Il-uirlis PDF
|
||||||
multiTool.header=Il-uirlis PDF
|
multiTool.header=Il-uirlis PDF
|
||||||
multiTool.uploadPrompts=Ainm comhaid
|
multiTool.uploadPrompts=Ainm comhaid
|
||||||
multiTool.selectAll=Select All
|
multiTool.selectAll=Roghnaigh Uile
|
||||||
multiTool.deselectAll=Deselect All
|
multiTool.deselectAll=Díroghnaigh Uile
|
||||||
multiTool.selectPages=Page Select
|
multiTool.selectPages=Roghnaigh Leathanach
|
||||||
multiTool.selectedPages=Selected Pages
|
multiTool.selectedPages=Leathanaigh Roghnaithe
|
||||||
multiTool.page=Page
|
multiTool.page=Leathanach
|
||||||
multiTool.deleteSelected=Delete Selected
|
multiTool.deleteSelected=Scrios Roghnaithe
|
||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Easpórtáil
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Easpórtáil Roghnaithe
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
multiTool.insertPageBreak=Ionsáigh Sos Leathanaigh
|
||||||
multiTool.addFile=Add File
|
multiTool.addFile=Cuir Comhad Leis
|
||||||
multiTool.rotateLeft=Rotate Left
|
multiTool.rotateLeft=Rothlaigh ar Chlé
|
||||||
multiTool.rotateRight=Rotate Right
|
multiTool.rotateRight=Rothlaigh ar Dheis
|
||||||
multiTool.split=Split
|
multiTool.split=Scoil
|
||||||
multiTool.moveLeft=Move Left
|
multiTool.moveLeft=Bog ar Chlé
|
||||||
multiTool.moveRight=Move Right
|
multiTool.moveRight=Bog ar Dheis
|
||||||
multiTool.delete=Delete
|
multiTool.delete=Scrios
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
multiTool.dragDropMessage=Leathanach(leathanaigh) roghnaithe
|
||||||
multiTool.undo=Undo
|
multiTool.undo=Cealaigh
|
||||||
multiTool.redo=Redo
|
multiTool.redo=Athdhéan
|
||||||
|
|
||||||
#decrypt
|
#decrypt
|
||||||
decrypt.passwordPrompt=This file is password-protected. Please enter the password:
|
decrypt.passwordPrompt=Tá an comhad seo cosanta ag pasfhocal. Cuir isteach an pasfhocal le do thoil:
|
||||||
decrypt.cancelled=Operation cancelled for PDF: {0}
|
decrypt.cancelled=Cealaíodh an oibríocht le haghaidh PDF: {0}
|
||||||
decrypt.noPassword=No password provided for encrypted PDF: {0}
|
decrypt.noPassword=Níor soláthraíodh focal faire don PDF criptithe: {0}
|
||||||
decrypt.invalidPassword=Please try again with the correct password.
|
decrypt.invalidPassword=Déan iarracht eile leis an bhfocal faire ceart.
|
||||||
decrypt.invalidPasswordHeader=Incorrect password or unsupported encryption for PDF: {0}
|
decrypt.invalidPasswordHeader=Focal faire mícheart nó criptiúchán PDF nach dtacaítear leis: {0}
|
||||||
decrypt.unexpectedError=There was an error processing the file. Please try again.
|
decrypt.unexpectedError=Tharla earráid agus an comhad á phróiseáil. Bain triail eile as.
|
||||||
decrypt.serverError=Server error while decrypting: {0}
|
decrypt.serverError=Earráid fhreastalaí agus é díchriptiú: {0}
|
||||||
decrypt.success=File decrypted successfully.
|
decrypt.success=D'éirigh le díchriptiú an chomhaid.
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=Tá an ghné seo ar fáil inár <a href="{0}">leathanach il-uirlisí</a> freisin. Seiceáil é le haghaidh Chomhéadain leathanach ar leathanach feabhsaithe agus gnéithe breise!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=Féach PDF
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=Féach PDF
|
viewPdf.header=Féach PDF
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1083,7 +1094,7 @@ pdfToImage.color=Dath
|
|||||||
pdfToImage.grey=Scála Liath
|
pdfToImage.grey=Scála Liath
|
||||||
pdfToImage.blackwhite=Dubh agus Bán (D’fhéadfadh sonraí a chailleadh!)
|
pdfToImage.blackwhite=Dubh agus Bán (D’fhéadfadh sonraí a chailleadh!)
|
||||||
pdfToImage.submit=Tiontaigh
|
pdfToImage.submit=Tiontaigh
|
||||||
pdfToImage.info=Python is not installed. Required for WebP conversion.
|
pdfToImage.info=Níl Python suiteáilte. Ag teastáil le haghaidh comhshó WebP.
|
||||||
pdfToImage.placeholder=(m.sh. 1,2,8 nó 4,7,12-16 nó 2n-1)
|
pdfToImage.placeholder=(m.sh. 1,2,8 nó 4,7,12-16 nó 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1117,12 +1128,12 @@ watermark.selectText.1=Roghnaigh PDF chun comhartha uisce a chur leis:
|
|||||||
watermark.selectText.2=Téacs Comhartha Uisce:
|
watermark.selectText.2=Téacs Comhartha Uisce:
|
||||||
watermark.selectText.3=Méid cló:
|
watermark.selectText.3=Méid cló:
|
||||||
watermark.selectText.4=Rothlú (0-360):
|
watermark.selectText.4=Rothlú (0-360):
|
||||||
watermark.selectText.5=Width Spacer (Spás idir gach comhartha uisce go cothrománach):
|
watermark.selectText.5=Spásaire Leithead (Spás idir gach comhartha uisce go cothrománach):
|
||||||
watermark.selectText.6=spásaire airde (Spás idir gach comhartha uisce go hingearach):
|
watermark.selectText.6=Spásaire Airde (Spás idir gach comhartha uisce go hingearach):
|
||||||
watermark.selectText.7=Teimhneacht (0% - 100%):
|
watermark.selectText.7=Teimhneacht (0% - 100%):
|
||||||
watermark.selectText.8=Cineál Comhartha Uisce:
|
watermark.selectText.8=Cineál Comhartha Uisce:
|
||||||
watermark.selectText.9=Íomhá Comhartha Uisce:
|
watermark.selectText.9=Íomhá Comhartha Uisce:
|
||||||
watermark.selectText.10=Convert PDF to PDF-Image
|
watermark.selectText.10=Tiontaigh PDF go PDF-Íomhá
|
||||||
watermark.submit=Cuir Uisce leis
|
watermark.submit=Cuir Uisce leis
|
||||||
watermark.type.1=Téacs
|
watermark.type.1=Téacs
|
||||||
watermark.type.2=Íomha
|
watermark.type.2=Íomha
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=Athrú
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF Go PDF/A
|
pdfToPDFA.title=PDF Go PDF/A
|
||||||
pdfToPDFA.header=PDF Go PDF/A
|
pdfToPDFA.header=PDF Go PDF/A
|
||||||
pdfToPDFA.credit=Úsáideann an tseirbhís seo qpdf chun PDF/A a thiontú
|
pdfToPDFA.credit=Úsáideann an tseirbhís seo libreoffice chun PDF/A a thiontú
|
||||||
pdfToPDFA.submit=Tiontaigh
|
pdfToPDFA.submit=Tiontaigh
|
||||||
pdfToPDFA.tip=Faoi láthair ní oibríonn sé le haghaidh ionchuir iolracha ag an am céanna
|
pdfToPDFA.tip=Faoi láthair ní oibríonn sé le haghaidh ionchuir iolracha ag an am céanna
|
||||||
pdfToPDFA.outputFormat=Formáid aschuir
|
pdfToPDFA.outputFormat=Formáid aschuir
|
||||||
@@ -1284,8 +1295,8 @@ licenses.license=Ceadúnas
|
|||||||
survey.nav=Suirbhé
|
survey.nav=Suirbhé
|
||||||
survey.title=Suirbhé Stirling-PDF
|
survey.title=Suirbhé Stirling-PDF
|
||||||
survey.description=Níl aon rian ar Stirling-PDF agus mar sin ba mhaith linn cloisteáil ónár n-úsáideoirí chun feabhas a chur ar Stirling-PDF!
|
survey.description=Níl aon rian ar Stirling-PDF agus mar sin ba mhaith linn cloisteáil ónár n-úsáideoirí chun feabhas a chur ar Stirling-PDF!
|
||||||
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
|
survey.changes=Tá Stirling-PDF athraithe ón suirbhé deireanach! Le tuilleadh a fháil amach féach ar ár mblagphost anseo:
|
||||||
survey.changes2=With these changes we are getting paid business support and funding
|
survey.changes2=De bharr na n-athruithe seo táimid ag fáil tacaíochta gnó agus maoiniú íoctha
|
||||||
survey.please=Smaoinigh ar ár suirbhé a dhéanamh le do thoil!
|
survey.please=Smaoinigh ar ár suirbhé a dhéanamh le do thoil!
|
||||||
survey.disabled=(Díchumasófar aníos an tsuirbhé sna nuashonruithe seo a leanas ach beidh siad ar fáil ag bun an leathanaigh)
|
survey.disabled=(Díchumasófar aníos an tsuirbhé sna nuashonruithe seo a leanas ach beidh siad ar fáil ag bun an leathanaigh)
|
||||||
survey.button=Tóg Suirbhé
|
survey.button=Tóg Suirbhé
|
||||||
@@ -1307,69 +1318,69 @@ error.discordSubmit=Discord - Cuir post Tacaíochta
|
|||||||
|
|
||||||
|
|
||||||
#remove-image
|
#remove-image
|
||||||
removeImage.title=Remove image
|
removeImage.title=Bain íomhá
|
||||||
removeImage.header=Remove image
|
removeImage.header=Bain íomhá
|
||||||
removeImage.removeImage=Remove image
|
removeImage.removeImage=Bain íomhá
|
||||||
removeImage.submit=Remove image
|
removeImage.submit=Bain íomhá
|
||||||
|
|
||||||
|
|
||||||
splitByChapters.title=Split PDF by Chapters
|
splitByChapters.title=Scoil PDF de réir Caibidlí
|
||||||
splitByChapters.header=Split PDF by Chapters
|
splitByChapters.header=Scoil PDF de réir Caibidlí
|
||||||
splitByChapters.bookmarkLevel=Bookmark Level
|
splitByChapters.bookmarkLevel=Leibhéal Leabharmharc
|
||||||
splitByChapters.includeMetadata=Include Metadata
|
splitByChapters.includeMetadata=Cuir meiteashonraí san áireamh
|
||||||
splitByChapters.allowDuplicates=Allow Duplicates
|
splitByChapters.allowDuplicates=Ceadaigh do Dhúblaigh
|
||||||
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
|
splitByChapters.desc.1=Scann an uirlis seo comhad PDF ina PDFanna iolracha bunaithe ar a struchtúr caibidle.
|
||||||
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
|
splitByChapters.desc.2=Leibhéal Leabharmharc: Roghnaigh leibhéal na leabharmharcanna le húsáid don scoilteadh (0 don bharrleibhéal, 1 don dara leibhéal, etc.).
|
||||||
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
|
splitByChapters.desc.3=Cuir Meiteashonraí san áireamh: Má dhéantar iad a sheiceáil, cuirfear meiteashonraí an PDF bhunaidh san áireamh i ngach PDF scoilte.
|
||||||
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
|
splitByChapters.desc.4=Ceadaigh do Dhúblaigh: Má dhéantar iad a sheiceáil, ceadaítear go leor leabharmharcanna ar an leathanach céanna chun PDFanna ar leith a chruthú.
|
||||||
splitByChapters.submit=Split PDF
|
splitByChapters.submit=Scoil PDF
|
||||||
|
|
||||||
#File Chooser
|
#File Chooser
|
||||||
fileChooser.click=Click
|
fileChooser.click=Cliceáil
|
||||||
fileChooser.or=or
|
fileChooser.or=nó
|
||||||
fileChooser.dragAndDrop=Drag & Drop
|
fileChooser.dragAndDrop=Tarraing & Scaoil
|
||||||
fileChooser.dragAndDropPDF=Drag & Drop PDF file
|
fileChooser.dragAndDropPDF=Tarraing & Scaoil comhad PDF
|
||||||
fileChooser.dragAndDropImage=Drag & Drop Image file
|
fileChooser.dragAndDropImage=Tarraing & Scaoil comhad Íomhá
|
||||||
fileChooser.hoveredDragAndDrop=Drag & Drop file(s) here
|
fileChooser.hoveredDragAndDrop=Tarraing agus scaoil comhad(í) anseo
|
||||||
|
|
||||||
#release notes
|
#release notes
|
||||||
releases.footer=Releases
|
releases.footer=Eisiúintí
|
||||||
releases.title=Release Notes
|
releases.title=Nótaí Eisiúna
|
||||||
releases.header=Release Notes
|
releases.header=Nótaí Eisiúna
|
||||||
releases.current.version=Current Release
|
releases.current.version=Eisiúna Reatha
|
||||||
releases.note=Release notes are only available in English
|
releases.note=Tá nótaí eisiúna ar fáil i mBéarla amháin
|
||||||
|
|
||||||
#Validate Signature
|
#Validate Signature
|
||||||
validateSignature.title=Validate PDF Signatures
|
validateSignature.title=Bailíochtaigh Sínithe PDF
|
||||||
validateSignature.header=Validate Digital Signatures
|
validateSignature.header=Bailíochtaigh Sínithe Digiteacha
|
||||||
validateSignature.selectPDF=Select signed PDF file
|
validateSignature.selectPDF=Roghnaigh comhad PDF sínithe
|
||||||
validateSignature.submit=Validate Signatures
|
validateSignature.submit=Bailíochtaigh Sínithe
|
||||||
validateSignature.results=Validation Results
|
validateSignature.results=Torthaí Bailíochtaithe
|
||||||
validateSignature.status=Status
|
validateSignature.status=Stádas
|
||||||
validateSignature.signer=Signer
|
validateSignature.signer=Sínitheoir
|
||||||
validateSignature.date=Date
|
validateSignature.date=Dáta
|
||||||
validateSignature.reason=Reason
|
validateSignature.reason=Cúis
|
||||||
validateSignature.location=Location
|
validateSignature.location=Suíomh
|
||||||
validateSignature.noSignatures=No digital signatures found in this document
|
validateSignature.noSignatures=Níor aimsíodh síniú digiteach ar bith sa doiciméad seo
|
||||||
validateSignature.status.valid=Valid
|
validateSignature.status.valid=Bailí
|
||||||
validateSignature.status.invalid=Invalid
|
validateSignature.status.invalid=Neamhbhailí
|
||||||
validateSignature.chain.invalid=Certificate chain validation failed - cannot verify signer's identity
|
validateSignature.chain.invalid=Theip ar bhailíochtú slabhra an teastais - ní féidir aitheantas an tsínitheora a fhíorú
|
||||||
validateSignature.trust.invalid=Certificate not in trust store - source cannot be verified
|
validateSignature.trust.invalid=Níl an teastas sa stór muiníne - ní féidir an fhoinse a fhíorú
|
||||||
validateSignature.cert.expired=Certificate has expired
|
validateSignature.cert.expired=Tá an teastas imithe in éag
|
||||||
validateSignature.cert.revoked=Certificate has been revoked
|
validateSignature.cert.revoked=Tá an teastas cúlghairthe
|
||||||
validateSignature.signature.info=Signature Information
|
validateSignature.signature.info=Eolas Sínithe
|
||||||
validateSignature.signature=Signature
|
validateSignature.signature=Síniú
|
||||||
validateSignature.signature.mathValid=Signature is mathematically valid BUT:
|
validateSignature.signature.mathValid=Tá an síniú bailí go matamaiticiúil ACH:
|
||||||
validateSignature.selectCustomCert=Custom Certificate File X.509 (Optional)
|
validateSignature.selectCustomCert=Comhad Teastais Saincheaptha X.509 (Roghnach)
|
||||||
validateSignature.cert.info=Certificate Details
|
validateSignature.cert.info=Sonraí an Teastais
|
||||||
validateSignature.cert.issuer=Issuer
|
validateSignature.cert.issuer=Eisitheoir
|
||||||
validateSignature.cert.subject=Subject
|
validateSignature.cert.subject=Ábhar
|
||||||
validateSignature.cert.serialNumber=Serial Number
|
validateSignature.cert.serialNumber=Sraithuimhir
|
||||||
validateSignature.cert.validFrom=Valid From
|
validateSignature.cert.validFrom=Bailí Ó
|
||||||
validateSignature.cert.validUntil=Valid Until
|
validateSignature.cert.validUntil=Bailí Go dtí
|
||||||
validateSignature.cert.algorithm=Algorithm
|
validateSignature.cert.algorithm=Algartam
|
||||||
validateSignature.cert.keySize=Key Size
|
validateSignature.cert.keySize=Méid na hEochrach
|
||||||
validateSignature.cert.version=Version
|
validateSignature.cert.version=Leagan
|
||||||
validateSignature.cert.keyUsage=Key Usage
|
validateSignature.cert.keyUsage=Úsáid Eochrach
|
||||||
validateSignature.cert.selfSigned=Self-Signed
|
validateSignature.cert.selfSigned=Féin-Sínithe
|
||||||
validateSignature.cert.bits=bits
|
validateSignature.cert.bits=giotáin
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=आप config/settings.yml फ़ाइल में वि
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=पसंदीदा
|
navbar.favorite=पसंदीदा
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=डार्क मोड
|
navbar.darkmode=डार्क मोड
|
||||||
navbar.language=भाषाएं
|
navbar.language=भाषाएं
|
||||||
navbar.settings=सेटिंग्स
|
navbar.settings=सेटिंग्स
|
||||||
@@ -261,10 +262,19 @@ home.desc=आपकी सभी PDF आवश्यकताओं के ल
|
|||||||
home.searchBar=सुविधाएं खोजें...
|
home.searchBar=सुविधाएं खोजें...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=PDF देखें
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=देखें, टिप्पणी करें, टेक्स्ट या छवियां जोड़ें
|
home.viewPdf.desc=देखें, टिप्पणी करें, टेक्स्ट या छवियां जोड़ें
|
||||||
viewPdf.tags=देखें,पढ़ें,टिप्पणी,टेक्स्ट,छवि
|
viewPdf.tags=देखें,पढ़ें,टिप्पणी,टेक्स्ट,छवि
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF मल्टी टूल
|
home.multiTool.title=PDF मल्टी टूल
|
||||||
home.multiTool.desc=मर्ज करें, घुमाएं, पुनर्व्यवस्थित करें और पृष्ठ हटाएं
|
home.multiTool.desc=मर्ज करें, घुमाएं, पुनर्व्यवस्थित करें और पृष्ठ हटाएं
|
||||||
multiTool.tags=मल्टी टूल,मल्टी ऑपरेशन,UI,क्लिक ड्रैग,फ्रंट एंड,क्लाइंट साइड,इंटरैक्टिव,इंटरैक्टेबल,मूव,डिलीट,माइग्रेट,डिवाइड
|
multiTool.tags=मल्टी टूल,मल्टी ऑपरेशन,UI,क्लिक ड्रैग,फ्रंट एंड,क्लाइंट साइड,इंटरैक्टिव,इंटरैक्टेबल,मूव,डिलीट,माइग्रेट,डिवाइड
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=अटैचमेंट दिखाएं
|
|||||||
redact.showLayers=लेयर्स दिखाएं (सभी लेयर्स को डिफ़ॉल्ट स्थिति में रीसेट करने के लिए डबल-क्लिक करें)
|
redact.showLayers=लेयर्स दिखाएं (सभी लेयर्स को डिफ़ॉल्ट स्थिति में रीसेट करने के लिए डबल-क्लिक करें)
|
||||||
redact.colourPicker=रंग चयनकर्ता
|
redact.colourPicker=रंग चयनकर्ता
|
||||||
redact.findCurrentOutlineItem=वर्तमान आउटलाइन आइटम खोजें
|
redact.findCurrentOutlineItem=वर्तमान आउटलाइन आइटम खोजें
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=जावास्क्रिप्ट दिखाएं
|
showJS.title=जावास्क्रिप्ट दिखाएं
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=एक बड़ी स्कैन की गई PDF
|
|||||||
autoSplitPDF.selectText.4=विभाजक पृष्ठ स्वचालित रूप से पहचाने जाते हैं और हटा दिए जाते हैं, एक साफ अंतिम दस्तावेज़ सुनिश्चित करते हैं।
|
autoSplitPDF.selectText.4=विभाजक पृष्ठ स्वचालित रूप से पहचाने जाते हैं और हटा दिए जाते हैं, एक साफ अंतिम दस्तावेज़ सुनिश्चित करते हैं।
|
||||||
autoSplitPDF.formPrompt=Stirling-PDF पृष्ठ विभाजक वाली PDF जमा करें:
|
autoSplitPDF.formPrompt=Stirling-PDF पृष्ठ विभाजक वाली PDF जमा करें:
|
||||||
autoSplitPDF.duplexMode=डुप्लेक्स मोड (सामने और पीछे स्कैनिंग)
|
autoSplitPDF.duplexMode=डुप्लेक्स मोड (सामने और पीछे स्कैनिंग)
|
||||||
autoSplitPDF.dividerDownload1='स्वतः विभाजक (न्यूनतम).pdf' डाउनलोड करें
|
|
||||||
autoSplitPDF.dividerDownload2='स्वतः विभाजक (निर्देशों के साथ).pdf' डाउनलोड करें
|
autoSplitPDF.dividerDownload2='स्वतः विभाजक (निर्देशों के साथ).pdf' डाउनलोड करें
|
||||||
autoSplitPDF.submit=जमा करें
|
autoSplitPDF.submit=जमा करें
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=प्रथम हटाएं
|
|||||||
pdfOrganiser.mode.8=अंतिम हटाएं
|
pdfOrganiser.mode.8=अंतिम हटाएं
|
||||||
pdfOrganiser.mode.9=प्रथम और अंतिम हटाएं
|
pdfOrganiser.mode.9=प्रथम और अंतिम हटाएं
|
||||||
pdfOrganiser.mode.10=विषम-सम मर्ज
|
pdfOrganiser.mode.10=विषम-सम मर्ज
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(जैसे 1,3,2 या 4-8,2,10-12 या 2n-1)
|
pdfOrganiser.placeholder=(जैसे 1,3,2 या 4-8,2,10-12 या 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=फ़ाइल सफलतापूर्वक डिक्
|
|||||||
multiTool-advert.message=यह सुविधा हमारे <a href="{0}">मल्टी-टूल पृष्ठ</a> में भी उपलब्ध है। बेहतर पृष्ठ-दर-पृष्ठ UI और अतिरिक्त सुविधाओं के लिए इसे देखें!
|
multiTool-advert.message=यह सुविधा हमारे <a href="{0}">मल्टी-टूल पृष्ठ</a> में भी उपलब्ध है। बेहतर पृष्ठ-दर-पृष्ठ UI और अतिरिक्त सुविधाओं के लिए इसे देखें!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=PDF देखें
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=PDF देखें
|
viewPdf.header=PDF देखें
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=बदलें
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF से PDF/A
|
pdfToPDFA.title=PDF से PDF/A
|
||||||
pdfToPDFA.header=PDF से PDF/A
|
pdfToPDFA.header=PDF से PDF/A
|
||||||
pdfToPDFA.credit=यह सेवा PDF/A रूपांतरण के लिए qpdf का उपयोग करती है
|
pdfToPDFA.credit=यह सेवा PDF/A रूपांतरण के लिए libreoffice का उपयोग करती है
|
||||||
pdfToPDFA.submit=बदलें
|
pdfToPDFA.submit=बदलें
|
||||||
pdfToPDFA.tip=वर्तमान में एक बार में कई इनपुट के लिए काम नहीं करता
|
pdfToPDFA.tip=वर्तमान में एक बार में कई इनपुट के लिए काम नहीं करता
|
||||||
pdfToPDFA.outputFormat=आउटपुट प्रारूप
|
pdfToPDFA.outputFormat=आउटपुट प्रारूप
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=Možete promijeniti postavke za analitike u datoteci config/s
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Favoriti
|
navbar.favorite=Favoriti
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=Tamni Način Rada
|
navbar.darkmode=Tamni Način Rada
|
||||||
navbar.language=Jezici
|
navbar.language=Jezici
|
||||||
navbar.settings=Postavke
|
navbar.settings=Postavke
|
||||||
@@ -261,10 +262,19 @@ home.desc=Sve na jednom mjestu za sve vaše PDF potrebe.
|
|||||||
home.searchBar=Pretraži funkcije...
|
home.searchBar=Pretraži funkcije...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=Pregledaj PDF
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=Pregledaj, komentiraj, dodaj tekst ili slike
|
home.viewPdf.desc=Pregledaj, komentiraj, dodaj tekst ili slike
|
||||||
viewPdf.tags=pregled,čitanje,komentiranje,tekst,slika
|
viewPdf.tags=pregled,čitanje,komentiranje,tekst,slika
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Višestruki alat
|
home.multiTool.title=PDF Višestruki alat
|
||||||
home.multiTool.desc=Spajanje, rotiranje, preuređivanje i uklanjanje stranica
|
home.multiTool.desc=Spajanje, rotiranje, preuređivanje i uklanjanje stranica
|
||||||
multiTool.tags=Višestruki alat, više operacija, korisničko sučelje, povlačenje klikom, prednji kraj, strana klijenta, interaktivno, nepopravljivo, pomicanje
|
multiTool.tags=Višestruki alat, više operacija, korisničko sučelje, povlačenje klikom, prednji kraj, strana klijenta, interaktivno, nepopravljivo, pomicanje
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Show Attachments
|
|||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
||||||
redact.colourPicker=Colour Picker
|
redact.colourPicker=Colour Picker
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
redact.findCurrentOutlineItem=Find current outline item
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Prikaži Javascript
|
showJS.title=Prikaži Javascript
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=Prenesite jednu veliku skeniranu PDF datoteku i pustit
|
|||||||
autoSplitPDF.selectText.4=Razdjelne stranice automatski se otkrivaju i uklanjaju, jamčeći uredan konačni dokument.
|
autoSplitPDF.selectText.4=Razdjelne stranice automatski se otkrivaju i uklanjaju, jamčeći uredan konačni dokument.
|
||||||
autoSplitPDF.formPrompt=Pošaljite PDF koji sadrži naše razdjelnike stranica:
|
autoSplitPDF.formPrompt=Pošaljite PDF koji sadrži naše razdjelnike stranica:
|
||||||
autoSplitPDF.duplexMode=Obostrani način rada (skeniranje s prednje i stražnje strane)
|
autoSplitPDF.duplexMode=Obostrani način rada (skeniranje s prednje i stražnje strane)
|
||||||
autoSplitPDF.dividerDownload1=Preuzmite 'Auto Splitter Divider (minimalan).pdf'
|
|
||||||
autoSplitPDF.dividerDownload2=Preuzmite 'Auto Splitter Divider (s uputama).pdf'
|
autoSplitPDF.dividerDownload2=Preuzmite 'Auto Splitter Divider (s uputama).pdf'
|
||||||
autoSplitPDF.submit=Potvrdi
|
autoSplitPDF.submit=Potvrdi
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=Ukloni Prvu
|
|||||||
pdfOrganiser.mode.8=Ukloni Zadnju
|
pdfOrganiser.mode.8=Ukloni Zadnju
|
||||||
pdfOrganiser.mode.9=Ukloni Prvu i Zadnju
|
pdfOrganiser.mode.9=Ukloni Prvu i Zadnju
|
||||||
pdfOrganiser.mode.10=Neparno-parna kombinacija
|
pdfOrganiser.mode.10=Neparno-parna kombinacija
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(npr. 1,3,2 ili 4-8,2,10-12 ili 2n-1)
|
pdfOrganiser.placeholder=(npr. 1,3,2 ili 4-8,2,10-12 ili 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=File decrypted successfully.
|
|||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=Pogledaj
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=Pogledaj PDF
|
viewPdf.header=Pogledaj PDF
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=Promijeniti
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF u PDF/A
|
pdfToPDFA.title=PDF u PDF/A
|
||||||
pdfToPDFA.header=PDF u PDF/A
|
pdfToPDFA.header=PDF u PDF/A
|
||||||
pdfToPDFA.credit=Ova usluga koristi qpdf za PDF/A pretvorbu
|
pdfToPDFA.credit=Ova usluga koristi libreoffice za PDF/A pretvorbu
|
||||||
pdfToPDFA.submit=Pretvoriti
|
pdfToPDFA.submit=Pretvoriti
|
||||||
pdfToPDFA.tip=Trenutno ne radi za više unosa odjednom
|
pdfToPDFA.tip=Trenutno ne radi za više unosa odjednom
|
||||||
pdfToPDFA.outputFormat=Izlazni format
|
pdfToPDFA.outputFormat=Izlazni format
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=Az analitikai beállításokat a config/settings.yml fájlban
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Kedvencek
|
navbar.favorite=Kedvencek
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=Sötét mód
|
navbar.darkmode=Sötét mód
|
||||||
navbar.language=Nyelvek
|
navbar.language=Nyelvek
|
||||||
navbar.settings=Beállítások
|
navbar.settings=Beállítások
|
||||||
@@ -261,10 +262,19 @@ home.desc=Az Ön helyi PDF-szükségleteinek teljes körű megoldása.
|
|||||||
home.searchBar=Funkciók keresése...
|
home.searchBar=Funkciók keresése...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=PDF megtekintése
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=Megtekintés, jegyzetelés, szöveg vagy képek hozzáadása
|
home.viewPdf.desc=Megtekintés, jegyzetelés, szöveg vagy képek hozzáadása
|
||||||
viewPdf.tags=megtekintés,olvasás,jegyzetelés,szöveg,kép
|
viewPdf.tags=megtekintés,olvasás,jegyzetelés,szöveg,kép
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF többfunkciós eszköz
|
home.multiTool.title=PDF többfunkciós eszköz
|
||||||
home.multiTool.desc=Egyesítés, forgatás, átrendezés és oldalak eltávolítása
|
home.multiTool.desc=Egyesítés, forgatás, átrendezés és oldalak eltávolítása
|
||||||
multiTool.tags=Többfunkciós eszköz,Több művelet,UI,húzd és ejtsd,frontend,kliens oldali,interaktív,kezelhető,mozgatás
|
multiTool.tags=Többfunkciós eszköz,Több művelet,UI,húzd és ejtsd,frontend,kliens oldali,interaktív,kezelhető,mozgatás
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Show Attachments
|
|||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
||||||
redact.colourPicker=Colour Picker
|
redact.colourPicker=Colour Picker
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
redact.findCurrentOutlineItem=Find current outline item
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=JavaScript megjelenítése
|
showJS.title=JavaScript megjelenítése
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=Töltse fel az egyetlen nagy szkennelt PDF fájlt, és
|
|||||||
autoSplitPDF.selectText.4=Az elválasztólapokat automatikusan felismeri és eltávolítja, garantálva a rendezett végeredményt.
|
autoSplitPDF.selectText.4=Az elválasztólapokat automatikusan felismeri és eltávolítja, garantálva a rendezett végeredményt.
|
||||||
autoSplitPDF.formPrompt=Töltse fel a Stirling-PDF oldalelválasztókat tartalmazó PDF-et:
|
autoSplitPDF.formPrompt=Töltse fel a Stirling-PDF oldalelválasztókat tartalmazó PDF-et:
|
||||||
autoSplitPDF.duplexMode=Duplex mód (Elő- és hátoldali szkennelés)
|
autoSplitPDF.duplexMode=Duplex mód (Elő- és hátoldali szkennelés)
|
||||||
autoSplitPDF.dividerDownload1='Automatikus elválasztó (minimális).pdf' letöltése
|
|
||||||
autoSplitPDF.dividerDownload2='Automatikus elválasztó (utasításokkal).pdf' letöltése
|
autoSplitPDF.dividerDownload2='Automatikus elválasztó (utasításokkal).pdf' letöltése
|
||||||
autoSplitPDF.submit=Küldés
|
autoSplitPDF.submit=Küldés
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=Első oldal eltávolítása
|
|||||||
pdfOrganiser.mode.8=Utolsó oldal eltávolítása
|
pdfOrganiser.mode.8=Utolsó oldal eltávolítása
|
||||||
pdfOrganiser.mode.9=Első és utolsó oldal eltávolítása
|
pdfOrganiser.mode.9=Első és utolsó oldal eltávolítása
|
||||||
pdfOrganiser.mode.10=Páros-páratlan egyesítés
|
pdfOrganiser.mode.10=Páros-páratlan egyesítés
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(pl. 1,3,2 vagy 4-8,2,10-12 vagy 2n-1)
|
pdfOrganiser.placeholder=(pl. 1,3,2 vagy 4-8,2,10-12 vagy 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=A fájl visszafejtése sikeres.
|
|||||||
multiTool-advert.message=Ez a funkció elérhető a <a href="{0}">többfunkciós eszköz oldalon</a> is. Nézze meg a fejlett oldalankénti felületet és további funkciókat!
|
multiTool-advert.message=Ez a funkció elérhető a <a href="{0}">többfunkciós eszköz oldalon</a> is. Nézze meg a fejlett oldalankénti felületet és további funkciókat!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=PDF megtekintése
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=PDF megtekintése
|
viewPdf.header=PDF megtekintése
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=Módosítás
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF konvertálása PDF/A formátumba
|
pdfToPDFA.title=PDF konvertálása PDF/A formátumba
|
||||||
pdfToPDFA.header=PDF konvertálása PDF/A formátumba
|
pdfToPDFA.header=PDF konvertálása PDF/A formátumba
|
||||||
pdfToPDFA.credit=Ez a szolgáltatás a qpdf használatával végzi a PDF/A konverziót
|
pdfToPDFA.credit=Ez a szolgáltatás a libreoffice használatával végzi a PDF/A konverziót
|
||||||
pdfToPDFA.submit=Konvertálás
|
pdfToPDFA.submit=Konvertálás
|
||||||
pdfToPDFA.tip=Jelenleg nem támogatja a több fájl egyidejű feldolgozását
|
pdfToPDFA.tip=Jelenleg nem támogatja a több fájl egyidejű feldolgozását
|
||||||
pdfToPDFA.outputFormat=Kimeneti formátum
|
pdfToPDFA.outputFormat=Kimeneti formátum
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=Anda dapat mengubah pengaturan untuk analitik di berkas confi
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Favorit
|
navbar.favorite=Favorit
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=Mode Gelap
|
navbar.darkmode=Mode Gelap
|
||||||
navbar.language=Bahasa
|
navbar.language=Bahasa
|
||||||
navbar.settings=Pengaturan
|
navbar.settings=Pengaturan
|
||||||
@@ -261,10 +262,19 @@ home.desc=Semua kebutuhan PDF Anda, langsung dari komputer lokal Anda.
|
|||||||
home.searchBar=Mencari fitur...
|
home.searchBar=Mencari fitur...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=Lihat PDF
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=Melihat, membuat anotasi, menambahkan teks atau gambar
|
home.viewPdf.desc=Melihat, membuat anotasi, menambahkan teks atau gambar
|
||||||
viewPdf.tags=melihat,membaca,membuat anotasi,teks,gambar
|
viewPdf.tags=melihat,membaca,membuat anotasi,teks,gambar
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Alat Multi PDF
|
home.multiTool.title=Alat Multi PDF
|
||||||
home.multiTool.desc=Menggabungkan, Memutar, Mengatur Ulang, dan Menghapus halaman
|
home.multiTool.desc=Menggabungkan, Memutar, Mengatur Ulang, dan Menghapus halaman
|
||||||
multiTool.tags=Alat multi,Operasi multi,UI,klik seret,front end,sisi klien,interaktif,sulit diatur,pindah
|
multiTool.tags=Alat multi,Operasi multi,UI,klik seret,front end,sisi klien,interaktif,sulit diatur,pindah
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Show Attachments
|
|||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
||||||
redact.colourPicker=Colour Picker
|
redact.colourPicker=Colour Picker
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
redact.findCurrentOutlineItem=Find current outline item
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Tampilkan Javascript
|
showJS.title=Tampilkan Javascript
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=Unggah satu berkas PDF besar yang dipindai dan biarkan
|
|||||||
autoSplitPDF.selectText.4=Halaman pembatas secara otomatis terdeteksi dan dihapus, menjamin dokumen akhir yang rapi.
|
autoSplitPDF.selectText.4=Halaman pembatas secara otomatis terdeteksi dan dihapus, menjamin dokumen akhir yang rapi.
|
||||||
autoSplitPDF.formPrompt=Kirimkan PDF yang berisi pembagi Halaman Stirling-PDF:
|
autoSplitPDF.formPrompt=Kirimkan PDF yang berisi pembagi Halaman Stirling-PDF:
|
||||||
autoSplitPDF.duplexMode=Mode Dupleks (Pemindaian depan dan belakang)
|
autoSplitPDF.duplexMode=Mode Dupleks (Pemindaian depan dan belakang)
|
||||||
autoSplitPDF.dividerDownload1=Unduh 'Pembagi Pembagi Otomatis (minimal).pdf'
|
|
||||||
autoSplitPDF.dividerDownload2=Unduh 'Pembagi Pembagi Otomatis (dengan instruksi).pdf'
|
autoSplitPDF.dividerDownload2=Unduh 'Pembagi Pembagi Otomatis (dengan instruksi).pdf'
|
||||||
autoSplitPDF.submit=Kirim
|
autoSplitPDF.submit=Kirim
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=Hapus Pertama
|
|||||||
pdfOrganiser.mode.8=Hapus Terakhir
|
pdfOrganiser.mode.8=Hapus Terakhir
|
||||||
pdfOrganiser.mode.9=Hapus Pertama dan Terakhir
|
pdfOrganiser.mode.9=Hapus Pertama dan Terakhir
|
||||||
pdfOrganiser.mode.10=Penggabungan Genap-Ganjil
|
pdfOrganiser.mode.10=Penggabungan Genap-Ganjil
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(misalnya 1,3,2 atau 4-8,2,10-12 atau 2n-1)
|
pdfOrganiser.placeholder=(misalnya 1,3,2 atau 4-8,2,10-12 atau 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=File decrypted successfully.
|
|||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=Lihat PDF
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=Lihat PDF
|
viewPdf.header=Lihat PDF
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=Ganti
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF Ke PDF/A
|
pdfToPDFA.title=PDF Ke PDF/A
|
||||||
pdfToPDFA.header=PDF ke PDF/A
|
pdfToPDFA.header=PDF ke PDF/A
|
||||||
pdfToPDFA.credit=Layanan ini menggunakan qpdf untuk konversi PDF/A.
|
pdfToPDFA.credit=Layanan ini menggunakan libreoffice untuk konversi PDF/A.
|
||||||
pdfToPDFA.submit=Konversi
|
pdfToPDFA.submit=Konversi
|
||||||
pdfToPDFA.tip=Saat ini tidak dapat digunakan untuk beberapa input sekaligus
|
pdfToPDFA.tip=Saat ini tidak dapat digunakan untuk beberapa input sekaligus
|
||||||
pdfToPDFA.outputFormat=Format keluaran
|
pdfToPDFA.outputFormat=Format keluaran
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ bored=Stanco di aspettare?
|
|||||||
alphabet=Alfabeto
|
alphabet=Alfabeto
|
||||||
downloadPdf=Scarica PDF
|
downloadPdf=Scarica PDF
|
||||||
text=Testo
|
text=Testo
|
||||||
font=Fonte
|
font=Font
|
||||||
selectFillter=-- Seleziona --
|
selectFillter=-- Seleziona --
|
||||||
pageNum=Numero pagina
|
pageNum=Numero pagina
|
||||||
sizes.small=Piccolo
|
sizes.small=Piccolo
|
||||||
@@ -138,6 +138,7 @@ analytics.settings=È possibile modificare le impostazioni per analitycs nel fil
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Preferiti
|
navbar.favorite=Preferiti
|
||||||
|
navbar.recent=Nuovo e aggiornato di recente
|
||||||
navbar.darkmode=Modalità Scura
|
navbar.darkmode=Modalità Scura
|
||||||
navbar.language=Lingue
|
navbar.language=Lingue
|
||||||
navbar.settings=Impostazioni
|
navbar.settings=Impostazioni
|
||||||
@@ -261,10 +262,19 @@ home.desc=La tua pagina auto-gestita per modificare qualsiasi PDF.
|
|||||||
home.searchBar=Cerca funzionalità...
|
home.searchBar=Cerca funzionalità...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=Visualizza PDF
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=Visualizza, annota, aggiungi testo o immagini
|
home.viewPdf.desc=Visualizza, annota, aggiungi testo o immagini
|
||||||
viewPdf.tags=visualizzare,leggere,annotare,testo,immagine
|
viewPdf.tags=visualizzare,leggere,annotare,testo,immagine
|
||||||
|
|
||||||
|
home.setFavorites=Imposta preferiti
|
||||||
|
home.hideFavorites=Nascondi i preferiti
|
||||||
|
home.showFavorites=Mostra preferiti
|
||||||
|
home.legacyHomepage=Vecchia homepage
|
||||||
|
home.newHomePage=Prova la nostra nuova homepage!
|
||||||
|
home.alphabetical=Alfabetico
|
||||||
|
home.globalPopularity=Popolarità
|
||||||
|
home.sortBy=Ordinamento:
|
||||||
|
|
||||||
home.multiTool.title=Multifunzione PDF
|
home.multiTool.title=Multifunzione PDF
|
||||||
home.multiTool.desc=Unisci, Ruota, Riordina, e Rimuovi pagine
|
home.multiTool.desc=Unisci, Ruota, Riordina, e Rimuovi pagine
|
||||||
multiTool.tags=Strumento multiplo,operazione multipla,interfaccia utente,trascinamento clic,front-end,lato client
|
multiTool.tags=Strumento multiplo,operazione multipla,interfaccia utente,trascinamento clic,front-end,lato client
|
||||||
@@ -592,7 +602,7 @@ autoRedact.submitButton=Invia
|
|||||||
redact.title=Redazione manuale
|
redact.title=Redazione manuale
|
||||||
redact.header=Redazione manuale
|
redact.header=Redazione manuale
|
||||||
redact.submit=Redazione
|
redact.submit=Redazione
|
||||||
redact.textBasedRedaction=TRedazione basata sul testo
|
redact.textBasedRedaction=Redazione basata sul testo
|
||||||
redact.pageBasedRedaction=Redazione basata sulla pagina
|
redact.pageBasedRedaction=Redazione basata sulla pagina
|
||||||
redact.convertPDFToImageLabel=Converti PDF in immagine PDF (utilizzato per rimuovere il testo dietro la casella)
|
redact.convertPDFToImageLabel=Converti PDF in immagine PDF (utilizzato per rimuovere il testo dietro la casella)
|
||||||
redact.pageRedactionNumbers.title=Pagine
|
redact.pageRedactionNumbers.title=Pagine
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Mostra allegati
|
|||||||
redact.showLayers=Mostra livelli (fare doppio clic per ripristinare tutti i livelli allo stato predefinito)
|
redact.showLayers=Mostra livelli (fare doppio clic per ripristinare tutti i livelli allo stato predefinito)
|
||||||
redact.colourPicker=Selettore colore
|
redact.colourPicker=Selettore colore
|
||||||
redact.findCurrentOutlineItem=Trova l'elemento di contorno corrente
|
redact.findCurrentOutlineItem=Trova l'elemento di contorno corrente
|
||||||
|
redact.applyChanges=Applica modifiche
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Mostra Javascript
|
showJS.title=Mostra Javascript
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=Carica il singolo file PDF scansionato di grandi dimen
|
|||||||
autoSplitPDF.selectText.4=Le pagine divisorie vengono rilevate e rimosse automaticamente, garantendo un documento finale ordinato.
|
autoSplitPDF.selectText.4=Le pagine divisorie vengono rilevate e rimosse automaticamente, garantendo un documento finale ordinato.
|
||||||
autoSplitPDF.formPrompt=Invia PDF contenente divisori di pagina Stirling-PDF:
|
autoSplitPDF.formPrompt=Invia PDF contenente divisori di pagina Stirling-PDF:
|
||||||
autoSplitPDF.duplexMode=Modalità duplex (scansione fronte e retro)
|
autoSplitPDF.duplexMode=Modalità duplex (scansione fronte e retro)
|
||||||
autoSplitPDF.dividerDownload1=Scarica 'Divisore automatico (minimo).pdf'
|
|
||||||
autoSplitPDF.dividerDownload2=Scarica 'Divisore automatico (con istruzioni).pdf'
|
autoSplitPDF.dividerDownload2=Scarica 'Divisore automatico (con istruzioni).pdf'
|
||||||
autoSplitPDF.submit=Invia
|
autoSplitPDF.submit=Invia
|
||||||
|
|
||||||
@@ -916,7 +926,7 @@ ocr.selectText.10=Modalità OCR
|
|||||||
ocr.selectText.11=Rimuovi immagini dopo la scansione (Rimuove TUTTE le immagini, utile solo come parte del processo di conversione)
|
ocr.selectText.11=Rimuovi immagini dopo la scansione (Rimuove TUTTE le immagini, utile solo come parte del processo di conversione)
|
||||||
ocr.selectText.12=Modalità di rendering (avanzato)
|
ocr.selectText.12=Modalità di rendering (avanzato)
|
||||||
ocr.help=Per favore leggi la documentazione su come usare il programma per altri linguaggi e/o uso non in Docker
|
ocr.help=Per favore leggi la documentazione su come usare il programma per altri linguaggi e/o uso non in Docker
|
||||||
ocr.credit=Questo servizio utilizza qpdf e Tesseract per l'OCR.
|
ocr.credit=Questo servizio utilizza Qpdf e Tesseract per l'OCR.
|
||||||
ocr.submit=Scansiona testo nel PDF con OCR
|
ocr.submit=Scansiona testo nel PDF con OCR
|
||||||
|
|
||||||
|
|
||||||
@@ -942,7 +952,7 @@ compress.title=Comprimi
|
|||||||
compress.header=Comprimi PDF
|
compress.header=Comprimi PDF
|
||||||
compress.credit=Questo servizio utilizza qpdf per la compressione/ottimizzazione dei PDF.
|
compress.credit=Questo servizio utilizza qpdf per la compressione/ottimizzazione dei PDF.
|
||||||
compress.selectText.1=Modalità manuale - Da 1 a 5
|
compress.selectText.1=Modalità manuale - Da 1 a 5
|
||||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
compress.selectText.1.1=Nei livelli di ottimizzazione da 6 a 9, oltre alla compressione PDF generale, la risoluzione dell'immagine viene ridotta per ridurre ulteriormente le dimensioni del file. Livelli più alti comportano una compressione dell'immagine più forte (fino al 50% delle dimensioni originali), ottenendo una maggiore riduzione delle dimensioni ma con una potenziale perdita di qualità nelle immagini.
|
||||||
compress.selectText.2=Livello di ottimizzazione:
|
compress.selectText.2=Livello di ottimizzazione:
|
||||||
compress.selectText.3=4 (Terribile per le immagini di testo)
|
compress.selectText.3=4 (Terribile per le immagini di testo)
|
||||||
compress.selectText.4=Modalità automatica - Regola automaticamente la qualità per ottenere le dimensioni esatte del PDF
|
compress.selectText.4=Modalità automatica - Regola automaticamente la qualità per ottenere le dimensioni esatte del PDF
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=Rimuovi prima
|
|||||||
pdfOrganiser.mode.8=Rimuovi ultima
|
pdfOrganiser.mode.8=Rimuovi ultima
|
||||||
pdfOrganiser.mode.9=Rimuovi la prima e l'ultima
|
pdfOrganiser.mode.9=Rimuovi la prima e l'ultima
|
||||||
pdfOrganiser.mode.10=Unione pari-dispari
|
pdfOrganiser.mode.10=Unione pari-dispari
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(ad es. 1,3,2 o 4-8,2,10-12 o 2n-1)
|
pdfOrganiser.placeholder=(ad es. 1,3,2 o 4-8,2,10-12 o 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=File decrittografato con successo.
|
|||||||
multiTool-advert.message=Questa funzione è disponibile anche nella nostra <a href="{0}">pagina multi-strumento</a>. Scoprila per un'interfaccia utente pagina per pagina migliorata e funzionalità aggiuntive!
|
multiTool-advert.message=Questa funzione è disponibile anche nella nostra <a href="{0}">pagina multi-strumento</a>. Scoprila per un'interfaccia utente pagina per pagina migliorata e funzionalità aggiuntive!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=Visualizza PDF
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=Visualizza PDF
|
viewPdf.header=Visualizza PDF
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=Cambia proprietà
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=Da PDF a PDF/A
|
pdfToPDFA.title=Da PDF a PDF/A
|
||||||
pdfToPDFA.header=Da PDF a PDF/A
|
pdfToPDFA.header=Da PDF a PDF/A
|
||||||
pdfToPDFA.credit=Questo servizio utilizza qpdf per la conversione in PDF/A.
|
pdfToPDFA.credit=Questo servizio utilizza libreoffice per la conversione in PDF/A.
|
||||||
pdfToPDFA.submit=Converti
|
pdfToPDFA.submit=Converti
|
||||||
pdfToPDFA.tip=Attualmente non funziona per più input contemporaneamente
|
pdfToPDFA.tip=Attualmente non funziona per più input contemporaneamente
|
||||||
pdfToPDFA.outputFormat=Formato di output
|
pdfToPDFA.outputFormat=Formato di output
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=config/settings.ymlファイルでアナリティクスの設
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=お気に入り
|
navbar.favorite=お気に入り
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=ダークモード
|
navbar.darkmode=ダークモード
|
||||||
navbar.language=言語
|
navbar.language=言語
|
||||||
navbar.settings=設定
|
navbar.settings=設定
|
||||||
@@ -239,17 +240,17 @@ database.creationDate=作成日
|
|||||||
database.fileSize=ファイルサイズ
|
database.fileSize=ファイルサイズ
|
||||||
database.deleteBackupFile=バックアップファイルの削除
|
database.deleteBackupFile=バックアップファイルの削除
|
||||||
database.importBackupFile=バックアップファイルをインポート
|
database.importBackupFile=バックアップファイルをインポート
|
||||||
database.createBackupFile=Create Backup File
|
database.createBackupFile=バックアップファイルの作成
|
||||||
database.downloadBackupFile=バックアップファイルをダウンロード
|
database.downloadBackupFile=バックアップファイルをダウンロード
|
||||||
database.info_1=データをインポートする際には、正しい構造を確保することが極めて重要です。不明な点がある場合は、専門家のアドバイスやサポートを受けてください。構造上のエラーは、アプリケーションの誤動作を引き起こす可能性があります。
|
database.info_1=データをインポートする際には、正しい構造を確保することが極めて重要です。不明な点がある場合は、専門家のアドバイスやサポートを受けてください。構造上のエラーは、アプリケーションの誤動作を引き起こす可能性があります。
|
||||||
database.info_2=ファイル名はアップロード時には関係ありません。アップロード後にbackup_user_yyyyMMddHHmm.sqlという形式にリネームされ、一貫した命名規則が保証されます。
|
database.info_2=ファイル名はアップロード時には関係ありません。アップロード後にbackup_user_yyyyMMddHHmm.sqlという形式にリネームされ、一貫した命名規則が保証されます。
|
||||||
database.submit=バックアップをインポート
|
database.submit=バックアップをインポート
|
||||||
database.importIntoDatabaseSuccessed=データベースへのインポートに成功
|
database.importIntoDatabaseSuccessed=データベースへのインポートに成功
|
||||||
database.backupCreated=Database backup successful
|
database.backupCreated=データベースのバックアップに成功しました
|
||||||
database.fileNotFound=ファイルが見つかりません
|
database.fileNotFound=ファイルが見つかりません
|
||||||
database.fileNullOrEmpty=ファイルはnullまたは空であってはなりません
|
database.fileNullOrEmpty=ファイルはnullまたは空であってはなりません
|
||||||
database.failedImportFile=ファイルのインポートに失敗
|
database.failedImportFile=ファイルのインポートに失敗
|
||||||
database.notSupported=This function is not available for your database connection.
|
database.notSupported=この機能はデータベース接続では使用できません。
|
||||||
|
|
||||||
session.expired=セッションが期限切れです。ページを更新してもう一度お試しください。
|
session.expired=セッションが期限切れです。ページを更新してもう一度お試しください。
|
||||||
session.refreshPage=ページを更新
|
session.refreshPage=ページを更新
|
||||||
@@ -261,10 +262,19 @@ home.desc=PDFのあらゆるニーズに対応するローカルホスティン
|
|||||||
home.searchBar=機能検索...
|
home.searchBar=機能検索...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=PDFを表示
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=表示、注釈、テキストや画像の追加
|
home.viewPdf.desc=表示、注釈、テキストや画像の追加
|
||||||
viewPdf.tags=view,read,annotate,text,image
|
viewPdf.tags=view,read,annotate,text,image
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDFマルチツール
|
home.multiTool.title=PDFマルチツール
|
||||||
home.multiTool.desc=ページの結合、回転、並べ替え、削除します。
|
home.multiTool.desc=ページの結合、回転、並べ替え、削除します。
|
||||||
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side,interactive,intractable,move
|
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side,interactive,intractable,move
|
||||||
@@ -452,8 +462,8 @@ home.MarkdownToPDF.title=MarkdownをPDFに変換
|
|||||||
home.MarkdownToPDF.desc=あらゆるMarkdownファイルをPDFに変換します。
|
home.MarkdownToPDF.desc=あらゆるMarkdownファイルをPDFに変換します。
|
||||||
MarkdownToPDF.tags=markup,web-content,transformation,convert
|
MarkdownToPDF.tags=markup,web-content,transformation,convert
|
||||||
|
|
||||||
home.PDFToMarkdown.title=PDF to Markdown
|
home.PDFToMarkdown.title=PDFをMarkdownに変換
|
||||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
home.PDFToMarkdown.desc=あらゆるPDFをMarkdownに変換します。
|
||||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||||
|
|
||||||
home.getPdfInfo.title=PDFのすべての情報を入手
|
home.getPdfInfo.title=PDFのすべての情報を入手
|
||||||
@@ -479,8 +489,8 @@ home.autoRedact.title=自動塗りつぶし
|
|||||||
home.autoRedact.desc=入力したテキストに基づいてPDF内のテキストを自動で塗りつぶし(黒塗り)します。
|
home.autoRedact.desc=入力したテキストに基づいてPDF内のテキストを自動で塗りつぶし(黒塗り)します。
|
||||||
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
home.redact.title=手動編集
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
home.redact.desc=選択したテキスト、描画した図形、選択したページに基づいてPDFを編集します。
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
||||||
|
|
||||||
home.tableExtraxt.title=PDFをCSVに変換
|
home.tableExtraxt.title=PDFをCSVに変換
|
||||||
@@ -532,7 +542,7 @@ replace-color.title=色の置換・反転
|
|||||||
replace-color.header=PDFの色の置換・反転
|
replace-color.header=PDFの色の置換・反転
|
||||||
home.replaceColorPdf.title=色の置換と反転
|
home.replaceColorPdf.title=色の置換と反転
|
||||||
home.replaceColorPdf.desc=PDF内のテキストと背景の色を置き換え、PDFのフルカラーを反転してファイルサイズを縮小します。
|
home.replaceColorPdf.desc=PDF内のテキストと背景の色を置き換え、PDFのフルカラーを反転してファイルサイズを縮小します。
|
||||||
replaceColorPdf.tags=Replace Color,Page operations,Back end,server side
|
replaceColorPdf.tags=色の置き換え、ページ操作、バックエンド、サーバー側
|
||||||
replace-color.selectText.1=色の置換または反転オプション
|
replace-color.selectText.1=色の置換または反転オプション
|
||||||
replace-color.selectText.2=デフォルト(デフォルトの高コントラスト色)
|
replace-color.selectText.2=デフォルト(デフォルトの高コントラスト色)
|
||||||
replace-color.selectText.3=カスタム(カスタマイズされた色)
|
replace-color.selectText.3=カスタム(カスタマイズされた色)
|
||||||
@@ -570,7 +580,7 @@ login.oauth2invalidRequest=無効なリクエスト
|
|||||||
login.oauth2AccessDenied=アクセス拒否
|
login.oauth2AccessDenied=アクセス拒否
|
||||||
login.oauth2InvalidTokenResponse=無効なトークン応答
|
login.oauth2InvalidTokenResponse=無効なトークン応答
|
||||||
login.oauth2InvalidIdToken=無効なIDトークン
|
login.oauth2InvalidIdToken=無効なIDトークン
|
||||||
login.relyingPartyRegistrationNotFound=No relying party registration found
|
login.relyingPartyRegistrationNotFound=リライングパーティーの登録が見つかりません
|
||||||
login.userIsDisabled=ユーザーは非アクティブ化されており、現在このユーザー名でのログインはブロックされています。管理者に連絡してください。
|
login.userIsDisabled=ユーザーは非アクティブ化されており、現在このユーザー名でのログインはブロックされています。管理者に連絡してください。
|
||||||
login.alreadyLoggedIn=すでにログインしています
|
login.alreadyLoggedIn=すでにログインしています
|
||||||
login.alreadyLoggedIn2=デバイスからログアウトしてもう一度お試しください。
|
login.alreadyLoggedIn2=デバイスからログアウトしてもう一度お試しください。
|
||||||
@@ -581,7 +591,7 @@ autoRedact.title=自動塗りつぶし
|
|||||||
autoRedact.header=自動塗りつぶし
|
autoRedact.header=自動塗りつぶし
|
||||||
autoRedact.colorLabel=カラー
|
autoRedact.colorLabel=カラー
|
||||||
autoRedact.textsToRedactLabel=編集するテキスト(行区切り)
|
autoRedact.textsToRedactLabel=編集するテキスト(行区切り)
|
||||||
autoRedact.textsToRedactPlaceholder=例 \n機密 \n極秘
|
autoRedact.textsToRedactPlaceholder=例: \n機密 \n極秘
|
||||||
autoRedact.useRegexLabel=正規表現を使用する
|
autoRedact.useRegexLabel=正規表現を使用する
|
||||||
autoRedact.wholeWordSearchLabel=単語単位の検索
|
autoRedact.wholeWordSearchLabel=単語単位の検索
|
||||||
autoRedact.customPaddingLabel=追加の余白
|
autoRedact.customPaddingLabel=追加の余白
|
||||||
@@ -589,30 +599,31 @@ autoRedact.convertPDFToImageLabel=PDFをPDF画像に変換 (塗りつぶしの
|
|||||||
autoRedact.submitButton=送信
|
autoRedact.submitButton=送信
|
||||||
|
|
||||||
#redact
|
#redact
|
||||||
redact.title=Manual Redaction
|
redact.title=手動編集
|
||||||
redact.header=Manual Redaction
|
redact.header=手動編集
|
||||||
redact.submit=Redact
|
redact.submit=編集
|
||||||
redact.textBasedRedaction=Text based Redaction
|
redact.textBasedRedaction=テキストベースの編集
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
redact.pageBasedRedaction=ページベースの編集
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
redact.convertPDFToImageLabel=PDFをPDF画像に変換します (ボックスの背後のテキストを削除するために使用します)
|
||||||
redact.pageRedactionNumbers.title=Pages
|
redact.pageRedactionNumbers.title=ページ
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
redact.pageRedactionNumbers.placeholder=(例:1,2,8、4,7,12-16、2n-1)
|
||||||
redact.redactionColor.title=Redaction Color
|
redact.redactionColor.title=編集色
|
||||||
redact.export=Export
|
redact.export=出力
|
||||||
redact.upload=Upload
|
redact.upload=アップロード
|
||||||
redact.boxRedaction=Box draw redaction
|
redact.boxRedaction=ボックス描画編集
|
||||||
redact.zoom=Zoom
|
redact.zoom=ズーム
|
||||||
redact.zoomIn=Zoom in
|
redact.zoomIn=拡大
|
||||||
redact.zoomOut=Zoom out
|
redact.zoomOut=縮小
|
||||||
redact.nextPage=Next Page
|
redact.nextPage=次のページ
|
||||||
redact.previousPage=Previous Page
|
redact.previousPage=前のページ
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
redact.toggleSidebar=サイドバーを切替え
|
||||||
redact.showThumbnails=Show Thumbnails
|
redact.showThumbnails=サムネイルを表示
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
redact.showDocumentOutline=ドキュメントのアウトラインを表示 (ダブルクリックするとすべての項目を展開/折りたたむことができます)
|
||||||
redact.showAttatchments=Show Attachments
|
redact.showAttatchments=添付ファイルを表示
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
redact.showLayers=レイヤーを表示(ダブルクリックするとすべてのレイヤーがデフォルトの状態にリセットされます)
|
||||||
redact.colourPicker=Colour Picker
|
redact.colourPicker=カラー選択
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
redact.findCurrentOutlineItem=現在のアウトライン項目を検索
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Javascriptを表示
|
showJS.title=Javascriptを表示
|
||||||
@@ -650,9 +661,9 @@ MarkdownToPDF.credit=WeasyPrintを使用
|
|||||||
|
|
||||||
|
|
||||||
#pdf-to-markdown
|
#pdf-to-markdown
|
||||||
PDFToMarkdown.title=PDF To Markdown
|
PDFToMarkdown.title=PDFをMarkdownに変換
|
||||||
PDFToMarkdown.header=PDF To Markdown
|
PDFToMarkdown.header=PDFをMarkdownに変換
|
||||||
PDFToMarkdown.submit=Convert
|
PDFToMarkdown.submit=変換
|
||||||
|
|
||||||
|
|
||||||
#url-to-pdf
|
#url-to-pdf
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=スキャンしたPDFファイルをアップロード
|
|||||||
autoSplitPDF.selectText.4=仕切りページは自動的に検出、削除されるので、最終的な文書はきれいに仕上がります。
|
autoSplitPDF.selectText.4=仕切りページは自動的に検出、削除されるので、最終的な文書はきれいに仕上がります。
|
||||||
autoSplitPDF.formPrompt=Stirling-PDF仕切り用紙を含むPDFを送信:
|
autoSplitPDF.formPrompt=Stirling-PDF仕切り用紙を含むPDFを送信:
|
||||||
autoSplitPDF.duplexMode=両面モード (表裏スキャン)
|
autoSplitPDF.duplexMode=両面モード (表裏スキャン)
|
||||||
autoSplitPDF.dividerDownload1=ダウンロード '自動仕切り用紙 (最小).pdf'
|
|
||||||
autoSplitPDF.dividerDownload2=ダウンロード '自動仕切り用紙 (手順書付き).pdf'
|
autoSplitPDF.dividerDownload2=ダウンロード '自動仕切り用紙 (手順書付き).pdf'
|
||||||
autoSplitPDF.submit=送信
|
autoSplitPDF.submit=送信
|
||||||
|
|
||||||
@@ -870,7 +880,7 @@ sign.first=最初のページ
|
|||||||
sign.last=最後のページ
|
sign.last=最後のページ
|
||||||
sign.next=次のページ
|
sign.next=次のページ
|
||||||
sign.previous=前のページ
|
sign.previous=前のページ
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=アスペクト比を維持を切替え
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
@@ -941,12 +951,12 @@ fileToPDF.submit=PDFを変換
|
|||||||
compress.title=圧縮
|
compress.title=圧縮
|
||||||
compress.header=PDFを圧縮
|
compress.header=PDFを圧縮
|
||||||
compress.credit=本サービスはPDFの圧縮/最適化にqpdfを使用しています。
|
compress.credit=本サービスはPDFの圧縮/最適化にqpdfを使用しています。
|
||||||
compress.selectText.1=手動モード - 1 から 5
|
compress.selectText.1=手動モード - 1から9
|
||||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
compress.selectText.1.1=最適化レベル6~9では、一般的なPDF圧縮に加えて画像解像度が縮小され、ファイルサイズがさらに縮小されます。レベルが高くなると、画像圧縮が強化され (元のサイズの最大 50%)、サイズはさらに縮小されますが、画像の品質が低下する可能性があります。
|
||||||
compress.selectText.2=品質レベル:
|
compress.selectText.2=品質レベル:
|
||||||
compress.selectText.3=4 (テキスト画像は最悪)
|
compress.selectText.3=4 (テキスト画像は最悪)
|
||||||
compress.selectText.4=自動モード - PDFを正確なサイズにするために品質を自動調整する。
|
compress.selectText.4=自動モード - PDFを正確なサイズにするために品質を自動調整する。
|
||||||
compress.selectText.5=PDFサイズ (例 25MB, 10.8MB, 25KB)
|
compress.selectText.5=PDFサイズ (例:25MB, 10.8MB, 25KB)
|
||||||
compress.submit=圧縮
|
compress.submit=圧縮
|
||||||
|
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=最初に削除
|
|||||||
pdfOrganiser.mode.8=最後を削除
|
pdfOrganiser.mode.8=最後を削除
|
||||||
pdfOrganiser.mode.9=最初と最後を削除
|
pdfOrganiser.mode.9=最初と最後を削除
|
||||||
pdfOrganiser.mode.10=奇数-偶数の結合
|
pdfOrganiser.mode.10=奇数-偶数の結合
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(例:1,3,2または4-8,2,10-12または2n-1)
|
pdfOrganiser.placeholder=(例:1,3,2または4-8,2,10-12または2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=ファイルの暗号化が正常に完了しました。
|
|||||||
multiTool-advert.message=この機能は、<a href="{0}">マルチツール</a>でもご利用いただけます。強化されたページごとのUIと追加機能についてはこちらをご覧ください。
|
multiTool-advert.message=この機能は、<a href="{0}">マルチツール</a>でもご利用いただけます。強化されたページごとのUIと追加機能についてはこちらをご覧ください。
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=PDFを表示
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=PDFを表示
|
viewPdf.header=PDFを表示
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=変更
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDFをPDF/Aに変換
|
pdfToPDFA.title=PDFをPDF/Aに変換
|
||||||
pdfToPDFA.header=PDFをPDF/Aに変換
|
pdfToPDFA.header=PDFをPDF/Aに変換
|
||||||
pdfToPDFA.credit=本サービスはPDF/Aの変換にqpdfを使用しています。
|
pdfToPDFA.credit=本サービスはPDF/Aの変換にlibreofficeを使用しています。
|
||||||
pdfToPDFA.submit=変換
|
pdfToPDFA.submit=変換
|
||||||
pdfToPDFA.tip=現在、一度に複数の入力に対して機能しません
|
pdfToPDFA.tip=現在、一度に複数の入力に対して機能しません
|
||||||
pdfToPDFA.outputFormat=出力形式
|
pdfToPDFA.outputFormat=出力形式
|
||||||
@@ -1233,7 +1244,7 @@ split-by-size-or-count.type.size=サイズ
|
|||||||
split-by-size-or-count.type.pageCount=ページ数
|
split-by-size-or-count.type.pageCount=ページ数
|
||||||
split-by-size-or-count.type.docCount=ドキュメント数
|
split-by-size-or-count.type.docCount=ドキュメント数
|
||||||
split-by-size-or-count.value.label=値の入力
|
split-by-size-or-count.value.label=値の入力
|
||||||
split-by-size-or-count.value.placeholder=サイズ (例、2MB または 3KB) または数値 (例、5) を入力
|
split-by-size-or-count.value.placeholder=サイズ (例:2MB または 3KB) または数値 (例:5) を入力
|
||||||
split-by-size-or-count.submit=分割
|
split-by-size-or-count.submit=分割
|
||||||
|
|
||||||
|
|
||||||
@@ -1246,7 +1257,7 @@ overlay-pdfs.mode.sequential=シーケンシャル・オーバーレイ
|
|||||||
overlay-pdfs.mode.interleaved=インターリーブ・オーバーレイ
|
overlay-pdfs.mode.interleaved=インターリーブ・オーバーレイ
|
||||||
overlay-pdfs.mode.fixedRepeat=固定リピート・オーバーレイ
|
overlay-pdfs.mode.fixedRepeat=固定リピート・オーバーレイ
|
||||||
overlay-pdfs.counts.label=オーバーレイ回数 (固定リピートモード用)
|
overlay-pdfs.counts.label=オーバーレイ回数 (固定リピートモード用)
|
||||||
overlay-pdfs.counts.placeholder=カンマ区切りでカウントを入力 (例、2,3,1)
|
overlay-pdfs.counts.placeholder=カンマ区切りでカウントを入力 (例:2,3,1)
|
||||||
overlay-pdfs.position.label=重ね位置の選択
|
overlay-pdfs.position.label=重ね位置の選択
|
||||||
overlay-pdfs.position.foreground=前面
|
overlay-pdfs.position.foreground=前面
|
||||||
overlay-pdfs.position.background=背面
|
overlay-pdfs.position.background=背面
|
||||||
@@ -1328,8 +1339,8 @@ splitByChapters.submit=PDFを分割
|
|||||||
fileChooser.click=クリック
|
fileChooser.click=クリック
|
||||||
fileChooser.or=または
|
fileChooser.or=または
|
||||||
fileChooser.dragAndDrop=ドラッグ&ドロップ
|
fileChooser.dragAndDrop=ドラッグ&ドロップ
|
||||||
fileChooser.dragAndDropPDF=Drag & Drop PDF file
|
fileChooser.dragAndDropPDF=PDFファイルをドラッグ&ドロップ
|
||||||
fileChooser.dragAndDropImage=Drag & Drop Image file
|
fileChooser.dragAndDropImage=画像ファイルをドラッグ&ドロップ
|
||||||
fileChooser.hoveredDragAndDrop=ファイルをここにドラッグ&ドロップ
|
fileChooser.hoveredDragAndDrop=ファイルをここにドラッグ&ドロップ
|
||||||
|
|
||||||
#release notes
|
#release notes
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=config/settings.yml 파일에서 분석 설정을 변경할
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=즐겨찾기
|
navbar.favorite=즐겨찾기
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=다크 모드
|
navbar.darkmode=다크 모드
|
||||||
navbar.language=언어
|
navbar.language=언어
|
||||||
navbar.settings=설정
|
navbar.settings=설정
|
||||||
@@ -261,10 +262,19 @@ home.desc=PDF 관련 모든 작업을 위한 로컬 호스팅 원스톱 솔루
|
|||||||
home.searchBar=기능 검색...
|
home.searchBar=기능 검색...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=PDF 보기
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=보기, 주석 달기, 텍스트 또는 이미지 추가
|
home.viewPdf.desc=보기, 주석 달기, 텍스트 또는 이미지 추가
|
||||||
viewPdf.tags=보기,읽기,주석,텍스트,이미지
|
viewPdf.tags=보기,읽기,주석,텍스트,이미지
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF 멀티 도구
|
home.multiTool.title=PDF 멀티 도구
|
||||||
home.multiTool.desc=병합, 회전, 재배치, 분할 및 페이지 제거
|
home.multiTool.desc=병합, 회전, 재배치, 분할 및 페이지 제거
|
||||||
multiTool.tags=멀티 도구,다중 작업,UI,클릭 드래그,프론트엔드,클라이언트 사이드,대화형,상호작용,이동,삭제,마이그레이션,분할
|
multiTool.tags=멀티 도구,다중 작업,UI,클릭 드래그,프론트엔드,클라이언트 사이드,대화형,상호작용,이동,삭제,마이그레이션,분할
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=첨부 파일 보기
|
|||||||
redact.showLayers=레이어 보기 (더블클릭하여 모든 레이어를 기본 상태로 재설정)
|
redact.showLayers=레이어 보기 (더블클릭하여 모든 레이어를 기본 상태로 재설정)
|
||||||
redact.colourPicker=색상 선택기
|
redact.colourPicker=색상 선택기
|
||||||
redact.findCurrentOutlineItem=현재 개요 항목 찾기
|
redact.findCurrentOutlineItem=현재 개요 항목 찾기
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=JavaScript 보기
|
showJS.title=JavaScript 보기
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=스캔한 단일 PDF 파일을 업로드하고 나머
|
|||||||
autoSplitPDF.selectText.4=구분자 페이지는 자동으로 감지되고 제거되어 깔끔한 최종 문서를 보장합니다.
|
autoSplitPDF.selectText.4=구분자 페이지는 자동으로 감지되고 제거되어 깔끔한 최종 문서를 보장합니다.
|
||||||
autoSplitPDF.formPrompt=Stirling-PDF 페이지 구분자가 포함된 PDF 제출:
|
autoSplitPDF.formPrompt=Stirling-PDF 페이지 구분자가 포함된 PDF 제출:
|
||||||
autoSplitPDF.duplexMode=양면 모드 (앞뒷면 스캔)
|
autoSplitPDF.duplexMode=양면 모드 (앞뒷면 스캔)
|
||||||
autoSplitPDF.dividerDownload1='자동 분할 구분자 (최소)' PDF 다운로드
|
|
||||||
autoSplitPDF.dividerDownload2='자동 분할 구분자 (설명 포함)' PDF 다운로드
|
autoSplitPDF.dividerDownload2='자동 분할 구분자 (설명 포함)' PDF 다운로드
|
||||||
autoSplitPDF.submit=제출
|
autoSplitPDF.submit=제출
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=첫 페이지 제거
|
|||||||
pdfOrganiser.mode.8=마지막 페이지 제거
|
pdfOrganiser.mode.8=마지막 페이지 제거
|
||||||
pdfOrganiser.mode.9=첫 페이지와 마지막 페이지 제거
|
pdfOrganiser.mode.9=첫 페이지와 마지막 페이지 제거
|
||||||
pdfOrganiser.mode.10=홀수-짝수 병합
|
pdfOrganiser.mode.10=홀수-짝수 병합
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(예: 1,3,2 또는 4-8,2,10-12 또는 2n-1)
|
pdfOrganiser.placeholder=(예: 1,3,2 또는 4-8,2,10-12 또는 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=파일이 성공적으로 복호화되었습니다.
|
|||||||
multiTool-advert.message=이 기능은 <a href="{0}">멀티 도구 페이지</a>에서도 사용할 수 있습니다. 향상된 페이지별 UI와 추가 기능을 확인해보세요!
|
multiTool-advert.message=이 기능은 <a href="{0}">멀티 도구 페이지</a>에서도 사용할 수 있습니다. 향상된 페이지별 UI와 추가 기능을 확인해보세요!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=PDF 보기
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=PDF 보기
|
viewPdf.header=PDF 보기
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=변경
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF를 PDF/A로
|
pdfToPDFA.title=PDF를 PDF/A로
|
||||||
pdfToPDFA.header=PDF를 PDF/A로
|
pdfToPDFA.header=PDF를 PDF/A로
|
||||||
pdfToPDFA.credit=이 서비스는 PDF/A 변환을 위해 qpdf를 사용합니다
|
pdfToPDFA.credit=이 서비스는 PDF/A 변환을 위해 libreoffice를 사용합니다
|
||||||
pdfToPDFA.submit=변환
|
pdfToPDFA.submit=변환
|
||||||
pdfToPDFA.tip=현재 여러 입력을 한 번에 처리할 수 없습니다
|
pdfToPDFA.tip=현재 여러 입력을 한 번에 처리할 수 없습니다
|
||||||
pdfToPDFA.outputFormat=출력 형식
|
pdfToPDFA.outputFormat=출력 형식
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ analytics.settings=You can change the settings for analytics in the config/setti
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Favorieten
|
navbar.favorite=Favorieten
|
||||||
|
navbar.recent=New and recently updated
|
||||||
navbar.darkmode=Donkere modus
|
navbar.darkmode=Donkere modus
|
||||||
navbar.language=Talen
|
navbar.language=Talen
|
||||||
navbar.settings=Instellingen
|
navbar.settings=Instellingen
|
||||||
@@ -261,10 +262,19 @@ home.desc=Jouw lokaal gehoste one-stop-shop voor al je PDF-behoeften.
|
|||||||
home.searchBar=Zoek naar functies...
|
home.searchBar=Zoek naar functies...
|
||||||
|
|
||||||
|
|
||||||
home.viewPdf.title=PDF bekijken
|
home.viewPdf.title=View/Edit PDF
|
||||||
home.viewPdf.desc=Bekijk, annoteer, voeg tekst of afbeeldingen toe
|
home.viewPdf.desc=Bekijk, annoteer, voeg tekst of afbeeldingen toe
|
||||||
viewPdf.tags=bekijken,lezen,annoteren,tekst,afbeelding
|
viewPdf.tags=bekijken,lezen,annoteren,tekst,afbeelding
|
||||||
|
|
||||||
|
home.setFavorites=Set Favourites
|
||||||
|
home.hideFavorites=Hide Favourites
|
||||||
|
home.showFavorites=Show Favourites
|
||||||
|
home.legacyHomepage=Old homepage
|
||||||
|
home.newHomePage=Try our new homepage!
|
||||||
|
home.alphabetical=Alphabetical
|
||||||
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF multitool
|
home.multiTool.title=PDF multitool
|
||||||
home.multiTool.desc=Pagina's samenvoegen, draaien, herschikken en verwijderen
|
home.multiTool.desc=Pagina's samenvoegen, draaien, herschikken en verwijderen
|
||||||
multiTool.tags=Multitool,meerdere bewerkingen,UI,klik sleep,voorkant,clientzijde,interactief,beweegbaar,verplaats
|
multiTool.tags=Multitool,meerdere bewerkingen,UI,klik sleep,voorkant,clientzijde,interactief,beweegbaar,verplaats
|
||||||
@@ -613,6 +623,7 @@ redact.showAttatchments=Show Attachments
|
|||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
||||||
redact.colourPicker=Colour Picker
|
redact.colourPicker=Colour Picker
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
redact.findCurrentOutlineItem=Find current outline item
|
||||||
|
redact.applyChanges=Apply Changes
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Toon Javascript
|
showJS.title=Toon Javascript
|
||||||
@@ -758,7 +769,6 @@ autoSplitPDF.selectText.3=Upload het enkele grote gescande PDF-bestand en laat S
|
|||||||
autoSplitPDF.selectText.4=Scheidingspagina's worden automatisch gedetecteerd en verwijderd, wat een net einddocument garandeert.
|
autoSplitPDF.selectText.4=Scheidingspagina's worden automatisch gedetecteerd en verwijderd, wat een net einddocument garandeert.
|
||||||
autoSplitPDF.formPrompt=Dien PDF in met Stirling-PDF Pagina-scheiders:
|
autoSplitPDF.formPrompt=Dien PDF in met Stirling-PDF Pagina-scheiders:
|
||||||
autoSplitPDF.duplexMode=Duplex Modus (voor- en achterkant scannen)
|
autoSplitPDF.duplexMode=Duplex Modus (voor- en achterkant scannen)
|
||||||
autoSplitPDF.dividerDownload1=Download 'Auto Splitter Divider (minimal).pdf'
|
|
||||||
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
|
autoSplitPDF.dividerDownload2=Download 'Auto Splitter Divider (with instructions).pdf'
|
||||||
autoSplitPDF.submit=Indienen
|
autoSplitPDF.submit=Indienen
|
||||||
|
|
||||||
@@ -982,6 +992,7 @@ pdfOrganiser.mode.7=Eerste verwijderen
|
|||||||
pdfOrganiser.mode.8=Laatste verwijderen
|
pdfOrganiser.mode.8=Laatste verwijderen
|
||||||
pdfOrganiser.mode.9=Eerste en laaste verwijderen
|
pdfOrganiser.mode.9=Eerste en laaste verwijderen
|
||||||
pdfOrganiser.mode.10=Oneven-even samenvoeken
|
pdfOrganiser.mode.10=Oneven-even samenvoeken
|
||||||
|
pdfOrganiser.mode.11=Duplicate all pages
|
||||||
pdfOrganiser.placeholder=(bijv. 1,3,2 of 4-8,2,10-12 of 2n-1)
|
pdfOrganiser.placeholder=(bijv. 1,3,2 of 4-8,2,10-12 of 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1035,7 @@ decrypt.success=File decrypted successfully.
|
|||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=PDF bekijken
|
viewPdf.title=View/Edit PDF
|
||||||
viewPdf.header=PDF bekijken
|
viewPdf.header=PDF bekijken
|
||||||
|
|
||||||
#pageRemover
|
#pageRemover
|
||||||
@@ -1175,7 +1186,7 @@ changeMetadata.submit=Wijzigen
|
|||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF naar PDF/A
|
pdfToPDFA.title=PDF naar PDF/A
|
||||||
pdfToPDFA.header=PDF naar PDF/A
|
pdfToPDFA.header=PDF naar PDF/A
|
||||||
pdfToPDFA.credit=Deze service gebruikt qpdf voor PDF/A-conversie
|
pdfToPDFA.credit=Deze service gebruikt libreoffice voor PDF/A-conversie
|
||||||
pdfToPDFA.submit=Converteren
|
pdfToPDFA.submit=Converteren
|
||||||
pdfToPDFA.tip=Werkt momenteel niet voor meerdere inputs tegelijkertijd.
|
pdfToPDFA.tip=Werkt momenteel niet voor meerdere inputs tegelijkertijd.
|
||||||
pdfToPDFA.outputFormat=Uitvoerindeling
|
pdfToPDFA.outputFormat=Uitvoerindeling
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user