mirror of
https://github.com/immich-app/immich.git
synced 2025-12-11 07:11:05 -08:00
Compare commits
325 Commits
revert-res
...
postgres-q
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d46e5f2436 | ||
|
|
b845184c80 | ||
|
|
1fde02ee1e | ||
|
|
526c02297c | ||
|
|
732b06eec8 | ||
|
|
436cff72b5 | ||
|
|
be5cc2cdf5 | ||
|
|
094a41ac9a | ||
|
|
ebad6a008f | ||
|
|
0c261ffbe2 | ||
|
|
6df6103c67 | ||
|
|
8c5116bc1d | ||
|
|
e3812a0e36 | ||
|
|
4b1ced439b | ||
|
|
2e8a286540 | ||
|
|
038a82c4f1 | ||
|
|
2c2dd01bf0 | ||
|
|
ac73e163df | ||
|
|
d89e88bb3f | ||
|
|
3ce353393a | ||
|
|
0e4cf9ac57 | ||
|
|
07290580a6 | ||
|
|
d9ce74b896 | ||
|
|
4c0f79b162 | ||
|
|
9851d24628 | ||
|
|
fe6cbd93b1 | ||
|
|
df20788088 | ||
|
|
3d042cc7f1 | ||
|
|
85446c5862 | ||
|
|
fb52ac0f5b | ||
|
|
48bcbee6ed | ||
|
|
f621f8ef2c | ||
|
|
7f69abbf0d | ||
|
|
895b2bf5cd | ||
|
|
f64e6f5dc3 | ||
|
|
64e738f79d | ||
|
|
a17390a422 | ||
|
|
1b5fc9c665 | ||
|
|
23717ce981 | ||
|
|
2fd05e8447 | ||
|
|
c664d99a34 | ||
|
|
21c7d70336 | ||
|
|
ad272333db | ||
|
|
460d594791 | ||
|
|
e6c575c33e | ||
|
|
85ac0512a6 | ||
|
|
205260d31c | ||
|
|
3858973be5 | ||
|
|
02994883fe | ||
|
|
a1f8150c30 | ||
|
|
d85ef19bfc | ||
|
|
d0014bdf94 | ||
|
|
e822e3eca9 | ||
|
|
644defa4a1 | ||
|
|
1fe3c7b9b3 | ||
|
|
0d60be3d87 | ||
|
|
765da7b182 | ||
|
|
b037158028 | ||
|
|
a03902f174 | ||
|
|
1d610ad9cb | ||
|
|
dab4870fed | ||
|
|
37f5e6e2cb | ||
|
|
57d622bc43 | ||
|
|
c167e46ec7 | ||
|
|
6ce8a1deeb | ||
|
|
f659ef4b7a | ||
|
|
bb6cdc99ab | ||
|
|
830b4dadcb | ||
|
|
d2f2f8d672 | ||
|
|
be1062474b | ||
|
|
64000d9d76 | ||
|
|
59fa8fbd0e | ||
|
|
19746a8685 | ||
|
|
987e5ab76c | ||
|
|
1b5e981a45 | ||
|
|
b7a0cf2470 | ||
|
|
13d6bd67b1 | ||
|
|
1de2eae12d | ||
|
|
bc5875ba8d | ||
|
|
0426b574fe | ||
|
|
2c3658e642 | ||
|
|
a493dab294 | ||
|
|
699fdd0d1b | ||
|
|
a774153f67 | ||
|
|
ca12aff3a4 | ||
|
|
550c1c0a10 | ||
|
|
92ac1193e6 | ||
|
|
2a95eccf6a | ||
|
|
ee017803bf | ||
|
|
0986a71ce3 | ||
|
|
af36eaa61b | ||
|
|
fda68f972f | ||
|
|
a8eec92da7 | ||
|
|
ad8511c978 | ||
|
|
fe8c5e8107 | ||
|
|
c70140e707 | ||
|
|
010b144754 | ||
|
|
b71039e83c | ||
|
|
56a4aa9ffe | ||
|
|
488dc4efbd | ||
|
|
f0ff8581da | ||
|
|
c49fd2065b | ||
|
|
21a6eb30ff | ||
|
|
9e063c993c | ||
|
|
dd1fcd5be5 | ||
|
|
52ae06c119 | ||
|
|
854ea13d6a | ||
|
|
504930947d | ||
|
|
0e6ac87645 | ||
|
|
bd2deda50c | ||
|
|
160bb492a2 | ||
|
|
6474a78b8b | ||
|
|
e275f2d8b3 | ||
|
|
81ed54aa61 | ||
|
|
067338b0ed | ||
|
|
5e68f8c519 | ||
|
|
242a559e0f | ||
|
|
ed2b54527c | ||
|
|
8b38f8a58d | ||
|
|
29b30570bf | ||
|
|
586a7a173b | ||
|
|
1bbfacfc09 | ||
|
|
85c2d36d99 | ||
|
|
8cefa0b84b | ||
|
|
f50e5d006c | ||
|
|
8f8ff3adc0 | ||
|
|
c4c35ed140 | ||
|
|
be2f670d35 | ||
|
|
7efcba2b12 | ||
|
|
459c815086 | ||
|
|
36fa61c013 | ||
|
|
8da5f21fcf | ||
|
|
76db8cf604 | ||
|
|
21becbf1b0 | ||
|
|
26f0ea4cb5 | ||
|
|
19e5a6f68f | ||
|
|
78f8e23834 | ||
|
|
5bceefce75 | ||
|
|
b710ad36f3 | ||
|
|
270d178a2e | ||
|
|
309528c807 | ||
|
|
7c422363fb | ||
|
|
3eb316abea | ||
|
|
b3371e16f2 | ||
|
|
b2c903c000 | ||
|
|
17e720440d | ||
|
|
a522130122 | ||
|
|
cecd9c24a4 | ||
|
|
f189c7b101 | ||
|
|
c5f087a3ca | ||
|
|
72f6d7791e | ||
|
|
f73fce1046 | ||
|
|
f2edcde1b2 | ||
|
|
9d0dd9dff8 | ||
|
|
c3d10c5be2 | ||
|
|
bd92748ddd | ||
|
|
aad5c3bada | ||
|
|
b2753103c6 | ||
|
|
e3f3baadb0 | ||
|
|
0b69d1c147 | ||
|
|
5a51ad3622 | ||
|
|
664c99278a | ||
|
|
184e142d87 | ||
|
|
8b00578c7b | ||
|
|
7562088fac | ||
|
|
79d4ce2d6d | ||
|
|
983f656a6b | ||
|
|
ab2a7006f9 | ||
|
|
1f18fe31f0 | ||
|
|
a373034629 | ||
|
|
5dac315af7 | ||
|
|
8309b73a02 | ||
|
|
e440cbe353 | ||
|
|
5548eb0dad | ||
|
|
3bec8dc337 | ||
|
|
5bcb58c3e7 | ||
|
|
c62fc155c8 | ||
|
|
40e3322b25 | ||
|
|
25f2b9602f | ||
|
|
ae6653392e | ||
|
|
d7a782da34 | ||
|
|
08b5952c87 | ||
|
|
584e5894bf | ||
|
|
52d4b2fe57 | ||
|
|
92f0973a46 | ||
|
|
75c83cb704 | ||
|
|
0b22d3348e | ||
|
|
abde0fbe60 | ||
|
|
eaa0e07329 | ||
|
|
9fd2c5220d | ||
|
|
7fcab4b251 | ||
|
|
e3995fb5f4 | ||
|
|
6d3f3d8616 | ||
|
|
4412680679 | ||
|
|
7df2c9c905 | ||
|
|
7a1e8ce6d8 | ||
|
|
8aea07b750 | ||
|
|
94dba29298 | ||
|
|
9e49783e49 | ||
|
|
43e3075f93 | ||
|
|
d03647904b | ||
|
|
206545356d | ||
|
|
3e372500b0 | ||
|
|
8943ec23ba | ||
|
|
04b03f2924 | ||
|
|
cf2c0260a6 | ||
|
|
ae8af84101 | ||
|
|
4794eeca88 | ||
|
|
ac65d46ec6 | ||
|
|
e5ca79dd44 | ||
|
|
49be6d7fd8 | ||
|
|
15c6506aee | ||
|
|
2c31a11e41 | ||
|
|
b6c5a03533 | ||
|
|
75bc32b47b | ||
|
|
fdbe6d649f | ||
|
|
2b131fe935 | ||
|
|
6ae24fbbd4 | ||
|
|
7f116d8e98 | ||
|
|
bd0840c411 | ||
|
|
a5123dec1a | ||
|
|
ffd18c5459 | ||
|
|
8242ff9bab | ||
|
|
8203b6c450 | ||
|
|
b352cf3336 | ||
|
|
96ed9a8c4a | ||
|
|
e7a5b96ed0 | ||
|
|
51c2c60231 | ||
|
|
43d585ce55 | ||
|
|
042da669d1 | ||
|
|
a724f147fe | ||
|
|
1e4b9ae5b7 | ||
|
|
99cddf1fd6 | ||
|
|
30d33f968f | ||
|
|
31ee19181a | ||
|
|
b58a450152 | ||
|
|
b87ba6865b | ||
|
|
565cceb323 | ||
|
|
f096dd0cc0 | ||
|
|
a3c3f9cfcb | ||
|
|
7b6a4be30c | ||
|
|
720189e2c2 | ||
|
|
dfab32c8f2 | ||
|
|
60174d662d | ||
|
|
8b6a765e12 | ||
|
|
2248a38567 | ||
|
|
97e52c5156 | ||
|
|
e8b4ac0522 | ||
|
|
548298b0c7 | ||
|
|
40cff2893c | ||
|
|
b621281351 | ||
|
|
4336afd6bf | ||
|
|
5a456ef277 | ||
|
|
5cb5fcbf62 | ||
|
|
95e3b15776 | ||
|
|
50335dc363 | ||
|
|
6e62c09d84 | ||
|
|
00d3b8d83a | ||
|
|
d911b76c08 | ||
|
|
502854cee1 | ||
|
|
59e5c82569 | ||
|
|
e4b0c00885 | ||
|
|
946507231d | ||
|
|
20ba800a50 | ||
|
|
f434e858ed | ||
|
|
3e03c47fbf | ||
|
|
9aa3850769 | ||
|
|
628dcdeebf | ||
|
|
11bfde2aa8 | ||
|
|
69b1ac47ea | ||
|
|
4f81265694 | ||
|
|
3428a876c7 | ||
|
|
bd822657d3 | ||
|
|
9e7744a9ab | ||
|
|
7729fe80fa | ||
|
|
68e24ad168 | ||
|
|
186c573565 | ||
|
|
5b63b9fc8b | ||
|
|
5c80e8734b | ||
|
|
a5093a9434 | ||
|
|
637ad1fdcb | ||
|
|
6789c2ac19 | ||
|
|
838a8dd9a6 | ||
|
|
d71c5602c3 | ||
|
|
8c50e3e80e | ||
|
|
efcb1129ce | ||
|
|
faabda4446 | ||
|
|
b8b2898c87 | ||
|
|
b25914c2a5 | ||
|
|
d613f15606 | ||
|
|
a831876fdc | ||
|
|
09f4476f97 | ||
|
|
238c151ac3 | ||
|
|
e4f83680d9 | ||
|
|
74f7fd4b53 | ||
|
|
f4dbfd856e | ||
|
|
55a3c30664 | ||
|
|
6fa0cb534a | ||
|
|
9f0dbfc150 | ||
|
|
6419ac74af | ||
|
|
d2bcf5d716 | ||
|
|
c8331f111f | ||
|
|
4b4bcd23f4 | ||
|
|
3fde5a8328 | ||
|
|
cc3ea32cd2 | ||
|
|
431cf281da | ||
|
|
8f786fd7dd | ||
|
|
3e73765375 | ||
|
|
411521b21d | ||
|
|
e163808348 | ||
|
|
411772123f | ||
|
|
84c35e35d6 | ||
|
|
f7d730eb05 | ||
|
|
16e0166d22 | ||
|
|
43f8f473e9 | ||
|
|
cc393b2b7b | ||
|
|
6341962de4 | ||
|
|
c26b28f6a4 | ||
|
|
c72c82c401 | ||
|
|
fecf3809a6 | ||
|
|
619bd72de9 | ||
|
|
fd4a5f71b5 | ||
|
|
2f8725c66f | ||
|
|
9fbd6369b9 | ||
|
|
c547d849d9 |
@@ -1,4 +1,4 @@
|
||||
ARG BASEIMAGE=mcr.microsoft.com/devcontainers/typescript-node:22@sha256:2ef23730ec68d8511ec8e6e0b82550ca728b256805d81f60ed890f3bfb21cfb9
|
||||
ARG BASEIMAGE=mcr.microsoft.com/devcontainers/typescript-node:22@sha256:a20b8a3538313487ac9266875bbf733e544c1aa2091df2bb99ab592a6d4f7399
|
||||
FROM ${BASEIMAGE}
|
||||
|
||||
# Flutter SDK
|
||||
|
||||
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -6,6 +6,9 @@ mobile/openapi/**/*.dart linguist-generated=true
|
||||
mobile/lib/**/*.g.dart -diff -merge
|
||||
mobile/lib/**/*.g.dart linguist-generated=true
|
||||
|
||||
mobile/lib/**/*.drift.dart -diff -merge
|
||||
mobile/lib/**/*.drift.dart linguist-generated=true
|
||||
|
||||
open-api/typescript-sdk/fetch-client.ts -diff -merge
|
||||
open-api/typescript-sdk/fetch-client.ts linguist-generated=true
|
||||
|
||||
|
||||
35
.github/workflows/build-mobile.yml
vendored
35
.github/workflows/build-mobile.yml
vendored
@@ -7,6 +7,15 @@ on:
|
||||
ref:
|
||||
required: false
|
||||
type: string
|
||||
secrets:
|
||||
KEY_JKS:
|
||||
required: true
|
||||
ALIAS:
|
||||
required: true
|
||||
ANDROID_KEY_PASSWORD:
|
||||
required: true
|
||||
ANDROID_STORE_PASSWORD:
|
||||
required: true
|
||||
pull_request:
|
||||
push:
|
||||
branches: [main]
|
||||
@@ -15,14 +24,21 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
pre-job:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
should_run: ${{ steps.found_paths.outputs.mobile == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- id: found_paths
|
||||
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3
|
||||
with:
|
||||
@@ -38,24 +54,19 @@ jobs:
|
||||
build-sign-android:
|
||||
name: Build and sign Android
|
||||
needs: pre-job
|
||||
permissions:
|
||||
contents: read
|
||||
# Skip when PR from a fork
|
||||
if: ${{ !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' && needs.pre-job.outputs.should_run == 'true' }}
|
||||
runs-on: macos-14
|
||||
|
||||
steps:
|
||||
- name: Determine ref
|
||||
id: get-ref
|
||||
run: |
|
||||
input_ref="${{ inputs.ref }}"
|
||||
github_ref="${{ github.sha }}"
|
||||
ref="${input_ref:-$github_ref}"
|
||||
echo "ref=$ref" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
ref: ${{ steps.get-ref.outputs.ref }}
|
||||
ref: ${{ inputs.ref || github.sha }}
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4
|
||||
- uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: '17'
|
||||
@@ -78,6 +89,10 @@ jobs:
|
||||
working-directory: ./mobile
|
||||
run: flutter pub get
|
||||
|
||||
- name: Generate translation file
|
||||
run: make translation
|
||||
working-directory: ./mobile
|
||||
|
||||
- name: Build Android App Bundle
|
||||
working-directory: ./mobile
|
||||
env:
|
||||
|
||||
17
.github/workflows/cache-cleanup.yml
vendored
17
.github/workflows/cache-cleanup.yml
vendored
@@ -8,31 +8,38 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
cleanup:
|
||||
name: Cleanup
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
actions: write
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Cleanup
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
REF: ${{ github.ref }}
|
||||
run: |
|
||||
gh extension install actions/gh-actions-cache
|
||||
|
||||
REPO=${{ github.repository }}
|
||||
BRANCH=${{ github.ref }}
|
||||
|
||||
echo "Fetching list of cache keys"
|
||||
cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH -L 100 | cut -f 1 )
|
||||
cacheKeysForPR=$(gh actions-cache list -R $REPO -B ${REF} -L 100 | cut -f 1 )
|
||||
|
||||
## Setting this to not fail the workflow while deleting cache keys.
|
||||
set +e
|
||||
echo "Deleting caches..."
|
||||
for cacheKey in $cacheKeysForPR
|
||||
do
|
||||
gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm
|
||||
gh actions-cache delete $cacheKey -R "$REPO" -B "${REF}" --confirm
|
||||
done
|
||||
echo "Done"
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
17
.github/workflows/cli.yml
vendored
17
.github/workflows/cli.yml
vendored
@@ -16,21 +16,25 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
packages: write
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: CLI Publish
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./cli
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
# Setup .npmrc file to publish to npm
|
||||
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version-file: './cli/.nvmrc'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
@@ -48,11 +52,16 @@ jobs:
|
||||
docker:
|
||||
name: Docker
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
needs: publish
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
||||
@@ -87,7 +96,7 @@ jobs:
|
||||
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
|
||||
|
||||
- name: Build and push image
|
||||
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
||||
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
|
||||
with:
|
||||
file: cli/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
||||
10
.github/workflows/codeql-analysis.yml
vendored
10
.github/workflows/codeql-analysis.yml
vendored
@@ -24,6 +24,8 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
@@ -43,10 +45,12 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@1b549b9259bda1cb5ddde3b41741a82a2d15a841 # v3
|
||||
uses: github/codeql-action/init@28deaeda66b76a05916b6923827895f2b14ab387 # v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -59,7 +63,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@1b549b9259bda1cb5ddde3b41741a82a2d15a841 # v3
|
||||
uses: github/codeql-action/autobuild@28deaeda66b76a05916b6923827895f2b14ab387 # v3
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
@@ -72,6 +76,6 @@ jobs:
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@1b549b9259bda1cb5ddde3b41741a82a2d15a841 # v3
|
||||
uses: github/codeql-action/analyze@28deaeda66b76a05916b6923827895f2b14ab387 # v3
|
||||
with:
|
||||
category: '/language:${{matrix.language}}'
|
||||
|
||||
147
.github/workflows/docker.yml
vendored
147
.github/workflows/docker.yml
vendored
@@ -12,18 +12,21 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
packages: write
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
pre-job:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
should_run_server: ${{ steps.found_paths.outputs.server == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
||||
should_run_ml: ${{ steps.found_paths.outputs.machine-learning == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- id: found_paths
|
||||
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3
|
||||
with:
|
||||
@@ -45,6 +48,9 @@ jobs:
|
||||
retag_ml:
|
||||
name: Re-Tag ML
|
||||
needs: pre-job
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
if: ${{ needs.pre-job.outputs.should_run_ml == 'false' && !github.event.pull_request.head.repo.fork }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
@@ -58,18 +64,22 @@ jobs:
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Re-tag image
|
||||
env:
|
||||
REGISTRY_NAME: 'ghcr.io'
|
||||
REPOSITORY: ${{ github.repository_owner }}/immich-machine-learning
|
||||
TAG_OLD: main${{ matrix.suffix }}
|
||||
TAG_PR: ${{ github.event.number == 0 && github.ref_name || format('pr-{0}', github.event.number) }}${{ matrix.suffix }}
|
||||
TAG_COMMIT: commit-${{ github.event_name != 'pull_request' && github.sha || github.event.pull_request.head.sha }}${{ matrix.suffix }}
|
||||
run: |
|
||||
REGISTRY_NAME="ghcr.io"
|
||||
REPOSITORY=${{ github.repository_owner }}/immich-machine-learning
|
||||
TAG_OLD=main${{ matrix.suffix }}
|
||||
TAG_PR=${{ github.event.number == 0 && github.ref_name || format('pr-{0}', github.event.number) }}${{ matrix.suffix }}
|
||||
TAG_COMMIT=commit-${{ github.event_name != 'pull_request' && github.sha || github.event.pull_request.head.sha }}${{ matrix.suffix }}
|
||||
docker buildx imagetools create -t $REGISTRY_NAME/$REPOSITORY:$TAG_PR $REGISTRY_NAME/$REPOSITORY:$TAG_OLD
|
||||
docker buildx imagetools create -t $REGISTRY_NAME/$REPOSITORY:$TAG_COMMIT $REGISTRY_NAME/$REPOSITORY:$TAG_OLD
|
||||
docker buildx imagetools create -t "${REGISTRY_NAME}/${REPOSITORY}:${TAG_PR}" "${REGISTRY_NAME}/${REPOSITORY}:${TAG_OLD}"
|
||||
docker buildx imagetools create -t "${REGISTRY_NAME}/${REPOSITORY}:${TAG_COMMIT}" "${REGISTRY_NAME}/${REPOSITORY}:${TAG_OLD}"
|
||||
|
||||
retag_server:
|
||||
name: Re-Tag Server
|
||||
needs: pre-job
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
if: ${{ needs.pre-job.outputs.should_run_server == 'false' && !github.event.pull_request.head.repo.fork }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
@@ -83,18 +93,22 @@ jobs:
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Re-tag image
|
||||
env:
|
||||
REGISTRY_NAME: 'ghcr.io'
|
||||
REPOSITORY: ${{ github.repository_owner }}/immich-server
|
||||
TAG_OLD: main${{ matrix.suffix }}
|
||||
TAG_PR: ${{ github.event.number == 0 && github.ref_name || format('pr-{0}', github.event.number) }}${{ matrix.suffix }}
|
||||
TAG_COMMIT: commit-${{ github.event_name != 'pull_request' && github.sha || github.event.pull_request.head.sha }}${{ matrix.suffix }}
|
||||
run: |
|
||||
REGISTRY_NAME="ghcr.io"
|
||||
REPOSITORY=${{ github.repository_owner }}/immich-server
|
||||
TAG_OLD=main${{ matrix.suffix }}
|
||||
TAG_PR=${{ github.event.number == 0 && github.ref_name || format('pr-{0}', github.event.number) }}${{ matrix.suffix }}
|
||||
TAG_COMMIT=commit-${{ github.event_name != 'pull_request' && github.sha || github.event.pull_request.head.sha }}${{ matrix.suffix }}
|
||||
docker buildx imagetools create -t $REGISTRY_NAME/$REPOSITORY:$TAG_PR $REGISTRY_NAME/$REPOSITORY:$TAG_OLD
|
||||
docker buildx imagetools create -t $REGISTRY_NAME/$REPOSITORY:$TAG_COMMIT $REGISTRY_NAME/$REPOSITORY:$TAG_OLD
|
||||
docker buildx imagetools create -t "${REGISTRY_NAME}/${REPOSITORY}:${TAG_PR}" "${REGISTRY_NAME}/${REPOSITORY}:${TAG_OLD}"
|
||||
docker buildx imagetools create -t "${REGISTRY_NAME}/${REPOSITORY}:${TAG_COMMIT}" "${REGISTRY_NAME}/${REPOSITORY}:${TAG_OLD}"
|
||||
|
||||
build_and_push_ml:
|
||||
name: Build and Push ML
|
||||
needs: pre-job
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
if: ${{ needs.pre-job.outputs.should_run_ml == 'true' }}
|
||||
runs-on: ${{ matrix.runner }}
|
||||
env:
|
||||
@@ -148,6 +162,8 @@ jobs:
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
||||
@@ -161,11 +177,14 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Generate cache key suffix
|
||||
env:
|
||||
REF: ${{ github.ref_name }}
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
|
||||
echo "CACHE_KEY_SUFFIX=pr-${{ github.event.number }}" >> $GITHUB_ENV
|
||||
else
|
||||
echo "CACHE_KEY_SUFFIX=$(echo ${{ github.ref_name }} | sed 's/[^a-zA-Z0-9]/-/g')" >> $GITHUB_ENV
|
||||
SUFFIX=$(echo "${REF}" | sed 's/[^a-zA-Z0-9]/-/g')
|
||||
echo "CACHE_KEY_SUFFIX=${SUFFIX}" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Generate cache target
|
||||
@@ -175,17 +194,23 @@ jobs:
|
||||
# Essentially just ignore the cache output (forks can't write to registry cache)
|
||||
echo "cache-to=type=local,dest=/tmp/discard,ignore-error=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "cache-to=type=registry,ref=${{ env.GHCR_REPO }}-build-cache:${{ env.PLATFORM_PAIR }}-${{ matrix.device }}-${{ env.CACHE_KEY_SUFFIX }},mode=max,compression=zstd" >> $GITHUB_OUTPUT
|
||||
echo "cache-to=type=registry,ref=${GHCR_REPO}-build-cache:${PLATFORM_PAIR}-${{ matrix.device }}-${CACHE_KEY_SUFFIX},mode=max,compression=zstd" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Generate docker image tags
|
||||
id: meta
|
||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5
|
||||
env:
|
||||
DOCKER_METADATA_PR_HEAD_SHA: 'true'
|
||||
|
||||
- name: Build and push image
|
||||
id: build
|
||||
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
||||
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
|
||||
with:
|
||||
context: ${{ env.context }}
|
||||
file: ${{ env.file }}
|
||||
platforms: ${{ matrix.platforms }}
|
||||
labels: ${{ steps.metadata.outputs.labels }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-to: ${{ steps.cache-target.outputs.cache-to }}
|
||||
cache-from: |
|
||||
type=registry,ref=${{ env.GHCR_REPO }}-build-cache:${{ env.PLATFORM_PAIR }}-${{ matrix.device }}-${{ env.CACHE_KEY_SUFFIX }}
|
||||
@@ -199,7 +224,7 @@ jobs:
|
||||
BUILD_SOURCE_COMMIT=${{ github.sha }}
|
||||
|
||||
- name: Export digest
|
||||
run: |
|
||||
run: | # zizmor: ignore[template-injection]
|
||||
mkdir -p ${{ runner.temp }}/digests
|
||||
digest="${{ steps.build.outputs.digest }}"
|
||||
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
||||
@@ -215,6 +240,10 @@ jobs:
|
||||
merge_ml:
|
||||
name: Merge & Push ML
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
packages: write
|
||||
if: ${{ needs.pre-job.outputs.should_run_ml == 'true' && !github.event.pull_request.head.repo.fork }}
|
||||
env:
|
||||
GHCR_REPO: ghcr.io/${{ github.repository_owner }}/immich-machine-learning
|
||||
@@ -237,7 +266,7 @@ jobs:
|
||||
- build_and_push_ml
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
||||
with:
|
||||
path: ${{ runner.temp }}/digests
|
||||
pattern: ml-digests-${{ matrix.device }}-*
|
||||
@@ -287,12 +316,31 @@ jobs:
|
||||
- name: Create manifest list and push
|
||||
working-directory: ${{ runner.temp }}/digests
|
||||
run: |
|
||||
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||
$(printf '${{ env.GHCR_REPO }}@sha256:%s ' *)
|
||||
# Process annotations
|
||||
declare -a ANNOTATIONS=()
|
||||
if [[ -n "$DOCKER_METADATA_OUTPUT_JSON" ]]; then
|
||||
while IFS= read -r annotation; do
|
||||
# Extract key and value by removing the manifest: prefix
|
||||
if [[ "$annotation" =~ ^manifest:(.+)=(.+)$ ]]; then
|
||||
key="${BASH_REMATCH[1]}"
|
||||
value="${BASH_REMATCH[2]}"
|
||||
# Use array to properly handle arguments with spaces
|
||||
ANNOTATIONS+=(--annotation "index:$key=$value")
|
||||
fi
|
||||
done < <(jq -r '.annotations[]' <<< "$DOCKER_METADATA_OUTPUT_JSON")
|
||||
fi
|
||||
|
||||
TAGS=$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||
SOURCE_ARGS=$(printf "${GHCR_REPO}@sha256:%s " *)
|
||||
|
||||
docker buildx imagetools create $TAGS "${ANNOTATIONS[@]}" $SOURCE_ARGS
|
||||
|
||||
build_and_push_server:
|
||||
name: Build and Push Server
|
||||
runs-on: ${{ matrix.runner }}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
needs: pre-job
|
||||
if: ${{ needs.pre-job.outputs.should_run_server == 'true' }}
|
||||
env:
|
||||
@@ -316,6 +364,8 @@ jobs:
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3
|
||||
@@ -329,11 +379,14 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Generate cache key suffix
|
||||
env:
|
||||
REF: ${{ github.ref_name }}
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
|
||||
echo "CACHE_KEY_SUFFIX=pr-${{ github.event.number }}" >> $GITHUB_ENV
|
||||
else
|
||||
echo "CACHE_KEY_SUFFIX=$(echo ${{ github.ref_name }} | sed 's/[^a-zA-Z0-9]/-/g')" >> $GITHUB_ENV
|
||||
SUFFIX=$(echo "${REF}" | sed 's/[^a-zA-Z0-9]/-/g')
|
||||
echo "CACHE_KEY_SUFFIX=${SUFFIX}" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Generate cache target
|
||||
@@ -343,17 +396,23 @@ jobs:
|
||||
# Essentially just ignore the cache output (forks can't write to registry cache)
|
||||
echo "cache-to=type=local,dest=/tmp/discard,ignore-error=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "cache-to=type=registry,ref=${{ env.GHCR_REPO }}-build-cache:${{ env.PLATFORM_PAIR }}-${{ matrix.device }}-${{ env.CACHE_KEY_SUFFIX }},mode=max,compression=zstd" >> $GITHUB_OUTPUT
|
||||
echo "cache-to=type=registry,ref=${GHCR_REPO}-build-cache:${PLATFORM_PAIR}-${CACHE_KEY_SUFFIX},mode=max,compression=zstd" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Generate docker image tags
|
||||
id: meta
|
||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5
|
||||
env:
|
||||
DOCKER_METADATA_PR_HEAD_SHA: 'true'
|
||||
|
||||
- name: Build and push image
|
||||
id: build
|
||||
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
||||
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
|
||||
with:
|
||||
context: ${{ env.context }}
|
||||
file: ${{ env.file }}
|
||||
platforms: ${{ matrix.platform }}
|
||||
labels: ${{ steps.metadata.outputs.labels }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-to: ${{ steps.cache-target.outputs.cache-to }}
|
||||
cache-from: |
|
||||
type=registry,ref=${{ env.GHCR_REPO }}-build-cache:${{ env.PLATFORM_PAIR }}-${{ env.CACHE_KEY_SUFFIX }}
|
||||
@@ -367,7 +426,7 @@ jobs:
|
||||
BUILD_SOURCE_COMMIT=${{ github.sha }}
|
||||
|
||||
- name: Export digest
|
||||
run: |
|
||||
run: | # zizmor: ignore[template-injection]
|
||||
mkdir -p ${{ runner.temp }}/digests
|
||||
digest="${{ steps.build.outputs.digest }}"
|
||||
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
||||
@@ -383,6 +442,10 @@ jobs:
|
||||
merge_server:
|
||||
name: Merge & Push Server
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
packages: write
|
||||
if: ${{ needs.pre-job.outputs.should_run_server == 'true' && !github.event.pull_request.head.repo.fork }}
|
||||
env:
|
||||
GHCR_REPO: ghcr.io/${{ github.repository_owner }}/immich-server
|
||||
@@ -391,7 +454,7 @@ jobs:
|
||||
- build_and_push_server
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
||||
with:
|
||||
path: ${{ runner.temp }}/digests
|
||||
pattern: server-digests-*
|
||||
@@ -441,12 +504,29 @@ jobs:
|
||||
- name: Create manifest list and push
|
||||
working-directory: ${{ runner.temp }}/digests
|
||||
run: |
|
||||
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||
$(printf '${{ env.GHCR_REPO }}@sha256:%s ' *)
|
||||
# Process annotations
|
||||
declare -a ANNOTATIONS=()
|
||||
if [[ -n "$DOCKER_METADATA_OUTPUT_JSON" ]]; then
|
||||
while IFS= read -r annotation; do
|
||||
# Extract key and value by removing the manifest: prefix
|
||||
if [[ "$annotation" =~ ^manifest:(.+)=(.+)$ ]]; then
|
||||
key="${BASH_REMATCH[1]}"
|
||||
value="${BASH_REMATCH[2]}"
|
||||
# Use array to properly handle arguments with spaces
|
||||
ANNOTATIONS+=(--annotation "index:$key=$value")
|
||||
fi
|
||||
done < <(jq -r '.annotations[]' <<< "$DOCKER_METADATA_OUTPUT_JSON")
|
||||
fi
|
||||
|
||||
TAGS=$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||
SOURCE_ARGS=$(printf "${GHCR_REPO}@sha256:%s " *)
|
||||
|
||||
docker buildx imagetools create $TAGS "${ANNOTATIONS[@]}" $SOURCE_ARGS
|
||||
|
||||
success-check-server:
|
||||
name: Docker Build & Push Server Success
|
||||
needs: [merge_server, retag_server]
|
||||
permissions: {}
|
||||
runs-on: ubuntu-latest
|
||||
if: always()
|
||||
steps:
|
||||
@@ -455,11 +535,13 @@ jobs:
|
||||
run: exit 1
|
||||
- name: All jobs passed or skipped
|
||||
if: ${{ !(contains(needs.*.result, 'failure')) }}
|
||||
# zizmor: ignore[template-injection]
|
||||
run: echo "All jobs passed or skipped" && echo "${{ toJSON(needs.*.result) }}"
|
||||
|
||||
success-check-ml:
|
||||
name: Docker Build & Push ML Success
|
||||
needs: [merge_ml, retag_ml]
|
||||
permissions: {}
|
||||
runs-on: ubuntu-latest
|
||||
if: always()
|
||||
steps:
|
||||
@@ -468,4 +550,5 @@ jobs:
|
||||
run: exit 1
|
||||
- name: All jobs passed or skipped
|
||||
if: ${{ !(contains(needs.*.result, 'failure')) }}
|
||||
# zizmor: ignore[template-injection]
|
||||
run: echo "All jobs passed or skipped" && echo "${{ toJSON(needs.*.result) }}"
|
||||
|
||||
13
.github/workflows/docs-build.yml
vendored
13
.github/workflows/docs-build.yml
vendored
@@ -10,14 +10,20 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
pre-job:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
should_run: ${{ steps.found_paths.outputs.docs == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- id: found_paths
|
||||
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3
|
||||
with:
|
||||
@@ -33,6 +39,8 @@ jobs:
|
||||
build:
|
||||
name: Docs Build
|
||||
needs: pre-job
|
||||
permissions:
|
||||
contents: read
|
||||
if: ${{ needs.pre-job.outputs.should_run == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
@@ -42,9 +50,11 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version-file: './docs/.nvmrc'
|
||||
|
||||
@@ -62,4 +72,5 @@ jobs:
|
||||
with:
|
||||
name: docs-build-output
|
||||
path: docs/build/
|
||||
include-hidden-files: true
|
||||
retention-days: 1
|
||||
|
||||
34
.github/workflows/docs-deploy.yml
vendored
34
.github/workflows/docs-deploy.yml
vendored
@@ -1,6 +1,6 @@
|
||||
name: Docs deploy
|
||||
on:
|
||||
workflow_run:
|
||||
workflow_run: # zizmor: ignore[dangerous-triggers] no attacker inputs are used here
|
||||
workflows: ['Docs build']
|
||||
types:
|
||||
- completed
|
||||
@@ -9,6 +9,9 @@ jobs:
|
||||
checks:
|
||||
name: Docs Deploy Checks
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
pull-requests: read
|
||||
outputs:
|
||||
parameters: ${{ steps.parameters.outputs.result }}
|
||||
artifact: ${{ steps.get-artifact.outputs.result }}
|
||||
@@ -36,6 +39,8 @@ jobs:
|
||||
- name: Determine deploy parameters
|
||||
id: parameters
|
||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
env:
|
||||
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
||||
with:
|
||||
script: |
|
||||
const eventType = context.payload.workflow_run.event;
|
||||
@@ -57,7 +62,8 @@ jobs:
|
||||
} else if (eventType == "pull_request") {
|
||||
let pull_number = context.payload.workflow_run.pull_requests[0]?.number;
|
||||
if(!pull_number) {
|
||||
const response = await github.rest.search.issuesAndPullRequests({q: 'repo:${{ github.repository }} is:pr sha:${{ github.event.workflow_run.head_sha }}',per_page: 1,})
|
||||
const {HEAD_SHA} = process.env;
|
||||
const response = await github.rest.search.issuesAndPullRequests({q: `repo:${{ github.repository }} is:pr sha:${HEAD_SHA}`,per_page: 1,})
|
||||
const items = response.data.items
|
||||
if (items.length < 1) {
|
||||
throw new Error("No pull request found for the commit")
|
||||
@@ -95,30 +101,36 @@ jobs:
|
||||
name: Docs Deploy
|
||||
runs-on: ubuntu-latest
|
||||
needs: checks
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
pull-requests: write
|
||||
if: ${{ fromJson(needs.checks.outputs.artifact).found && fromJson(needs.checks.outputs.parameters).shouldDeploy }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Load parameters
|
||||
id: parameters
|
||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
env:
|
||||
PARAM_JSON: ${{ needs.checks.outputs.parameters }}
|
||||
with:
|
||||
script: |
|
||||
const json = `${{ needs.checks.outputs.parameters }}`;
|
||||
const parameters = JSON.parse(json);
|
||||
const parameters = JSON.parse(process.env.PARAM_JSON);
|
||||
core.setOutput("event", parameters.event);
|
||||
core.setOutput("name", parameters.name);
|
||||
core.setOutput("shouldDeploy", parameters.shouldDeploy);
|
||||
|
||||
- run: |
|
||||
echo "Starting docs deployment for ${{ steps.parameters.outputs.event }} ${{ steps.parameters.outputs.name }}"
|
||||
|
||||
- name: Download artifact
|
||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
env:
|
||||
ARTIFACT_JSON: ${{ needs.checks.outputs.artifact }}
|
||||
with:
|
||||
script: |
|
||||
let artifact = ${{ needs.checks.outputs.artifact }};
|
||||
let artifact = JSON.parse(process.env.ARTIFACT_JSON);
|
||||
let download = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
@@ -162,9 +174,11 @@ jobs:
|
||||
|
||||
- name: Output Cleaning
|
||||
id: clean
|
||||
env:
|
||||
TG_OUTPUT: ${{ steps.docs-output.outputs.tg_action_output }}
|
||||
run: |
|
||||
TG_OUT=$(echo '${{ steps.docs-output.outputs.tg_action_output }}' | sed 's|%0A|\n|g ; s|%3C|<|g' | jq -c .)
|
||||
echo "output=$TG_OUT" >> $GITHUB_OUTPUT
|
||||
CLEANED=$(echo "$TG_OUTPUT" | sed 's|%0A|\n|g ; s|%3C|<|g' | jq -c .)
|
||||
echo "output=$CLEANED" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Publish to Cloudflare Pages
|
||||
uses: cloudflare/pages-action@f0a1cd58cd66095dee69bfa18fa5efd1dde93bca # v1
|
||||
|
||||
9
.github/workflows/docs-destroy.yml
vendored
9
.github/workflows/docs-destroy.yml
vendored
@@ -1,15 +1,22 @@
|
||||
name: Docs destroy
|
||||
on:
|
||||
pull_request_target:
|
||||
pull_request_target: # zizmor: ignore[dangerous-triggers] no attacker inputs are used here
|
||||
types: [closed]
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
name: Docs Destroy
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Destroy Docs Subdomain
|
||||
env:
|
||||
|
||||
8
.github/workflows/fix-format.yml
vendored
8
.github/workflows/fix-format.yml
vendored
@@ -4,16 +4,19 @@ on:
|
||||
pull_request:
|
||||
types: [labeled]
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
fix-formatting:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.label.name == 'fix:formatting' }}
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Generate a token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@af35edadc00be37caa72ed9f3e6d5f7801bfdf09 # v1
|
||||
uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -23,9 +26,10 @@ jobs:
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.ref }}
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
persist-credentials: true
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version-file: './server/.nvmrc'
|
||||
|
||||
|
||||
4
.github/workflows/pr-label-validation.yml
vendored
4
.github/workflows/pr-label-validation.yml
vendored
@@ -1,9 +1,11 @@
|
||||
name: PR Label Validation
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
pull_request_target: # zizmor: ignore[dangerous-triggers] no attacker inputs are used here
|
||||
types: [opened, labeled, unlabeled, synchronize]
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
validate-release-label:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
4
.github/workflows/pr-labeler.yml
vendored
4
.github/workflows/pr-labeler.yml
vendored
@@ -1,6 +1,8 @@
|
||||
name: 'Pull Request Labeler'
|
||||
on:
|
||||
- pull_request_target
|
||||
- pull_request_target # zizmor: ignore[dangerous-triggers] no attacker inputs are used here
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
labeler:
|
||||
|
||||
@@ -4,9 +4,13 @@ on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, edited]
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
validate-pr-title:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: PR Conventional Commit Validation
|
||||
uses: ytanikin/PRConventionalCommits@b628c5a234cc32513014b7bfdd1e47b532124d98 # 1.3.0
|
||||
|
||||
35
.github/workflows/prepare-release.yml
vendored
35
.github/workflows/prepare-release.yml
vendored
@@ -21,17 +21,18 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-root
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
bump_version:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
ref: ${{ steps.push-tag.outputs.commit_long_sha }}
|
||||
|
||||
permissions: {} # No job-level permissions are needed because it uses the app-token
|
||||
steps:
|
||||
- name: Generate a token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@af35edadc00be37caa72ed9f3e6d5f7801bfdf09 # v1
|
||||
uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -40,12 +41,16 @@ jobs:
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
persist-credentials: true
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@22695119d769bdb6f7032ad67b9bca0ef8c4a174 # v5
|
||||
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5
|
||||
|
||||
- name: Bump version
|
||||
run: misc/release/pump-version.sh -s "${{ inputs.serverBump }}" -m "${{ inputs.mobileBump }}"
|
||||
env:
|
||||
SERVER_BUMP: ${{ inputs.serverBump }}
|
||||
MOBILE_BUMP: ${{ inputs.mobileBump }}
|
||||
run: misc/release/pump-version.sh -s "${SERVER_BUMP}" -m "${MOBILE_BUMP}"
|
||||
|
||||
- name: Commit and tag
|
||||
id: push-tag
|
||||
@@ -59,18 +64,26 @@ jobs:
|
||||
build_mobile:
|
||||
uses: ./.github/workflows/build-mobile.yml
|
||||
needs: bump_version
|
||||
secrets: inherit
|
||||
permissions:
|
||||
contents: read
|
||||
secrets:
|
||||
KEY_JKS: ${{ secrets.KEY_JKS }}
|
||||
ALIAS: ${{ secrets.ALIAS }}
|
||||
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
|
||||
ANDROID_STORE_PASSWORD: ${{ secrets.ANDROID_STORE_PASSWORD }}
|
||||
with:
|
||||
ref: ${{ needs.bump_version.outputs.ref }}
|
||||
|
||||
prepare_release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build_mobile
|
||||
|
||||
permissions:
|
||||
actions: read # To download the app artifact
|
||||
# No content permissions are needed because it uses the app-token
|
||||
steps:
|
||||
- name: Generate a token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@af35edadc00be37caa72ed9f3e6d5f7801bfdf09 # v1
|
||||
uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -79,17 +92,19 @@ jobs:
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Download APK
|
||||
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
||||
with:
|
||||
name: release-apk-signed
|
||||
|
||||
- name: Create draft release
|
||||
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2
|
||||
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2
|
||||
with:
|
||||
draft: true
|
||||
tag_name: ${{ env.IMMICH_VERSION }}
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
generate_release_notes: true
|
||||
body_path: misc/release/notes.tmpl
|
||||
files: |
|
||||
|
||||
2
.github/workflows/preview-label.yaml
vendored
2
.github/workflows/preview-label.yaml
vendored
@@ -4,6 +4,8 @@ on:
|
||||
pull_request:
|
||||
types: [labeled, closed]
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
comment-status:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
10
.github/workflows/sdk.yml
vendored
10
.github/workflows/sdk.yml
vendored
@@ -4,20 +4,24 @@ on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
permissions:
|
||||
packages: write
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: Publish `@immich/sdk`
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./open-api/typescript-sdk
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
# Setup .npmrc file to publish to npm
|
||||
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version-file: './open-api/typescript-sdk/.nvmrc'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
47
.github/workflows/static_analysis.yml
vendored
47
.github/workflows/static_analysis.yml
vendored
@@ -9,14 +9,20 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
pre-job:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
should_run: ${{ steps.found_paths.outputs.mobile == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- id: found_paths
|
||||
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3
|
||||
with:
|
||||
@@ -33,12 +39,14 @@ jobs:
|
||||
name: Run Dart Code Analysis
|
||||
needs: pre-job
|
||||
if: ${{ needs.pre-job.outputs.should_run == 'true' }}
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Flutter SDK
|
||||
uses: subosito/flutter-action@e938fdf56512cc96ef2f93601a5a40bde3801046 # v2
|
||||
@@ -50,6 +58,10 @@ jobs:
|
||||
run: dart pub get
|
||||
working-directory: ./mobile
|
||||
|
||||
- name: Generate translation file
|
||||
run: make translation; dart format lib/generated/codegen_loader.g.dart
|
||||
working-directory: ./mobile
|
||||
|
||||
- name: Run Build Runner
|
||||
run: make build
|
||||
working-directory: ./mobile
|
||||
@@ -65,9 +77,11 @@ jobs:
|
||||
|
||||
- name: Verify files have not changed
|
||||
if: steps.verify-changed-files.outputs.files_changed == 'true'
|
||||
env:
|
||||
CHANGED_FILES: ${{ steps.verify-changed-files.outputs.changed_files }}
|
||||
run: |
|
||||
echo "ERROR: Generated files not up to date! Run make_build inside the mobile directory"
|
||||
echo "Changed files: ${{ steps.verify-changed-files.outputs.changed_files }}"
|
||||
echo "Changed files: ${CHANGED_FILES}"
|
||||
exit 1
|
||||
|
||||
- name: Run dart analyze
|
||||
@@ -81,3 +95,30 @@ jobs:
|
||||
- name: Run dart custom_lint
|
||||
run: dart run custom_lint
|
||||
working-directory: ./mobile
|
||||
|
||||
zizmor:
|
||||
name: zizmor
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
actions: read
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install the latest version of uv
|
||||
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5
|
||||
|
||||
- name: Run zizmor 🌈
|
||||
run: uvx zizmor --format=sarif . > results.sarif
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Upload SARIF file
|
||||
uses: github/codeql-action/upload-sarif@28deaeda66b76a05916b6923827895f2b14ab387 # v3
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
category: zizmor
|
||||
|
||||
184
.github/workflows/test.yml
vendored
184
.github/workflows/test.yml
vendored
@@ -9,9 +9,13 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
pre-job:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
should_run_web: ${{ steps.found_paths.outputs.web == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
||||
should_run_server: ${{ steps.found_paths.outputs.server == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
||||
@@ -25,6 +29,9 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- id: found_paths
|
||||
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3
|
||||
with:
|
||||
@@ -58,6 +65,8 @@ jobs:
|
||||
needs: pre-job
|
||||
if: ${{ needs.pre-job.outputs.should_run_server == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./server
|
||||
@@ -65,9 +74,11 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version-file: './server/.nvmrc'
|
||||
|
||||
@@ -95,6 +106,8 @@ jobs:
|
||||
needs: pre-job
|
||||
if: ${{ needs.pre-job.outputs.should_run_cli == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./cli
|
||||
@@ -102,9 +115,11 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version-file: './cli/.nvmrc'
|
||||
|
||||
@@ -136,6 +151,8 @@ jobs:
|
||||
needs: pre-job
|
||||
if: ${{ needs.pre-job.outputs.should_run_cli == 'true' }}
|
||||
runs-on: windows-latest
|
||||
permissions:
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./cli
|
||||
@@ -143,9 +160,11 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version-file: './cli/.nvmrc'
|
||||
|
||||
@@ -165,11 +184,13 @@ jobs:
|
||||
run: npm run test:cov
|
||||
if: ${{ !cancelled() }}
|
||||
|
||||
web-unit-tests:
|
||||
name: Test & Lint Web
|
||||
web-lint:
|
||||
name: Lint Web
|
||||
needs: pre-job
|
||||
if: ${{ needs.pre-job.outputs.should_run_web == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: mich
|
||||
permissions:
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./web
|
||||
@@ -177,9 +198,11 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version-file: './web/.nvmrc'
|
||||
|
||||
@@ -191,7 +214,7 @@ jobs:
|
||||
run: npm ci
|
||||
|
||||
- name: Run linter
|
||||
run: npm run lint
|
||||
run: npm run lint:p
|
||||
if: ${{ !cancelled() }}
|
||||
|
||||
- name: Run formatter
|
||||
@@ -202,6 +225,35 @@ jobs:
|
||||
run: npm run check:svelte
|
||||
if: ${{ !cancelled() }}
|
||||
|
||||
web-unit-tests:
|
||||
name: Test Web
|
||||
needs: pre-job
|
||||
if: ${{ needs.pre-job.outputs.should_run_web == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./web
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version-file: './web/.nvmrc'
|
||||
|
||||
- name: Run setup typescript-sdk
|
||||
run: npm ci && npm run build
|
||||
working-directory: ./open-api/typescript-sdk
|
||||
|
||||
- name: Run npm install
|
||||
run: npm ci
|
||||
|
||||
- name: Run tsc
|
||||
run: npm run check:typescript
|
||||
if: ${{ !cancelled() }}
|
||||
@@ -215,6 +267,8 @@ jobs:
|
||||
needs: pre-job
|
||||
if: ${{ needs.pre-job.outputs.should_run_e2e == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./e2e
|
||||
@@ -222,9 +276,11 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version-file: './e2e/.nvmrc'
|
||||
|
||||
@@ -254,6 +310,8 @@ jobs:
|
||||
needs: pre-job
|
||||
if: ${{ needs.pre-job.outputs.should_run_server == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./server
|
||||
@@ -261,9 +319,11 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version-file: './server/.nvmrc'
|
||||
|
||||
@@ -278,19 +338,25 @@ jobs:
|
||||
name: End-to-End Tests (Server & CLI)
|
||||
needs: pre-job
|
||||
if: ${{ needs.pre-job.outputs.should_run_e2e_server_cli == 'true' }}
|
||||
runs-on: mich
|
||||
runs-on: ${{ matrix.runner }}
|
||||
permissions:
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./e2e
|
||||
strategy:
|
||||
matrix:
|
||||
runner: [mich, ubuntu-24.04-arm]
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: 'recursive'
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version-file: './e2e/.nvmrc'
|
||||
|
||||
@@ -320,19 +386,25 @@ jobs:
|
||||
name: End-to-End Tests (Web)
|
||||
needs: pre-job
|
||||
if: ${{ needs.pre-job.outputs.should_run_e2e_web == 'true' }}
|
||||
runs-on: mich
|
||||
runs-on: ${{ matrix.runner }}
|
||||
permissions:
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./e2e
|
||||
strategy:
|
||||
matrix:
|
||||
runner: [mich, ubuntu-24.04-arm]
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: 'recursive'
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version-file: './e2e/.nvmrc'
|
||||
|
||||
@@ -357,13 +429,33 @@ jobs:
|
||||
run: npx playwright test
|
||||
if: ${{ !cancelled() }}
|
||||
|
||||
success-check-e2e:
|
||||
name: End-to-End Tests Success
|
||||
needs: [e2e-tests-server-cli, e2e-tests-web]
|
||||
permissions: {}
|
||||
runs-on: ubuntu-latest
|
||||
if: always()
|
||||
steps:
|
||||
- name: Any jobs failed?
|
||||
if: ${{ contains(needs.*.result, 'failure') }}
|
||||
run: exit 1
|
||||
- name: All jobs passed or skipped
|
||||
if: ${{ !(contains(needs.*.result, 'failure')) }}
|
||||
# zizmor: ignore[template-injection]
|
||||
run: echo "All jobs passed or skipped" && echo "${{ toJSON(needs.*.result) }}"
|
||||
|
||||
mobile-unit-tests:
|
||||
name: Unit Test Mobile
|
||||
needs: pre-job
|
||||
if: ${{ needs.pre-job.outputs.should_run_mobile == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Flutter SDK
|
||||
uses: subosito/flutter-action@e938fdf56512cc96ef2f93601a5a40bde3801046 # v2
|
||||
with:
|
||||
@@ -378,14 +470,19 @@ jobs:
|
||||
needs: pre-job
|
||||
if: ${{ needs.pre-job.outputs.should_run_ml == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./machine-learning
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@22695119d769bdb6f7032ad67b9bca0ef8c4a174 # v5
|
||||
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5
|
||||
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5
|
||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
||||
# TODO: add caching when supported (https://github.com/actions/setup-python/pull/818)
|
||||
# with:
|
||||
# python-version: 3.11
|
||||
@@ -395,22 +492,24 @@ jobs:
|
||||
uv sync --extra cpu
|
||||
- name: Lint with ruff
|
||||
run: |
|
||||
uv run ruff check --output-format=github app export
|
||||
uv run ruff check --output-format=github immich_ml
|
||||
- name: Check black formatting
|
||||
run: |
|
||||
uv run black --check app export
|
||||
uv run black --check immich_ml
|
||||
- name: Run mypy type checking
|
||||
run: |
|
||||
uv run mypy --strict app/
|
||||
uv run mypy --strict immich_ml/
|
||||
- name: Run tests and coverage
|
||||
run: |
|
||||
uv run pytest app --cov=app --cov-report term-missing
|
||||
uv run pytest --cov=immich_ml --cov-report term-missing
|
||||
|
||||
github-files-formatting:
|
||||
name: .github Files Formatting
|
||||
needs: pre-job
|
||||
if: ${{ needs.pre-job.outputs['should_run_.github'] == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./.github
|
||||
@@ -418,9 +517,11 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version-file: './.github/.nvmrc'
|
||||
|
||||
@@ -434,25 +535,34 @@ jobs:
|
||||
shellcheck:
|
||||
name: ShellCheck
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Run ShellCheck
|
||||
uses: ludeeus/action-shellcheck@master
|
||||
with:
|
||||
ignore_paths: >-
|
||||
**/open-api/**
|
||||
**/openapi/**
|
||||
**/openapi**
|
||||
**/node_modules/**
|
||||
|
||||
generated-api-up-to-date:
|
||||
name: OpenAPI Clients
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version-file: './server/.nvmrc'
|
||||
|
||||
@@ -476,14 +586,18 @@ jobs:
|
||||
|
||||
- name: Verify files have not changed
|
||||
if: steps.verify-changed-files.outputs.files_changed == 'true'
|
||||
env:
|
||||
CHANGED_FILES: ${{ steps.verify-changed-files.outputs.changed_files }}
|
||||
run: |
|
||||
echo "ERROR: Generated files not up to date!"
|
||||
echo "Changed files: ${{ steps.verify-changed-files.outputs.changed_files }}"
|
||||
echo "Changed files: ${CHANGED_FILES}"
|
||||
exit 1
|
||||
|
||||
generated-typeorm-migrations-up-to-date:
|
||||
name: TypeORM Checks
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
services:
|
||||
postgres:
|
||||
image: tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52
|
||||
@@ -505,9 +619,11 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version-file: './server/.nvmrc'
|
||||
|
||||
@@ -518,27 +634,29 @@ jobs:
|
||||
run: npm run build
|
||||
|
||||
- name: Run existing migrations
|
||||
run: npm run typeorm:migrations:run
|
||||
run: npm run migrations:run
|
||||
|
||||
- name: Test npm run schema:reset command works
|
||||
run: npm run typeorm:schema:reset
|
||||
run: npm run schema:reset
|
||||
|
||||
- name: Generate new migrations
|
||||
continue-on-error: true
|
||||
run: npm run typeorm:migrations:generate ./src/migrations/TestMigration
|
||||
run: npm run migrations:generate TestMigration
|
||||
|
||||
- name: Find file changes
|
||||
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20
|
||||
id: verify-changed-files
|
||||
with:
|
||||
files: |
|
||||
server/src/migrations/
|
||||
server/src
|
||||
- name: Verify migration files have not changed
|
||||
if: steps.verify-changed-files.outputs.files_changed == 'true'
|
||||
env:
|
||||
CHANGED_FILES: ${{ steps.verify-changed-files.outputs.changed_files }}
|
||||
run: |
|
||||
echo "ERROR: Generated migration files not up to date!"
|
||||
echo "Changed files: ${{ steps.verify-changed-files.outputs.changed_files }}"
|
||||
cat ./src/migrations/*-TestMigration.ts
|
||||
echo "Changed files: ${CHANGED_FILES}"
|
||||
cat ./src/*-TestMigration.ts
|
||||
exit 1
|
||||
|
||||
- name: Run SQL generation
|
||||
@@ -555,9 +673,11 @@ jobs:
|
||||
|
||||
- name: Verify SQL files have not changed
|
||||
if: steps.verify-changed-sql-files.outputs.files_changed == 'true'
|
||||
env:
|
||||
CHANGED_FILES: ${{ steps.verify-changed-sql-files.outputs.changed_files }}
|
||||
run: |
|
||||
echo "ERROR: Generated SQL files not up to date!"
|
||||
echo "Changed files: ${{ steps.verify-changed-sql-files.outputs.changed_files }}"
|
||||
echo "Changed files: ${CHANGED_FILES}"
|
||||
exit 1
|
||||
|
||||
# mobile-integration-tests:
|
||||
|
||||
14
.github/workflows/weblate-lock.yml
vendored
14
.github/workflows/weblate-lock.yml
vendored
@@ -4,30 +4,32 @@ on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
pre-job:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
should_run: ${{ steps.found_paths.outputs.i18n == 'true' && github.head_ref != 'chore/translations'}}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- id: found_paths
|
||||
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3
|
||||
with:
|
||||
filters: |
|
||||
i18n:
|
||||
- 'i18n/!(en)**\.json'
|
||||
- name: Debug
|
||||
run: |
|
||||
echo "Should run: ${{ steps.found_paths.outputs.i18n == 'true' && github.head_ref != 'chore/translations'}}"
|
||||
echo "Found i18n paths: ${{ steps.found_paths.outputs.i18n }}"
|
||||
echo "Head ref: ${{ github.head_ref }}"
|
||||
|
||||
enforce-lock:
|
||||
name: Check Weblate Lock
|
||||
needs: [pre-job]
|
||||
runs-on: ubuntu-latest
|
||||
permissions: {}
|
||||
if: ${{ needs.pre-job.outputs.should_run == 'true' }}
|
||||
steps:
|
||||
- name: Check weblate lock
|
||||
@@ -47,6 +49,7 @@ jobs:
|
||||
name: Weblate Lock Check Success
|
||||
needs: [enforce-lock]
|
||||
runs-on: ubuntu-latest
|
||||
permissions: {}
|
||||
if: always()
|
||||
steps:
|
||||
- name: Any jobs failed?
|
||||
@@ -54,4 +57,5 @@ jobs:
|
||||
run: exit 1
|
||||
- name: All jobs passed or skipped
|
||||
if: ${{ !(contains(needs.*.result, 'failure')) }}
|
||||
# zizmor: ignore[template-injection]
|
||||
run: echo "All jobs passed or skipped" && echo "${{ toJSON(needs.*.result) }}"
|
||||
|
||||
77
.vscode/settings.json
vendored
77
.vscode/settings.json
vendored
@@ -1,44 +1,63 @@
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"[javascript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.tabSize": 2,
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.tabSize": 2,
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[css]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.tabSize": 2,
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[svelte]": {
|
||||
"editor.defaultFormatter": "svelte.svelte-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.tabSize": 2
|
||||
},
|
||||
"svelte.enable-ts-plugin": true,
|
||||
"eslint.validate": [
|
||||
"javascript",
|
||||
"svelte"
|
||||
],
|
||||
"typescript.preferences.importModuleSpecifier": "non-relative",
|
||||
"[dart]": {
|
||||
"editor.defaultFormatter": "Dart-Code.dart-code",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.selectionHighlight": false,
|
||||
"editor.suggest.snippetsPreventQuickSuggestions": false,
|
||||
"editor.suggestSelection": "first",
|
||||
"editor.tabCompletion": "onlySnippets",
|
||||
"editor.wordBasedSuggestions": "off",
|
||||
"editor.defaultFormatter": "Dart-Code.dart-code"
|
||||
"editor.wordBasedSuggestions": "off"
|
||||
},
|
||||
"cSpell.words": [
|
||||
"immich"
|
||||
],
|
||||
"[javascript]": {
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.organizeImports": "explicit",
|
||||
"source.removeUnusedImports": "explicit"
|
||||
},
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.tabSize": 2
|
||||
},
|
||||
"[json]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.tabSize": 2
|
||||
},
|
||||
"[jsonc]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.tabSize": 2
|
||||
},
|
||||
"[svelte]": {
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.organizeImports": "explicit",
|
||||
"source.removeUnusedImports": "explicit"
|
||||
},
|
||||
"editor.defaultFormatter": "svelte.svelte-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.tabSize": 2
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.organizeImports": "explicit",
|
||||
"source.removeUnusedImports": "explicit"
|
||||
},
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.tabSize": 2
|
||||
},
|
||||
"cSpell.words": ["immich"],
|
||||
"editor.formatOnSave": true,
|
||||
"eslint.validate": ["javascript", "svelte"],
|
||||
"explorer.fileNesting.enabled": true,
|
||||
"explorer.fileNesting.patterns": {
|
||||
"*.dart": "${capture}.g.dart,${capture}.gr.dart,${capture}.drift.dart",
|
||||
"*.ts": "${capture}.spec.ts,${capture}.mock.ts"
|
||||
}
|
||||
}
|
||||
},
|
||||
"svelte.enable-ts-plugin": true,
|
||||
"typescript.preferences.importModuleSpecifier": "non-relative"
|
||||
}
|
||||
|
||||
3
Makefile
3
Makefile
@@ -17,6 +17,9 @@ e2e:
|
||||
prod:
|
||||
docker compose -f ./docker/docker-compose.prod.yml up --build -V --remove-orphans
|
||||
|
||||
prod-down:
|
||||
docker compose -f ./docker/docker-compose.prod.yml down --remove-orphans
|
||||
|
||||
prod-scale:
|
||||
docker compose -f ./docker/docker-compose.prod.yml up --build -V --scale immich-server=3 --scale immich-microservices=3 --remove-orphans
|
||||
|
||||
|
||||
@@ -61,9 +61,7 @@
|
||||
|
||||
## Demo
|
||||
|
||||
Access the demo [here](https://demo.immich.app). The demo is running on a Free-tier Oracle VM in Amsterdam with a 2.4Ghz quad-core ARM64 CPU and 24GB RAM.
|
||||
|
||||
For the mobile app, you can use `https://demo.immich.app` for the `Server Endpoint URL`
|
||||
Access the demo [here](https://demo.immich.app). For the mobile app, you can use `https://demo.immich.app` for the `Server Endpoint URL`.
|
||||
|
||||
### Login credentials
|
||||
|
||||
@@ -104,7 +102,7 @@ For the mobile app, you can use `https://demo.immich.app` for the `Server Endpoi
|
||||
| Read-only gallery | Yes | Yes |
|
||||
| Stacked Photos | Yes | Yes |
|
||||
| Tags | No | Yes |
|
||||
| Folder View | No | Yes |
|
||||
| Folder View | Yes | Yes |
|
||||
|
||||
## Translations
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:22.14.0-alpine3.20@sha256:40be979442621049f40b1d51a26b55e281246b5de4e5f51a18da7beb6e17e3f9 AS core
|
||||
FROM node:22.15.0-alpine3.20@sha256:686b8892b69879ef5bfd6047589666933508f9a5451c67320df3070ba0e9807b AS core
|
||||
|
||||
WORKDIR /usr/src/open-api/typescript-sdk
|
||||
COPY open-api/typescript-sdk/package*.json open-api/typescript-sdk/tsconfig*.json ./
|
||||
|
||||
@@ -1,39 +1,29 @@
|
||||
import { FlatCompat } from '@eslint/eslintrc';
|
||||
import js from '@eslint/js';
|
||||
import typescriptEslint from '@typescript-eslint/eslint-plugin';
|
||||
import tsParser from '@typescript-eslint/parser';
|
||||
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
|
||||
import eslintPluginUnicorn from 'eslint-plugin-unicorn';
|
||||
import globals from 'globals';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import typescriptEslint from 'typescript-eslint';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: __dirname,
|
||||
recommendedConfig: js.configs.recommended,
|
||||
allConfig: js.configs.all,
|
||||
});
|
||||
|
||||
export default [
|
||||
export default typescriptEslint.config([
|
||||
eslintPluginUnicorn.configs.recommended,
|
||||
eslintPluginPrettierRecommended,
|
||||
js.configs.recommended,
|
||||
typescriptEslint.configs.recommended,
|
||||
{
|
||||
ignores: ['eslint.config.mjs', 'dist'],
|
||||
},
|
||||
...compat.extends(
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:prettier/recommended',
|
||||
'plugin:unicorn/recommended',
|
||||
),
|
||||
{
|
||||
plugins: {
|
||||
'@typescript-eslint': typescriptEslint,
|
||||
},
|
||||
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.node,
|
||||
},
|
||||
|
||||
parser: tsParser,
|
||||
parser: typescriptEslint.parser,
|
||||
ecmaVersion: 5,
|
||||
sourceType: 'module',
|
||||
|
||||
@@ -58,4 +48,4 @@ export default [
|
||||
'object-shorthand': ['error', 'always'],
|
||||
},
|
||||
},
|
||||
];
|
||||
]);
|
||||
|
||||
2065
cli/package-lock.json
generated
2065
cli/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@immich/cli",
|
||||
"version": "2.2.55",
|
||||
"version": "2.2.65",
|
||||
"description": "Command Line Interface (CLI) for Immich",
|
||||
"type": "module",
|
||||
"exports": "./dist/index.js",
|
||||
@@ -21,9 +21,7 @@
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/micromatch": "^4.0.9",
|
||||
"@types/mock-fs": "^4.13.1",
|
||||
"@types/node": "^22.13.10",
|
||||
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
||||
"@typescript-eslint/parser": "^8.15.0",
|
||||
"@types/node": "^22.14.1",
|
||||
"@vitest/coverage-v8": "^3.0.0",
|
||||
"byte-size": "^9.0.0",
|
||||
"cli-progress": "^3.12.0",
|
||||
@@ -31,12 +29,13 @@
|
||||
"eslint": "^9.14.0",
|
||||
"eslint-config-prettier": "^10.0.0",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"eslint-plugin-unicorn": "^56.0.1",
|
||||
"eslint-plugin-unicorn": "^57.0.0",
|
||||
"globals": "^16.0.0",
|
||||
"mock-fs": "^5.2.0",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-plugin-organize-imports": "^4.0.0",
|
||||
"typescript": "^5.3.3",
|
||||
"typescript-eslint": "^8.28.0",
|
||||
"vite": "^6.0.0",
|
||||
"vite-tsconfig-paths": "^5.0.0",
|
||||
"vitest": "^3.0.0",
|
||||
|
||||
@@ -33,6 +33,7 @@ services:
|
||||
- ${UPLOAD_LOCATION}/photos/upload:/usr/src/app/upload/upload
|
||||
- /usr/src/app/node_modules
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- ../flickr30k-images:/flickr30k:ro
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
@@ -58,7 +59,6 @@ services:
|
||||
- 9231:9231
|
||||
- 2283:2283
|
||||
depends_on:
|
||||
- redis
|
||||
- database
|
||||
healthcheck:
|
||||
disable: false
|
||||
@@ -114,12 +114,6 @@ services:
|
||||
healthcheck:
|
||||
disable: false
|
||||
|
||||
redis:
|
||||
container_name: immich_redis
|
||||
image: redis:6.2-alpine@sha256:148bb5411c184abd288d9aaed139c98123eeb8824c5d3fce03cf721db58066d8
|
||||
healthcheck:
|
||||
test: redis-cli ping || exit 1
|
||||
|
||||
database:
|
||||
container_name: immich_postgres
|
||||
image: tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52
|
||||
@@ -154,25 +148,25 @@ services:
|
||||
-c wal_compression=on
|
||||
|
||||
# set IMMICH_TELEMETRY_INCLUDE=all in .env to enable metrics
|
||||
# immich-prometheus:
|
||||
# container_name: immich_prometheus
|
||||
# ports:
|
||||
# - 9090:9090
|
||||
# image: prom/prometheus
|
||||
# volumes:
|
||||
# - ./prometheus.yml:/etc/prometheus/prometheus.yml
|
||||
# - prometheus-data:/prometheus
|
||||
immich-prometheus:
|
||||
container_name: immich_prometheus
|
||||
ports:
|
||||
- 9090:9090
|
||||
image: prom/prometheus
|
||||
volumes:
|
||||
- ./prometheus.yml:/etc/prometheus/prometheus.yml
|
||||
- prometheus-data:/prometheus
|
||||
|
||||
# first login uses admin/admin
|
||||
# add data source for http://immich-prometheus:9090 to get started
|
||||
# immich-grafana:
|
||||
# container_name: immich_grafana
|
||||
# command: ['./run.sh', '-disable-reporting']
|
||||
# ports:
|
||||
# - 3000:3000
|
||||
# image: grafana/grafana:10.3.3-ubuntu
|
||||
# volumes:
|
||||
# - grafana-data:/var/lib/grafana
|
||||
immich-grafana:
|
||||
container_name: immich_grafana
|
||||
command: ['./run.sh', '-disable-reporting']
|
||||
ports:
|
||||
- 3001:3000
|
||||
image: grafana/grafana:10.3.3-ubuntu
|
||||
volumes:
|
||||
- grafana-data:/var/lib/grafana
|
||||
|
||||
volumes:
|
||||
model-cache:
|
||||
|
||||
@@ -27,7 +27,6 @@ services:
|
||||
ports:
|
||||
- 2283:2283
|
||||
depends_on:
|
||||
- redis
|
||||
- database
|
||||
restart: always
|
||||
healthcheck:
|
||||
@@ -54,13 +53,6 @@ services:
|
||||
healthcheck:
|
||||
disable: false
|
||||
|
||||
redis:
|
||||
container_name: immich_redis
|
||||
image: redis:6.2-alpine@sha256:148bb5411c184abd288d9aaed139c98123eeb8824c5d3fce03cf721db58066d8
|
||||
healthcheck:
|
||||
test: redis-cli ping || exit 1
|
||||
restart: always
|
||||
|
||||
database:
|
||||
container_name: immich_postgres
|
||||
image: tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52
|
||||
@@ -90,7 +82,7 @@ services:
|
||||
container_name: immich_prometheus
|
||||
ports:
|
||||
- 9090:9090
|
||||
image: prom/prometheus@sha256:502ad90314c7485892ce696cb14a99fceab9fc27af29f4b427f41bd39701a199
|
||||
image: prom/prometheus@sha256:339ce86a59413be18d0e445472891d022725b4803fab609069110205e79fb2f1
|
||||
volumes:
|
||||
- ./prometheus.yml:/etc/prometheus/prometheus.yml
|
||||
- prometheus-data:/prometheus
|
||||
@@ -102,7 +94,7 @@ services:
|
||||
command: [ './run.sh', '-disable-reporting' ]
|
||||
ports:
|
||||
- 3000:3000
|
||||
image: grafana/grafana:11.5.2-ubuntu@sha256:8b5858c447e06fd7a89006b562ba7bba7c4d5813600c7982374c41852adefaeb
|
||||
image: grafana/grafana:11.6.1-ubuntu@sha256:6fc273288470ef499dd3c6b36aeade093170d4f608f864c5dd3a7fabeae77b50
|
||||
volumes:
|
||||
- grafana-data:/var/lib/grafana
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ services:
|
||||
ports:
|
||||
- '2283:2283'
|
||||
depends_on:
|
||||
- redis
|
||||
- database
|
||||
restart: always
|
||||
healthcheck:
|
||||
@@ -47,13 +46,6 @@ services:
|
||||
healthcheck:
|
||||
disable: false
|
||||
|
||||
redis:
|
||||
container_name: immich_redis
|
||||
image: docker.io/redis:6.2-alpine@sha256:148bb5411c184abd288d9aaed139c98123eeb8824c5d3fce03cf721db58066d8
|
||||
healthcheck:
|
||||
test: redis-cli ping || exit 1
|
||||
restart: always
|
||||
|
||||
database:
|
||||
container_name: immich_postgres
|
||||
image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
# The location where your uploaded files are stored
|
||||
UPLOAD_LOCATION=./library
|
||||
# The location where your database files are stored
|
||||
|
||||
# The location where your database files are stored. Network shares are not supported for the database
|
||||
DB_DATA_LOCATION=./postgres
|
||||
|
||||
# To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from this list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
global:
|
||||
scrape_interval: 15s
|
||||
evaluation_interval: 15s
|
||||
scrape_interval: 3s
|
||||
evaluation_interval: 3s
|
||||
|
||||
scrape_configs:
|
||||
- job_name: immich_api
|
||||
scrape_interval: 3s
|
||||
static_configs:
|
||||
- targets: ['immich-server:8081']
|
||||
- targets: ["immich-server:8081"]
|
||||
|
||||
- job_name: immich_microservices
|
||||
scrape_interval:
|
||||
static_configs:
|
||||
- targets: ['immich-server:8082']
|
||||
- targets: ["immich-server:8082"]
|
||||
|
||||
@@ -278,7 +278,7 @@ You can use [Smart Search](/docs/features/searching.md) for this to some extent.
|
||||
|
||||
### I'm getting a lot of "faces" that aren't faces, what can I do?
|
||||
|
||||
You can increase the MIN DETECTION SCORE to 0.8 to help prevent bad thumbnails. Setting the score too high (above 0.9) might filter out too many real faces depending on the library used. If you just want to hide specific faces, you can adjust the 'MIN FACES DETECTED' setting in the administration panel
|
||||
You can increase the MIN DETECTION SCORE to 0.8 to help prevent bad thumbnails. Setting the score too high (above 0.9) might filter out too many real faces depending on the library used. If you just want to hide specific faces, you can adjust the 'MIN FACES DETECTED' setting in the administration panel
|
||||
to increase the bar for what the algorithm considers a "core face" for that person, reducing the chance of bad thumbnails being chosen.
|
||||
|
||||
### The immich_model-cache volume takes up a lot of space, what could be the problem?
|
||||
@@ -367,12 +367,6 @@ You need to [enable WebSockets](/docs/administration/reverse-proxy/) on your rev
|
||||
|
||||
Immich components are typically deployed using docker. To see logs for deployed docker containers, you can use the [Docker CLI](https://docs.docker.com/engine/reference/commandline/cli/), specifically the `docker logs` command. For examples, see [Docker Help](/docs/guides/docker-help.md).
|
||||
|
||||
### How can I reduce the log verbosity of Redis?
|
||||
|
||||
To decrease Redis logs, you can add the following line to the `redis:` section of the `docker-compose.yml`:
|
||||
|
||||
` command: redis-server --loglevel warning`
|
||||
|
||||
### How can I run Immich as a non-root user?
|
||||
|
||||
You can change the user in the container by setting the `user` argument in `docker-compose.yml` for each service.
|
||||
@@ -380,7 +374,6 @@ You may need to add mount points or docker volumes for the following internal co
|
||||
|
||||
- `immich-machine-learning:/.config`
|
||||
- `immich-machine-learning:/.cache`
|
||||
- `redis:/data`
|
||||
|
||||
The non-root user/group needs read/write access to the volume mounts, including `UPLOAD_LOCATION` and `/cache` for machine-learning.
|
||||
|
||||
@@ -425,7 +418,7 @@ After removing the containers and volumes, there are a few directories that need
|
||||
- `UPLOAD_LOCATION` contains all the media uploaded to Immich.
|
||||
|
||||
:::note Portainer
|
||||
If you use portainer, bring down the stack in portainer. Go into the volumes section
|
||||
If you use portainer, bring down the stack in portainer. Go into the volumes section
|
||||
and remove all the volumes related to immich then restart the stack.
|
||||
:::
|
||||
|
||||
|
||||
@@ -23,23 +23,32 @@ Refer to the official [postgres documentation](https://www.postgresql.org/docs/c
|
||||
It is not recommended to directly backup the `DB_DATA_LOCATION` folder. Doing so while the database is running can lead to a corrupted backup that cannot be restored.
|
||||
:::
|
||||
|
||||
### Automatic Database Backups
|
||||
### Automatic Database Dumps
|
||||
|
||||
For convenience, Immich will automatically create database backups by default. The backups are stored in `UPLOAD_LOCATION/backups`.
|
||||
As mentioned above, you should make your own backup of these together with the asset folders as noted below.
|
||||
You can adjust the schedule and amount of kept backups in the [admin settings](http://my.immich.app/admin/system-settings?isOpen=backup).
|
||||
By default, Immich will keep the last 14 backups and create a new backup every day at 2:00 AM.
|
||||
:::warning
|
||||
The automatic database dumps can be used to restore the database in the event of damage to the Postgres database files.
|
||||
There is no monitoring for these dumps and you will not be notified if they are unsuccessful.
|
||||
:::
|
||||
|
||||
#### Trigger Backup
|
||||
:::caution
|
||||
The database dumps do **NOT** contain any pictures or videos, only metadata. They are only usable with a copy of the other files in `UPLOAD_LOCATION` as outlined below.
|
||||
:::
|
||||
|
||||
You are able to trigger a backup in the [admin job status page](http://my.immich.app/admin/jobs-status).
|
||||
Visit the page, open the "Create job" modal from the top right, select "Backup Database" and click "Confirm".
|
||||
A job will run and trigger a backup, you can verify this worked correctly by checking the logs or the backup folder.
|
||||
This backup will count towards the last X backups that will be kept based on your settings.
|
||||
For disaster-recovery purposes, Immich will automatically create database dumps. The dumps are stored in `UPLOAD_LOCATION/backups`.
|
||||
Please be sure to make your own, independent backup of the database together with the asset folders as noted below.
|
||||
You can adjust the schedule and amount of kept database dumps in the [admin settings](http://my.immich.app/admin/system-settings?isOpen=backup).
|
||||
By default, Immich will keep the last 14 database dumps and create a new dump every day at 2:00 AM.
|
||||
|
||||
#### Trigger Dump
|
||||
|
||||
You are able to trigger a database dump in the [admin job status page](http://my.immich.app/admin/jobs-status).
|
||||
Visit the page, open the "Create job" modal from the top right, select "Create Database Dump" and click "Confirm".
|
||||
A job will run and trigger a dump, you can verify this worked correctly by checking the logs or the `backups/` folder.
|
||||
This dumps will count towards the last `X` dumps that will be kept based on your settings.
|
||||
|
||||
#### Restoring
|
||||
|
||||
We hope to make restoring simpler in future versions, for now you can find the backups in the `UPLOAD_LOCATION/backups` folder on your host.
|
||||
We hope to make restoring simpler in future versions, for now you can find the database dumps in the `UPLOAD_LOCATION/backups` folder on your host.
|
||||
Then please follow the steps in the following section for restoring the database.
|
||||
|
||||
### Manual Backup and Restore
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 16 KiB |
@@ -31,7 +31,7 @@ Admin can send a welcome email if the Email option is set, you can learn here ho
|
||||
|
||||
Admin can specify the storage quota for the user as the instance's admin; once the limit is reached, the user won't be able to upload to the instance anymore.
|
||||
|
||||
In order to select a storage quota, click on the pencil icon and enter the storage quota in GiB. You can choose an unlimited quota using the value 0 (default).
|
||||
In order to select a storage quota, click on the pencil icon and enter the storage quota in GiB. You can choose an unlimited quota by leaving it empty (default).
|
||||
|
||||
:::tip
|
||||
The system administrator can see the usage quota percentage of all users in Server Stats page.
|
||||
|
||||
@@ -13,7 +13,7 @@ Immich uses a traditional client-server design, with a dedicated database for da
|
||||
|
||||
<img alt="Immich Architecture" src={AppArchitecture} className="p-4 dark:bg-immich-dark-primary my-4" />
|
||||
|
||||
The diagram shows clients communicating with the server's API via REST. The server communicates with downstream systems (i.e. Redis, Postgres, Machine Learning, file system) through repository interfaces. Not shown in the diagram, is that the server is split into two separate containers `immich-server` and `immich-microservices`. The microservices container does not handle API requests or schedule cron jobs, but primarily handles incoming job requests from Redis.
|
||||
The diagram shows clients communicating with the server's API via REST. The server communicates with downstream systems (i.e. Postgres, Machine Learning, file system) through repository interfaces. Not shown in the diagram, is that the server is split into two separate containers `immich-server` and `immich-microservices`. The microservices container does not handle API requests or schedule cron jobs, but primarily handles incoming job requests from Postgres.
|
||||
|
||||
## Clients
|
||||
|
||||
@@ -53,7 +53,6 @@ The Immich backend is divided into several services, which are run as individual
|
||||
1. `immich-server` - Handle and respond to REST API requests, execute background jobs (thumbnail generation, metadata extraction, transcoding, etc.)
|
||||
1. `immich-machine-learning` - Execute machine learning models
|
||||
1. `postgres` - Persistent data storage
|
||||
1. `redis`- Queue management for background jobs
|
||||
|
||||
### Immich Server
|
||||
|
||||
@@ -111,7 +110,3 @@ Immich persists data in Postgres, which includes information about access and au
|
||||
:::info
|
||||
See [Database Migrations](./database-migrations.md) for more information about how to modify the database to create an index, modify a table, add a new column, etc.
|
||||
:::
|
||||
|
||||
### Redis
|
||||
|
||||
Immich uses [Redis](https://redis.com/) via [BullMQ](https://docs.bullmq.io/) to manage job queues. Some jobs trigger subsequent jobs. For example, Smart Search and Facial Recognition relies on thumbnail generation and automatically run after one is generated.
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
# Database Migrations
|
||||
|
||||
After making any changes in the `server/src/entities`, a database migration need to run in order to register the changes in the database. Follow the steps below to create a new migration.
|
||||
After making any changes in the `server/src/schema`, a database migration need to run in order to register the changes in the database. Follow the steps below to create a new migration.
|
||||
|
||||
1. Run the command
|
||||
|
||||
```bash
|
||||
npm run typeorm:migrations:generate <migration-name>
|
||||
npm run migrations:generate <migration-name>
|
||||
```
|
||||
|
||||
2. Check if the migration file makes sense.
|
||||
3. Move the migration file to folder `./server/src/migrations` in your code editor.
|
||||
3. Move the migration file to folder `./server/src/schema/migrations` in your code editor.
|
||||
|
||||
The server will automatically detect `*.ts` file changes and restart. Part of the server start-up process includes running any new migrations, so it will be applied immediately.
|
||||
|
||||
@@ -23,7 +23,6 @@ This environment includes the services below. Additional details are available i
|
||||
- Server - [`/server`](https://github.com/immich-app/immich/tree/main/server)
|
||||
- Web app - [`/web`](https://github.com/immich-app/immich/tree/main/web)
|
||||
- Machine learning - [`/machine-learning`](https://github.com/immich-app/immich/tree/main/machine-learning)
|
||||
- Redis
|
||||
- PostgreSQL development database with exposed port `5432` so you can use any database client to access it
|
||||
|
||||
All the services are packaged to run as with single Docker Compose command.
|
||||
@@ -63,6 +62,13 @@ If you only want to do web development connected to an existing, remote backend,
|
||||
IMMICH_SERVER_URL=https://demo.immich.app/ npm run dev
|
||||
```
|
||||
|
||||
If you're using PowerShell on Windows you may need to set the env var separately like so:
|
||||
|
||||
```powershell
|
||||
$env:IMMICH_SERVER_URL = "https://demo.immich.app/"
|
||||
npm run dev
|
||||
```
|
||||
|
||||
#### `@immich/ui`
|
||||
|
||||
To see local changes to `@immich/ui` in Immich, do the following:
|
||||
@@ -76,9 +82,20 @@ To see local changes to `@immich/ui` in Immich, do the following:
|
||||
|
||||
### Mobile app
|
||||
|
||||
The mobile app `(/mobile)` will required Flutter toolchain 3.13.x and FVM to be installed on your system.
|
||||
#### Setup
|
||||
|
||||
Please refer to the [Flutter's official documentation](https://flutter.dev/docs/get-started/install) for more information on setting up the toolchain on your machine.
|
||||
1. Setup Flutter toolchain using FVM.
|
||||
2. Run `flutter pub get` to install the dependencies.
|
||||
3. Run `make translation` to generate the translation file.
|
||||
4. Run `fvm flutter run` to start the app.
|
||||
|
||||
#### Translation
|
||||
|
||||
To add a new translation text, enter the key-value pair in the `i18n/en.json` in the root of the immich project. Then, from the `mobile/` directory, run
|
||||
|
||||
```bash
|
||||
make translation
|
||||
```
|
||||
|
||||
The mobile app asks you what backend to connect to. You can utilize the demo backend (https://demo.immich.app/) if you don't need to change server code or upload photos. Alternatively, you can run the server yourself per the instructions above.
|
||||
|
||||
|
||||
@@ -42,6 +42,12 @@ docker run -it -v "$(pwd)":/import:ro -e IMMICH_INSTANCE_URL=https://your-immich
|
||||
|
||||
Please modify the `IMMICH_INSTANCE_URL` and `IMMICH_API_KEY` environment variables as suitable. You can also use a Docker env file to store your sensitive API key.
|
||||
|
||||
This `docker run` command will directly run the command `immich` inside the container. You can directly append the desired parameters (see under "usage") to the commandline like this:
|
||||
|
||||
```bash
|
||||
docker run -it -v "$(pwd)":/import:ro -e IMMICH_INSTANCE_URL=https://your-immich-instance/api -e IMMICH_API_KEY=your-api-key ghcr.io/immich-app/immich-cli:latest upload -a -c 5 --recursive directory/
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
<details>
|
||||
@@ -112,7 +118,7 @@ You begin by authenticating to your Immich server. For instance:
|
||||
immich login http://192.168.1.216:2283/api HFEJ38DNSDUEG
|
||||
```
|
||||
|
||||
This will store your credentials in a `auth.yml` file in the configuration directory which defaults to `~/.config/`. The directory can be set with the `-d` option or the environment variable `IMMICH_CONFIG_DIR`. Please keep the file secure, either by performing the logout command after you are done, or deleting it manually.
|
||||
This will store your credentials in a `auth.yml` file in the configuration directory which defaults to `~/.config/immich/`. The directory can be set with the `-d` option or the environment variable `IMMICH_CONFIG_DIR`. Please keep the file secure, either by performing the logout command after you are done, or deleting it manually.
|
||||
|
||||
Once you are authenticated, you can upload assets to your Immich server.
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 4.9 MiB After Width: | Height: | Size: 4.9 MiB |
@@ -42,7 +42,7 @@ You do not need to redo any machine learning jobs after enabling hardware accele
|
||||
|
||||
- The GPU must have compute capability 5.2 or greater.
|
||||
- The server must have the official NVIDIA driver installed.
|
||||
- The installed driver must be >= 535 (it must support CUDA 12.2).
|
||||
- The installed driver must be >= 545 (it must support CUDA 12.3).
|
||||
- On Linux (except for WSL2), you also need to have [NVIDIA Container Toolkit][nvct] installed.
|
||||
|
||||
#### ROCm
|
||||
@@ -71,7 +71,7 @@ You do not need to redo any machine learning jobs after enabling hardware accele
|
||||
|
||||
1. If you do not already have it, download the latest [`hwaccel.ml.yml`][hw-file] file and ensure it's in the same folder as the `docker-compose.yml`.
|
||||
2. In the `docker-compose.yml` under `immich-machine-learning`, uncomment the `extends` section and change `cpu` to the appropriate backend.
|
||||
3. Still in `immich-machine-learning`, add one of -[armnn, cuda, rocm, openvino] to the `image` section's tag at the end of the line.
|
||||
3. Still in `immich-machine-learning`, add one of -[armnn, cuda, rocm, openvino, rknn] to the `image` section's tag at the end of the line.
|
||||
4. Redeploy the `immich-machine-learning` container with these updated settings.
|
||||
|
||||
### Confirming Device Usage
|
||||
|
||||
@@ -45,7 +45,7 @@ Some search examples:
|
||||
</TabItem>
|
||||
<TabItem value="Mobile" label="Mobile">
|
||||
|
||||
<img src={require('./img/moblie-smart-serach.webp').default} width="30%" title='Smart search on mobile' />
|
||||
<img src={require('./img/mobile-smart-search.webp').default} width="30%" title='Smart search on mobile' />
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -56,7 +56,20 @@ Navigating to `Administration > Settings > Machine Learning Settings > Smart Sea
|
||||
|
||||
### CLIP models
|
||||
|
||||
More powerful models can be used for more accurate search results, but are slower and can require more server resources. Check the dropdowns below to see how they compare in memory usage, speed and quality by language.
|
||||
The default search model is fast, but there are many other options that can provide better search results. The tradeoff of using these models is that they're slower and/or use more memory (both when indexing images with background Smart Search jobs and when searching).
|
||||
|
||||
The first step of choosing the right model for you is to know which languages your users will search in.
|
||||
|
||||
If your users will only search in English, then the [CLIP][huggingface-clip] section is the first place to look. This is a curated list of the models that generally perform the best for their size class. The models here are ordered from higher to lower quality. This means that the top models will generally rank the most relevant results higher and have a higher capacity to understand descriptive, detailed, and/or niche queries. The models are also generally ordered from larger to smaller, so consider the impact on memory usage, job processing and search speed when deciding on one. The smaller models in this list are not too different in quality and many times faster.
|
||||
|
||||
[Multilingual models][huggingface-multilingual-clip] are also available so users can search in their native language. Use these models if you expect non-English searches to be common. They can be separated into two search patterns:
|
||||
|
||||
- `nllb` models expect the search query to be in the language specified in the user settings
|
||||
- `xlm` and `siglip2` models understand search text regardless of the current language setting
|
||||
|
||||
`nllb` models tend to perform the best and are recommended when users primarily searches in their native, non-English language. `xlm` and `siglip2` models are more flexible and are recommended for mixed language search, where the same user might search in different languages at different times.
|
||||
|
||||
For more details, check the tables below to see how they compare in memory usage, speed and quality by language.
|
||||
|
||||
Once you've chosen a model, follow these steps:
|
||||
|
||||
@@ -81,7 +94,7 @@ Memory and execution time estimates were obtained without acceleration on a 7800
|
||||
|
||||
**Memory (MiB)**: The peak RSS usage of the process afer performing the above timing benchmark. Does not include image decoding, concurrent processing, the web server, etc., which are relatively constant factors.
|
||||
|
||||
**Recall (%)**: Evaluated on Crossmodal-3600, the average of the recall@1, recall@5 and recall@10 results for zeroshot image retrieval.
|
||||
**Recall (%)**: Evaluated on Crossmodal-3600, the average of the recall@1, recall@5 and recall@10 results for zeroshot image retrieval. Chinese (Simplified), English, French, German, Italian, Japanese, Korean, Polish, Russian, Spanish and Turkish are additionally tested on XTD-10. Chinese (Simplified) and English are additionally tested on Flickr30k. The recall metrics are the average across all tested datasets.
|
||||
|
||||
**Pareto Optimal**: Whether the model is not completely outclassed by another model. Try to use models that are optimal for the languages relevant to you. Specifically, for a given model and language, if there's another model that's better for that language in at least one respect (memory usage, execution time, recall) while being at least as good for that language in every other way, then the model is not optimal for that language.
|
||||
|
||||
@@ -93,59 +106,59 @@ Memory and execution time estimates were obtained without acceleration on a 7800
|
||||
<summary>English</summary>
|
||||
| Model | Memory (MiB) | Execution Time (ms) | Recall (%) | Pareto Optimal |
|
||||
|------------------------------------------------------|--------------|---------------------|------------|----------------|
|
||||
| ViT-H-14-378-quickgelu__dfn5b | 5049 | 108.4 | 75.73 | ✅ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 75.44 | ✅ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 75.19 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 75.09 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 75.07 | ❌ |
|
||||
| ViT-H-14-quickgelu__dfn5b | 4701 | 38.74 | 75.01 | ❌ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 74.92 | ❌ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 74.9 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 74.87 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 74.87 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 74.77 | ❌ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 74.28 | ❌ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 74.26 | ✅ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 73.15 | ✅ |
|
||||
| ViT-L-14-quickgelu__dfn2b | 2212 | 20.49 | 72.78 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP-384__webli | 4417 | 72.19 | 72.58 | ❌ |
|
||||
| ViT-L-16-SigLIP-384__webli | 3396 | 47.6 | 72.57 | ❌ |
|
||||
| ViT-B-16-SigLIP-512__webli | 1828 | 26.17 | 72.47 | ✅ |
|
||||
| ViT-B-16-SigLIP-384__webli | 1128 | 13.53 | 72.45 | ✅ |
|
||||
| ViT-L-16-SigLIP-256__webli | 3160 | 23.84 | 72.44 | ❌ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 72.37 | ❌ |
|
||||
| ViT-B-16-SigLIP__webli | 1081 | 5.77 | 71.64 | ✅ |
|
||||
| ViT-B-16-SigLIP-256__webli | 1102 | 7.11 | 71.63 | ❌ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 71.45 | ❌ |
|
||||
| ViT-H-14__laion2b-s32b-b79k | 4676 | 39.06 | 71.33 | ❌ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 71.19 | ❌ |
|
||||
| ViT-L-14__laion2b-s32b-b82k | 2233 | 20.56 | 69.86 | ❌ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 69.66 | ❌ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 69.38 | ❌ |
|
||||
| ViT-B-32__laion2b-s34b-b79k | 1001 | 2.29 | 68.78 | ✅ |
|
||||
| ViT-L-14__laion400m_e31 | 2183 | 19.87 | 68.53 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e32 | 1246 | 6.95 | 68.53 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e31 | 1263 | 6.94 | 68.53 | ❌ |
|
||||
| ViT-L-14__laion400m_e32 | 2218 | 19.73 | 68.51 | ❌ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 68.41 | ❌ |
|
||||
| ViT-B-32__laion2b_e16 | 1004 | 2.38 | 68.41 | ❌ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 68.33 | ❌ |
|
||||
| ViT-B-16__laion400m_e31 | 991 | 5.04 | 66.96 | ✅ |
|
||||
| ViT-B-16__laion400m_e32 | 975 | 4.98 | 66.95 | ✅ |
|
||||
| ViT-B-32__laion400m_e31 | 999 | 2.28 | 65.65 | ✅ |
|
||||
| ViT-B-32__laion400m_e32 | 1003 | 2.35 | 65.49 | ❌ |
|
||||
| ViT-L-14__openai | 2212 | 19.91 | 60.12 | ❌ |
|
||||
| ViT-B-32__openai | 1004 | 2.26 | 59.37 | ✅ |
|
||||
| RN50x64__openai | 5079 | 48.79 | 59.36 | ❌ |
|
||||
| RN50x16__openai | 2221 | 15.87 | 59.17 | ❌ |
|
||||
| ViT-L-14-336__openai | 2616 | 43.45 | 59.09 | ❌ |
|
||||
| RN50__openai | 913 | 2.39 | 58.32 | ✅ |
|
||||
| ViT-B-16__openai | 985 | 5.03 | 58.27 | ❌ |
|
||||
| RN50x4__openai | 1416 | 5.85 | 57.88 | ❌ |
|
||||
| RN50__cc12m | 914 | 2.37 | 57.75 | ✅ |
|
||||
| RN101__openai | 1111 | 3.21 | 57.7 | ❌ |
|
||||
| RN101__yfcc15m | 1111 | 3.22 | 50.11 | ❌ |
|
||||
| RN50__yfcc15m | 908 | 2.34 | 48.28 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 85.99 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 85.96 | ❌ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 85.96 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 85.93 | ❌ |
|
||||
| ViT-H-14-378-quickgelu__dfn5b | 5049 | 108.4 | 85.78 | ❌ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 85.75 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 85.62 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 85.53 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 85.48 | ❌ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 85.47 | ✅ |
|
||||
| ViT-H-14-quickgelu__dfn5b | 4701 | 38.74 | 85.09 | ❌ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 85.03 | ✅ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 84.86 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP-384__webli | 4417 | 72.19 | 84.61 | ❌ |
|
||||
| ViT-L-16-SigLIP-384__webli | 3396 | 47.6 | 84.17 | ❌ |
|
||||
| ViT-L-16-SigLIP-256__webli | 3160 | 23.84 | 83.51 | ❌ |
|
||||
| ViT-B-16-SigLIP-512__webli | 1828 | 26.17 | 83.28 | ✅ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 83.24 | ❌ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 83.23 | ❌ |
|
||||
| ViT-B-16-SigLIP-384__webli | 1128 | 13.53 | 83.19 | ✅ |
|
||||
| ViT-L-14-quickgelu__dfn2b | 2212 | 20.49 | 82.54 | ❌ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 82.43 | ❌ |
|
||||
| ViT-H-14__laion2b-s32b-b79k | 4676 | 39.06 | 82.36 | ❌ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 82.28 | ✅ |
|
||||
| ViT-B-16-SigLIP__webli | 1081 | 5.77 | 81.9 | ✅ |
|
||||
| ViT-B-16-SigLIP-256__webli | 1102 | 7.11 | 81.9 | ❌ |
|
||||
| ViT-L-14__laion2b-s32b-b82k | 2233 | 20.56 | 80.82 | ❌ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 80.65 | ❌ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 80.16 | ❌ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 79.78 | ❌ |
|
||||
| ViT-L-14__laion400m_e31 | 2183 | 19.87 | 78.64 | ❌ |
|
||||
| ViT-L-14__laion400m_e32 | 2218 | 19.73 | 78.6 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e32 | 1246 | 6.95 | 78.06 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e31 | 1263 | 6.94 | 78.06 | ❌ |
|
||||
| ViT-B-32__laion2b-s34b-b79k | 1001 | 2.29 | 77.62 | ✅ |
|
||||
| ViT-B-32__laion2b_e16 | 1004 | 2.38 | 77.47 | ❌ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 76.91 | ❌ |
|
||||
| ViT-B-16__laion400m_e32 | 975 | 4.98 | 76.43 | ✅ |
|
||||
| ViT-B-16__laion400m_e31 | 991 | 5.04 | 76.35 | ❌ |
|
||||
| ViT-B-32__laion400m_e31 | 999 | 2.28 | 73.83 | ✅ |
|
||||
| ViT-B-32__laion400m_e32 | 1003 | 2.35 | 73.62 | ❌ |
|
||||
| RN50x64__openai | 5079 | 48.79 | 73.34 | ❌ |
|
||||
| ViT-L-14__openai | 2212 | 19.91 | 72.99 | ❌ |
|
||||
| ViT-L-14-336__openai | 2616 | 43.45 | 72.76 | ❌ |
|
||||
| RN50x16__openai | 2221 | 15.87 | 72.59 | ❌ |
|
||||
| RN50x4__openai | 1416 | 5.85 | 70.8 | ❌ |
|
||||
| ViT-B-16__openai | 985 | 5.03 | 70.01 | ❌ |
|
||||
| ViT-B-32__openai | 1004 | 2.26 | 69.9 | ✅ |
|
||||
| RN101__openai | 1111 | 3.21 | 69.3 | ❌ |
|
||||
| RN50__openai | 913 | 2.39 | 69.02 | ✅ |
|
||||
| RN50__cc12m | 914 | 2.37 | 64.59 | ✅ |
|
||||
| RN101__yfcc15m | 1111 | 3.22 | 55.21 | ❌ |
|
||||
| RN50__yfcc15m | 908 | 2.34 | 53.63 | ✅ |
|
||||
</details>
|
||||
<details>
|
||||
<summary>Arabic</summary>
|
||||
@@ -156,8 +169,8 @@ Memory and execution time estimates were obtained without acceleration on a 7800
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 74.03 | ✅ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 73.19 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 69.31 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 69.29 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 69.29 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 69.29 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 68.64 | ✅ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 68.35 | ✅ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 68.25 | ✅ |
|
||||
@@ -195,25 +208,25 @@ Memory and execution time estimates were obtained without acceleration on a 7800
|
||||
<summary>Chinese (Simplified)</summary>
|
||||
| Model | Memory (MiB) | Execution Time (ms) | Recall (%) | Pareto Optimal |
|
||||
|------------------------------------------------------|--------------|---------------------|------------|----------------|
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 77.49 | ✅ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 77.19 | ✅ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 76.98 | ❌ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 72.89 | ✅ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 72.65 | ✅ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 72.52 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 67.83 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 67.81 | ❌ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 67.51 | ❌ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 67.39 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 67.33 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 67.23 | ❌ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 67.05 | ❌ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 66.87 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 66.24 | ❌ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 66.1 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 65.56 | ❌ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 64.39 | ❌ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 62.56 | ❌ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 79.7 | ✅ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 78.94 | ❌ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 75.22 | ✅ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 74.8 | ✅ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 73.91 | ❌ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 72.8 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 72.77 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 72.41 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 72.36 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 71.59 | ❌ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 71.37 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 71.3 | ✅ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 71.11 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 70.95 | ✅ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 70.51 | ✅ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 67.48 | ✅ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 66.84 | ✅ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 65.7 | ✅ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 63.38 | ❌ |
|
||||
</details>
|
||||
<details>
|
||||
<summary>Croatian</summary>
|
||||
@@ -324,8 +337,8 @@ Memory and execution time estimates were obtained without acceleration on a 7800
|
||||
|------------------------------------------------------|--------------|---------------------|------------|----------------|
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 80.05 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 79.81 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 79.72 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 79.72 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 79.72 | ❌ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 79.64 | ✅ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 79.49 | ✅ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 79.41 | ❌ |
|
||||
@@ -357,8 +370,8 @@ Memory and execution time estimates were obtained without acceleration on a 7800
|
||||
| ViT-L-14__laion400m_e32 | 2218 | 19.73 | 29.56 | ❌ |
|
||||
| ViT-B-32__laion2b-s34b-b79k | 1001 | 2.29 | 29.54 | ✅ |
|
||||
| ViT-B-32__laion2b_e16 | 1004 | 2.38 | 29.36 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e31 | 1263 | 6.94 | 27.76 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e32 | 1246 | 6.95 | 27.76 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e31 | 1263 | 6.94 | 27.76 | ❌ |
|
||||
| ViT-B-16__laion400m_e32 | 975 | 4.98 | 25.67 | ✅ |
|
||||
| ViT-B-32__laion400m_e32 | 1003 | 2.35 | 25.59 | ❌ |
|
||||
| ViT-B-16__laion400m_e31 | 991 | 5.04 | 25.53 | ❌ |
|
||||
@@ -384,8 +397,8 @@ Memory and execution time estimates were obtained without acceleration on a 7800
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 34.27 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 34.14 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 33.98 | ❌ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 30.57 | ❌ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 30.57 | ❌ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 30.57 | ❌ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 30.05 | ✅ |
|
||||
| ViT-L-16-SigLIP-384__webli | 3396 | 47.6 | 24.92 | ❌ |
|
||||
| ViT-L-16-SigLIP-256__webli | 3160 | 23.84 | 24.02 | ❌ |
|
||||
@@ -422,110 +435,111 @@ Memory and execution time estimates were obtained without acceleration on a 7800
|
||||
<summary>French</summary>
|
||||
| Model | Memory (MiB) | Execution Time (ms) | Recall (%) | Pareto Optimal |
|
||||
|------------------------------------------------------|--------------|---------------------|------------|----------------|
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 88.01 | ✅ |
|
||||
| ViT-H-14-378-quickgelu__dfn5b | 5049 | 108.4 | 87.74 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 87.69 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 87.6 | ✅ |
|
||||
| ViT-H-14-quickgelu__dfn5b | 4701 | 38.74 | 87.58 | ✅ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 87.51 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 87.23 | ❌ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 86.9 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 86.9 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 86.44 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 86.44 | ❌ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 86.28 | ❌ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 86.11 | ❌ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 86.08 | ✅ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 84.49 | ❌ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 84.3 | ✅ |
|
||||
| ViT-L-14-quickgelu__dfn2b | 2212 | 20.49 | 83.03 | ✅ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 82.93 | ❌ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 82.27 | ✅ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 82.14 | ❌ |
|
||||
| ViT-L-16-SigLIP-384__webli | 3396 | 47.6 | 80.96 | ❌ |
|
||||
| ViT-L-16-SigLIP-256__webli | 3160 | 23.84 | 80.64 | ❌ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 80.28 | ✅ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 79.65 | ✅ |
|
||||
| ViT-B-16-SigLIP-512__webli | 1828 | 26.17 | 77.4 | ✅ |
|
||||
| ViT-B-16-SigLIP-384__webli | 1128 | 13.53 | 76.88 | ✅ |
|
||||
| ViT-B-16-SigLIP__webli | 1081 | 5.77 | 76.3 | ✅ |
|
||||
| ViT-B-16-SigLIP-256__webli | 1102 | 7.11 | 75.68 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP-384__webli | 4417 | 72.19 | 69.59 | ❌ |
|
||||
| ViT-H-14__laion2b-s32b-b79k | 4676 | 39.06 | 68.36 | ❌ |
|
||||
| ViT-L-14__laion2b-s32b-b82k | 2233 | 20.56 | 61.78 | ❌ |
|
||||
| ViT-L-14__laion400m_e32 | 2218 | 19.73 | 58.4 | ❌ |
|
||||
| ViT-L-14__laion400m_e31 | 2183 | 19.87 | 58.35 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e31 | 1263 | 6.94 | 57.17 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e32 | 1246 | 6.95 | 57.17 | ❌ |
|
||||
| ViT-B-32__laion2b_e16 | 1004 | 2.38 | 57.05 | ✅ |
|
||||
| ViT-B-32__laion2b-s34b-b79k | 1001 | 2.29 | 56.08 | ✅ |
|
||||
| ViT-B-16__laion400m_e31 | 991 | 5.04 | 52.96 | ✅ |
|
||||
| ViT-B-16__laion400m_e32 | 975 | 4.98 | 52.83 | ✅ |
|
||||
| ViT-B-32__laion400m_e32 | 1003 | 2.35 | 51.88 | ❌ |
|
||||
| ViT-B-32__laion400m_e31 | 999 | 2.28 | 51.82 | ✅ |
|
||||
| RN50x64__openai | 5079 | 48.79 | 42.86 | ❌ |
|
||||
| ViT-L-14-336__openai | 2616 | 43.45 | 42.81 | ❌ |
|
||||
| ViT-L-14__openai | 2212 | 19.91 | 42.54 | ❌ |
|
||||
| RN50x16__openai | 2221 | 15.87 | 41.72 | ❌ |
|
||||
| RN50x4__openai | 1416 | 5.85 | 38.85 | ❌ |
|
||||
| RN101__openai | 1111 | 3.21 | 36.79 | ❌ |
|
||||
| ViT-B-16__openai | 985 | 5.03 | 36.47 | ❌ |
|
||||
| ViT-B-32__openai | 1004 | 2.26 | 35.17 | ✅ |
|
||||
| RN50__openai | 913 | 2.39 | 34.44 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 86.5 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 86.5 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 86.39 | ❌ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 86.15 | ❌ |
|
||||
| ViT-H-14-378-quickgelu__dfn5b | 5049 | 108.4 | 86.1 | ❌ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 86.07 | ❌ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 86.06 | ❌ |
|
||||
| ViT-H-14-quickgelu__dfn5b | 4701 | 38.74 | 85.89 | ✅ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 85.67 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 85.67 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 85.63 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 85.39 | ✅ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 85.35 | ✅ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 84.97 | ✅ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 83.8 | ✅ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 82.96 | ❌ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 82.91 | ✅ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 82.52 | ❌ |
|
||||
| ViT-L-14-quickgelu__dfn2b | 2212 | 20.49 | 81.21 | ✅ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 80.23 | ✅ |
|
||||
| ViT-L-16-SigLIP-384__webli | 3396 | 47.6 | 79.85 | ❌ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 79.47 | ✅ |
|
||||
| ViT-L-16-SigLIP-256__webli | 3160 | 23.84 | 79.3 | ❌ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 77.49 | ✅ |
|
||||
| ViT-B-16-SigLIP-512__webli | 1828 | 26.17 | 76.82 | ✅ |
|
||||
| ViT-B-16-SigLIP-384__webli | 1128 | 13.53 | 75.94 | ✅ |
|
||||
| ViT-B-16-SigLIP__webli | 1081 | 5.77 | 75.3 | ✅ |
|
||||
| ViT-B-16-SigLIP-256__webli | 1102 | 7.11 | 75.24 | ❌ |
|
||||
| ViT-H-14__laion2b-s32b-b79k | 4676 | 39.06 | 69.33 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP-384__webli | 4417 | 72.19 | 64.41 | ❌ |
|
||||
| ViT-L-14__laion2b-s32b-b82k | 2233 | 20.56 | 62.86 | ❌ |
|
||||
| ViT-L-14__laion400m_e32 | 2218 | 19.73 | 59.27 | ❌ |
|
||||
| ViT-L-14__laion400m_e31 | 2183 | 19.87 | 59.09 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e32 | 1246 | 6.95 | 58.25 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e31 | 1263 | 6.94 | 58.25 | ❌ |
|
||||
| ViT-B-32__laion2b_e16 | 1004 | 2.38 | 56.97 | ✅ |
|
||||
| ViT-B-32__laion2b-s34b-b79k | 1001 | 2.29 | 56.21 | ✅ |
|
||||
| ViT-B-32__laion400m_e31 | 999 | 2.28 | 53.36 | ✅ |
|
||||
| ViT-B-16__laion400m_e32 | 975 | 4.98 | 53.33 | ✅ |
|
||||
| ViT-B-16__laion400m_e31 | 991 | 5.04 | 53.26 | ❌ |
|
||||
| ViT-B-32__laion400m_e32 | 1003 | 2.35 | 53.22 | ❌ |
|
||||
| ViT-L-14__openai | 2212 | 19.91 | 46.34 | ❌ |
|
||||
| RN50x64__openai | 5079 | 48.79 | 46.3 | ❌ |
|
||||
| ViT-L-14-336__openai | 2616 | 43.45 | 45.95 | ❌ |
|
||||
| RN50x16__openai | 2221 | 15.87 | 45.69 | ❌ |
|
||||
| RN50x4__openai | 1416 | 5.85 | 42.48 | ❌ |
|
||||
| RN101__openai | 1111 | 3.21 | 40.16 | ❌ |
|
||||
| ViT-B-16__openai | 985 | 5.03 | 40.1 | ❌ |
|
||||
| ViT-B-32__openai | 1004 | 2.26 | 38.27 | ✅ |
|
||||
| RN50__openai | 913 | 2.39 | 37.8 | ✅ |
|
||||
</details>
|
||||
<details>
|
||||
<summary>German</summary>
|
||||
| Model | Memory (MiB) | Execution Time (ms) | Recall (%) | Pareto Optimal |
|
||||
|------------------------------------------------------|--------------|---------------------|------------|----------------|
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 90.04 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 89.97 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 89.85 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 89.81 | ✅ |
|
||||
| ViT-H-14-378-quickgelu__dfn5b | 5049 | 108.4 | 89.77 | ❌ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 89.69 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 89.45 | ✅ |
|
||||
| ViT-H-14-quickgelu__dfn5b | 4701 | 38.74 | 89.44 | ❌ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 89.39 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 89.35 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 89.03 | ❌ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 88.82 | ✅ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 88.55 | ❌ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 88.42 | ❌ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 87.19 | ❌ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 86.44 | ✅ |
|
||||
| ViT-L-14-quickgelu__dfn2b | 2212 | 20.49 | 84.81 | ✅ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 84.81 | ❌ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 84.58 | ❌ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 84.44 | ✅ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 83.33 | ✅ |
|
||||
| ViT-L-16-SigLIP-384__webli | 3396 | 47.6 | 82.75 | ❌ |
|
||||
| ViT-L-16-SigLIP-256__webli | 3160 | 23.84 | 82.32 | ❌ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 81.63 | ✅ |
|
||||
| ViT-B-16-SigLIP-512__webli | 1828 | 26.17 | 76.76 | ✅ |
|
||||
| ViT-B-16-SigLIP-384__webli | 1128 | 13.53 | 76.33 | ✅ |
|
||||
| ViT-B-16-SigLIP__webli | 1081 | 5.77 | 75.19 | ✅ |
|
||||
| ViT-B-16-SigLIP-256__webli | 1102 | 7.11 | 75.07 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP-384__webli | 4417 | 72.19 | 64.61 | ❌ |
|
||||
| ViT-H-14__laion2b-s32b-b79k | 4676 | 39.06 | 52.81 | ❌ |
|
||||
| ViT-L-14__laion2b-s32b-b82k | 2233 | 20.56 | 42.88 | ❌ |
|
||||
| ViT-L-14__laion400m_e32 | 2218 | 19.73 | 38.65 | ❌ |
|
||||
| ViT-L-14__laion400m_e31 | 2183 | 19.87 | 38.37 | ❌ |
|
||||
| ViT-B-32__laion2b_e16 | 1004 | 2.38 | 37.65 | ✅ |
|
||||
| ViT-B-32__laion2b-s34b-b79k | 1001 | 2.29 | 36.6 | ✅ |
|
||||
| ViT-B-16-plus-240__laion400m_e31 | 1263 | 6.94 | 35.44 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e32 | 1246 | 6.95 | 35.44 | ❌ |
|
||||
| ViT-B-16__laion400m_e31 | 991 | 5.04 | 32.46 | ✅ |
|
||||
| ViT-B-16__laion400m_e32 | 975 | 4.98 | 32.31 | ✅ |
|
||||
| ViT-B-32__laion400m_e31 | 999 | 2.28 | 31.85 | ✅ |
|
||||
| ViT-B-32__laion400m_e32 | 1003 | 2.35 | 31.81 | ❌ |
|
||||
| RN50x64__openai | 5079 | 48.79 | 28.41 | ❌ |
|
||||
| ViT-L-14__openai | 2212 | 19.91 | 27.63 | ❌ |
|
||||
| ViT-L-14-336__openai | 2616 | 43.45 | 27.09 | ❌ |
|
||||
| RN50x16__openai | 2221 | 15.87 | 24.48 | ❌ |
|
||||
| RN50x4__openai | 1416 | 5.85 | 23.49 | ❌ |
|
||||
| RN50__openai | 913 | 2.39 | 20.91 | ✅ |
|
||||
| ViT-B-16__openai | 985 | 5.03 | 20.83 | ❌ |
|
||||
| RN101__openai | 1111 | 3.21 | 20.39 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 87.32 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 87.29 | ❌ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 87.29 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 87.21 | ✅ |
|
||||
| ViT-H-14-378-quickgelu__dfn5b | 5049 | 108.4 | 87.18 | ❌ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 87.14 | ❌ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 87.07 | ❌ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 86.83 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 86.81 | ✅ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 86.75 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 86.74 | ✅ |
|
||||
| ViT-H-14-quickgelu__dfn5b | 4701 | 38.74 | 86.68 | ❌ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 86.56 | ✅ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 86.16 | ✅ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 84.54 | ❌ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 84.41 | ✅ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 84.25 | ✅ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 83.8 | ❌ |
|
||||
| ViT-L-14-quickgelu__dfn2b | 2212 | 20.49 | 82.59 | ✅ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 81.53 | ✅ |
|
||||
| ViT-L-16-SigLIP-384__webli | 3396 | 47.6 | 81.34 | ❌ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 81.15 | ✅ |
|
||||
| ViT-L-16-SigLIP-256__webli | 3160 | 23.84 | 81.05 | ❌ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 78.35 | ✅ |
|
||||
| ViT-B-16-SigLIP-512__webli | 1828 | 26.17 | 76.56 | ✅ |
|
||||
| ViT-B-16-SigLIP-384__webli | 1128 | 13.53 | 76.0 | ✅ |
|
||||
| ViT-B-16-SigLIP__webli | 1081 | 5.77 | 75.21 | ✅ |
|
||||
| ViT-B-16-SigLIP-256__webli | 1102 | 7.11 | 75.14 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP-384__webli | 4417 | 72.19 | 65.86 | ❌ |
|
||||
| ViT-H-14__laion2b-s32b-b79k | 4676 | 39.06 | 56.87 | ❌ |
|
||||
| ViT-L-14__laion2b-s32b-b82k | 2233 | 20.56 | 47.19 | ❌ |
|
||||
| ViT-L-14__laion400m_e32 | 2218 | 19.73 | 43.36 | ❌ |
|
||||
| ViT-L-14__laion400m_e31 | 2183 | 19.87 | 43.0 | ❌ |
|
||||
| ViT-B-32__laion2b_e16 | 1004 | 2.38 | 41.81 | ✅ |
|
||||
| ViT-B-32__laion2b-s34b-b79k | 1001 | 2.29 | 40.43 | ✅ |
|
||||
| ViT-B-16-plus-240__laion400m_e32 | 1246 | 6.95 | 40.41 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e31 | 1263 | 6.94 | 40.41 | ❌ |
|
||||
| ViT-B-16__laion400m_e31 | 991 | 5.04 | 37.71 | ✅ |
|
||||
| ViT-B-16__laion400m_e32 | 975 | 4.98 | 37.64 | ✅ |
|
||||
| ViT-B-32__laion400m_e31 | 999 | 2.28 | 36.04 | ✅ |
|
||||
| ViT-B-32__laion400m_e32 | 1003 | 2.35 | 35.9 | ❌ |
|
||||
| RN50x64__openai | 5079 | 48.79 | 34.19 | ❌ |
|
||||
| ViT-L-14__openai | 2212 | 19.91 | 33.1 | ❌ |
|
||||
| ViT-L-14-336__openai | 2616 | 43.45 | 32.25 | ❌ |
|
||||
| RN50x16__openai | 2221 | 15.87 | 30.56 | ❌ |
|
||||
| RN50x4__openai | 1416 | 5.85 | 29.2 | ❌ |
|
||||
| ViT-B-16__openai | 985 | 5.03 | 25.77 | ❌ |
|
||||
| RN101__openai | 1111 | 3.21 | 25.46 | ❌ |
|
||||
| RN50__openai | 913 | 2.39 | 24.92 | ✅ |
|
||||
| ViT-B-32__openai | 1004 | 2.26 | 24.13 | ✅ |
|
||||
</details>
|
||||
<details>
|
||||
<summary>Greek</summary>
|
||||
@@ -542,10 +556,10 @@ Memory and execution time estimates were obtained without acceleration on a 7800
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 60.63 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 60.41 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 60.1 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 60.06 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 60.06 | ❌ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 59.44 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 60.06 | ❌ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 59.44 | ❌ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 59.44 | ❌ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 59.43 | ✅ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 58.78 | ✅ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 53.42 | ❌ |
|
||||
@@ -670,99 +684,104 @@ Memory and execution time estimates were obtained without acceleration on a 7800
|
||||
<summary>Italian</summary>
|
||||
| Model | Memory (MiB) | Execution Time (ms) | Recall (%) | Pareto Optimal |
|
||||
|------------------------------------------------------|--------------|---------------------|------------|----------------|
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 88.6 | ✅ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 88.25 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 88.12 | ✅ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 88.04 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 87.97 | ❌ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 87.69 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 87.29 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 87.06 | ❌ |
|
||||
| ViT-H-14-378-quickgelu__dfn5b | 5049 | 108.4 | 86.91 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 86.88 | ✅ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 86.68 | ✅ |
|
||||
| ViT-H-14-quickgelu__dfn5b | 4701 | 38.74 | 86.61 | ❌ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 85.55 | ❌ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 85.37 | ❌ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 83.78 | ✅ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 83.0 | ❌ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 81.81 | ✅ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 81.77 | ❌ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 81.32 | ❌ |
|
||||
| ViT-L-16-SigLIP-384__webli | 3396 | 47.6 | 80.97 | ❌ |
|
||||
| ViT-L-14-quickgelu__dfn2b | 2212 | 20.49 | 80.53 | ✅ |
|
||||
| ViT-L-16-SigLIP-256__webli | 3160 | 23.84 | 80.1 | ❌ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 79.71 | ✅ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 77.31 | ✅ |
|
||||
| ViT-B-16-SigLIP-512__webli | 1828 | 26.17 | 75.19 | ✅ |
|
||||
| ViT-B-16-SigLIP-384__webli | 1128 | 13.53 | 74.49 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP-384__webli | 4417 | 72.19 | 74.04 | ❌ |
|
||||
| ViT-B-16-SigLIP-256__webli | 1102 | 7.11 | 73.68 | ✅ |
|
||||
| ViT-B-16-SigLIP__webli | 1081 | 5.77 | 73.57 | ✅ |
|
||||
| ViT-H-14__laion2b-s32b-b79k | 4676 | 39.06 | 51.04 | ❌ |
|
||||
| ViT-L-14__laion2b-s32b-b82k | 2233 | 20.56 | 41.73 | ❌ |
|
||||
| ViT-L-14__laion400m_e32 | 2218 | 19.73 | 36.87 | ❌ |
|
||||
| ViT-L-14__laion400m_e31 | 2183 | 19.87 | 36.84 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e31 | 1263 | 6.94 | 34.68 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e32 | 1246 | 6.95 | 34.68 | ❌ |
|
||||
| ViT-B-32__laion2b_e16 | 1004 | 2.38 | 34.64 | ✅ |
|
||||
| ViT-B-32__laion2b-s34b-b79k | 1001 | 2.29 | 33.8 | ✅ |
|
||||
| ViT-B-16__laion400m_e32 | 975 | 4.98 | 30.11 | ✅ |
|
||||
| ViT-B-16__laion400m_e31 | 991 | 5.04 | 30.04 | ❌ |
|
||||
| ViT-B-32__laion400m_e32 | 1003 | 2.35 | 29.89 | ❌ |
|
||||
| ViT-B-32__laion400m_e31 | 999 | 2.28 | 29.88 | ✅ |
|
||||
| RN50x64__openai | 5079 | 48.79 | 26.67 | ❌ |
|
||||
| ViT-L-14__openai | 2212 | 19.91 | 25.51 | ❌ |
|
||||
| ViT-L-14-336__openai | 2616 | 43.45 | 25.3 | ❌ |
|
||||
| RN50x16__openai | 2221 | 15.87 | 21.37 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 87.17 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 86.91 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 86.83 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 86.77 | ✅ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 86.67 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 86.42 | ❌ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 86.35 | ✅ |
|
||||
| ViT-H-14-378-quickgelu__dfn5b | 5049 | 108.4 | 86.34 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 86.18 | ✅ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 86.17 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 85.84 | ✅ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 85.8 | ❌ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 85.7 | ✅ |
|
||||
| ViT-H-14-quickgelu__dfn5b | 4701 | 38.74 | 85.67 | ❌ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 83.32 | ✅ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 82.95 | ❌ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 82.73 | ❌ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 82.72 | ❌ |
|
||||
| ViT-L-16-SigLIP-384__webli | 3396 | 47.6 | 81.07 | ❌ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 80.8 | ✅ |
|
||||
| ViT-L-14-quickgelu__dfn2b | 2212 | 20.49 | 80.6 | ✅ |
|
||||
| ViT-L-16-SigLIP-256__webli | 3160 | 23.84 | 80.35 | ❌ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 78.79 | ✅ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 76.62 | ✅ |
|
||||
| ViT-B-16-SigLIP-512__webli | 1828 | 26.17 | 76.51 | ✅ |
|
||||
| ViT-B-16-SigLIP-384__webli | 1128 | 13.53 | 76.08 | ✅ |
|
||||
| ViT-B-16-SigLIP__webli | 1081 | 5.77 | 75.29 | ✅ |
|
||||
| ViT-B-16-SigLIP-256__webli | 1102 | 7.11 | 75.29 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP-384__webli | 4417 | 72.19 | 74.84 | ❌ |
|
||||
| ViT-H-14__laion2b-s32b-b79k | 4676 | 39.06 | 56.32 | ❌ |
|
||||
| ViT-L-14__laion2b-s32b-b82k | 2233 | 20.56 | 47.25 | ❌ |
|
||||
| ViT-L-14__laion400m_e32 | 2218 | 19.73 | 43.09 | ❌ |
|
||||
| ViT-L-14__laion400m_e31 | 2183 | 19.87 | 42.99 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e32 | 1246 | 6.95 | 40.29 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e31 | 1263 | 6.94 | 40.29 | ❌ |
|
||||
| ViT-B-32__laion2b_e16 | 1004 | 2.38 | 39.67 | ✅ |
|
||||
| ViT-B-32__laion2b-s34b-b79k | 1001 | 2.29 | 39.03 | ✅ |
|
||||
| ViT-B-16__laion400m_e32 | 975 | 4.98 | 36.14 | ✅ |
|
||||
| ViT-B-16__laion400m_e31 | 991 | 5.04 | 35.89 | ❌ |
|
||||
| ViT-B-32__laion400m_e32 | 1003 | 2.35 | 35.59 | ❌ |
|
||||
| ViT-B-32__laion400m_e31 | 999 | 2.28 | 35.56 | ✅ |
|
||||
| RN50x64__openai | 5079 | 48.79 | 33.53 | ❌ |
|
||||
| ViT-L-14__openai | 2212 | 19.91 | 32.19 | ❌ |
|
||||
| ViT-L-14-336__openai | 2616 | 43.45 | 30.95 | ❌ |
|
||||
| RN50x16__openai | 2221 | 15.87 | 28.85 | ❌ |
|
||||
| RN50x4__openai | 1416 | 5.85 | 25.75 | ❌ |
|
||||
| ViT-B-16__openai | 985 | 5.03 | 25.18 | ❌ |
|
||||
| RN101__openai | 1111 | 3.21 | 24.48 | ❌ |
|
||||
| RN50__openai | 913 | 2.39 | 23.89 | ✅ |
|
||||
| ViT-B-32__openai | 1004 | 2.26 | 23.39 | ✅ |
|
||||
</details>
|
||||
<details>
|
||||
<summary>Japanese</summary>
|
||||
| Model | Memory (MiB) | Execution Time (ms) | Recall (%) | Pareto Optimal |
|
||||
|------------------------------------------------------|--------------|---------------------|------------|----------------|
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 86.97 | ✅ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 85.15 | ❌ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 84.69 | ❌ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 81.77 | ✅ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 81.26 | ❌ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 81.19 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 69.99 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 68.58 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 68.35 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 68.29 | ❌ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 67.99 | ❌ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 67.68 | ❌ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 67.67 | ❌ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 66.85 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 66.54 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 65.77 | ❌ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 61.48 | ✅ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 58.1 | ❌ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 55.31 | ❌ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 83.95 | ✅ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 82.21 | ❌ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 81.55 | ❌ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 78.72 | ✅ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 78.53 | ❌ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 75.93 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 66.86 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 65.59 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 65.48 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 65.36 | ❌ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 64.47 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 64.17 | ❌ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 64.08 | ❌ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 63.69 | ✅ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 63.33 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 63.02 | ❌ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 58.39 | ✅ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 56.38 | ❌ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 53.16 | ❌ |
|
||||
</details>
|
||||
<details>
|
||||
<summary>Korean</summary>
|
||||
| Model | Memory (MiB) | Execution Time (ms) | Recall (%) | Pareto Optimal |
|
||||
|------------------------------------------------------|--------------|---------------------|------------|----------------|
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 77.21 | ✅ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 76.89 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 75.72 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 75.06 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 74.94 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 74.36 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 74.09 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 73.61 | ❌ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 73.55 | ✅ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 73.41 | ✅ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 73.18 | ✅ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 72.79 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 72.27 | ❌ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 71.73 | ✅ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 71.12 | ❌ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 70.25 | ✅ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 67.54 | ✅ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 67.37 | ✅ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 65.44 | ✅ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 80.56 | ✅ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 80.53 | ✅ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 77.09 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 77.08 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 76.97 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 76.92 | ✅ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 76.58 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 76.2 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 75.95 | ✅ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 75.86 | ✅ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 75.67 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 75.49 | ❌ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 74.6 | ❌ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 74.52 | ✅ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 73.88 | ❌ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 71.09 | ✅ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 68.87 | ✅ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 67.94 | ✅ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 66.39 | ✅ |
|
||||
</details>
|
||||
<details>
|
||||
<summary>Maori</summary>
|
||||
@@ -834,34 +853,34 @@ Memory and execution time estimates were obtained without acceleration on a 7800
|
||||
<summary>Polish</summary>
|
||||
| Model | Memory (MiB) | Execution Time (ms) | Recall (%) | Pareto Optimal |
|
||||
|------------------------------------------------------|--------------|---------------------|------------|----------------|
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 80.6 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 80.17 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 80.06 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 80.04 | ✅ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 79.98 | ❌ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 79.8 | ✅ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 79.72 | ✅ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 79.66 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 79.45 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 79.26 | ❌ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 79.21 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 79.14 | ✅ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 78.23 | ✅ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 75.33 | ✅ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 74.7 | ✅ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 74.63 | ❌ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 73.69 | ✅ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 73.44 | ❌ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 70.34 | ❌ |
|
||||
| ViT-H-14-378-quickgelu__dfn5b | 5049 | 108.4 | 59.4 | ❌ |
|
||||
| ViT-H-14-quickgelu__dfn5b | 4701 | 38.74 | 59.14 | ❌ |
|
||||
| ViT-L-16-SigLIP-256__webli | 3160 | 23.84 | 48.74 | ❌ |
|
||||
| ViT-L-16-SigLIP-384__webli | 3396 | 47.6 | 48.35 | ❌ |
|
||||
| ViT-L-14-quickgelu__dfn2b | 2212 | 20.49 | 40.76 | ✅ |
|
||||
| ViT-B-16-SigLIP__webli | 1081 | 5.77 | 39.13 | ✅ |
|
||||
| ViT-B-16-SigLIP-512__webli | 1828 | 26.17 | 39.09 | ❌ |
|
||||
| ViT-B-16-SigLIP-384__webli | 1128 | 13.53 | 38.55 | ❌ |
|
||||
| ViT-B-16-SigLIP-256__webli | 1102 | 7.11 | 38.46 | ❌ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 83.49 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 83.45 | ❌ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 83.11 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 82.99 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 82.96 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 82.93 | ❌ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 82.61 | ❌ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 82.26 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 82.24 | ✅ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 82.03 | ✅ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 82.03 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 81.92 | ✅ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 81.27 | ✅ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 80.0 | ✅ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 79.65 | ✅ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 76.75 | ✅ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 76.52 | ✅ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 75.1 | ✅ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 73.9 | ❌ |
|
||||
| ViT-H-14-378-quickgelu__dfn5b | 5049 | 108.4 | 65.03 | ❌ |
|
||||
| ViT-H-14-quickgelu__dfn5b | 4701 | 38.74 | 64.89 | ❌ |
|
||||
| ViT-L-16-SigLIP-256__webli | 3160 | 23.84 | 51.6 | ❌ |
|
||||
| ViT-L-16-SigLIP-384__webli | 3396 | 47.6 | 51.29 | ❌ |
|
||||
| ViT-L-14-quickgelu__dfn2b | 2212 | 20.49 | 46.15 | ✅ |
|
||||
| ViT-B-16-SigLIP-512__webli | 1828 | 26.17 | 41.55 | ✅ |
|
||||
| ViT-B-16-SigLIP-384__webli | 1128 | 13.53 | 41.17 | ✅ |
|
||||
| ViT-B-16-SigLIP-256__webli | 1102 | 7.11 | 40.9 | ✅ |
|
||||
| ViT-B-16-SigLIP__webli | 1081 | 5.77 | 40.76 | ✅ |
|
||||
</details>
|
||||
<details>
|
||||
<summary>Portuguese</summary>
|
||||
@@ -955,84 +974,87 @@ Memory and execution time estimates were obtained without acceleration on a 7800
|
||||
<summary>Russian</summary>
|
||||
| Model | Memory (MiB) | Execution Time (ms) | Recall (%) | Pareto Optimal |
|
||||
|------------------------------------------------------|--------------|---------------------|------------|----------------|
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 87.65 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 87.62 | ❌ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 87.4 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 87.39 | ❌ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 86.88 | ❌ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 86.87 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 86.74 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 86.26 | ✅ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 85.98 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 85.66 | ❌ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 85.54 | ❌ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 84.69 | ❌ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 84.29 | ✅ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 84.24 | ❌ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 82.86 | ✅ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 81.59 | ✅ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 80.56 | ✅ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 80.44 | ❌ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 79.99 | ❌ |
|
||||
| ViT-H-14-quickgelu__dfn5b | 4701 | 38.74 | 39.51 | ❌ |
|
||||
| ViT-H-14-378-quickgelu__dfn5b | 5049 | 108.4 | 39.16 | ❌ |
|
||||
| ViT-L-16-SigLIP-256__webli | 3160 | 23.84 | 23.33 | ❌ |
|
||||
| ViT-L-16-SigLIP-384__webli | 3396 | 47.6 | 22.4 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 84.54 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 84.41 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 84.36 | ❌ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 84.31 | ❌ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 84.22 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 83.9 | ✅ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 83.69 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 83.5 | ✅ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 83.31 | ❌ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 83.21 | ❌ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 83.11 | ✅ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 82.7 | ❌ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 82.69 | ❌ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 80.91 | ✅ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 79.75 | ❌ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 79.35 | ✅ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 78.91 | ❌ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 78.06 | ✅ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 76.44 | ✅ |
|
||||
| ViT-H-14-378-quickgelu__dfn5b | 5049 | 108.4 | 42.81 | ❌ |
|
||||
| ViT-H-14-quickgelu__dfn5b | 4701 | 38.74 | 42.1 | ❌ |
|
||||
| ViT-L-16-SigLIP-256__webli | 3160 | 23.84 | 24.95 | ❌ |
|
||||
| ViT-L-16-SigLIP-384__webli | 3396 | 47.6 | 24.25 | ❌ |
|
||||
| ViT-B-16-SigLIP-256__webli | 1102 | 7.11 | 20.85 | ✅ |
|
||||
| ViT-B-16-SigLIP__webli | 1081 | 5.77 | 20.44 | ✅ |
|
||||
| ViT-B-16-SigLIP-512__webli | 1828 | 26.17 | 20.41 | ❌ |
|
||||
</details>
|
||||
<details>
|
||||
<summary>Spanish</summary>
|
||||
| Model | Memory (MiB) | Execution Time (ms) | Recall (%) | Pareto Optimal |
|
||||
|------------------------------------------------------|--------------|---------------------|------------|----------------|
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 84.24 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 83.94 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 83.91 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 83.78 | ✅ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 83.71 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 83.59 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 83.2 | ✅ |
|
||||
| ViT-H-14-378-quickgelu__dfn5b | 5049 | 108.4 | 83.0 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 82.91 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 82.58 | ❌ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 82.5 | ✅ |
|
||||
| ViT-H-14-quickgelu__dfn5b | 4701 | 38.74 | 82.48 | ❌ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 82.22 | ✅ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 81.34 | ❌ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 80.18 | ❌ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 80.14 | ❌ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 78.99 | ✅ |
|
||||
| ViT-L-14-quickgelu__dfn2b | 2212 | 20.49 | 78.19 | ✅ |
|
||||
| ViT-L-16-SigLIP-384__webli | 3396 | 47.6 | 78.15 | ❌ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 77.93 | ✅ |
|
||||
| ViT-L-16-SigLIP-256__webli | 3160 | 23.84 | 77.64 | ❌ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 77.21 | ❌ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 76.36 | ❌ |
|
||||
| ViT-B-16-SigLIP-512__webli | 1828 | 26.17 | 75.73 | ✅ |
|
||||
| ViT-B-16-SigLIP-384__webli | 1128 | 13.53 | 75.56 | ✅ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 75.01 | ✅ |
|
||||
| ViT-B-16-SigLIP-256__webli | 1102 | 7.11 | 74.62 | ✅ |
|
||||
| ViT-B-16-SigLIP__webli | 1081 | 5.77 | 74.6 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP-384__webli | 4417 | 72.19 | 70.31 | ❌ |
|
||||
| ViT-H-14__laion2b-s32b-b79k | 4676 | 39.06 | 58.31 | ❌ |
|
||||
| ViT-L-14__laion2b-s32b-b82k | 2233 | 20.56 | 49.56 | ❌ |
|
||||
| ViT-L-14__laion400m_e32 | 2218 | 19.73 | 46.69 | ❌ |
|
||||
| ViT-L-14__laion400m_e31 | 2183 | 19.87 | 46.53 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e32 | 1246 | 6.95 | 44.05 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e31 | 1263 | 6.94 | 44.05 | ❌ |
|
||||
| ViT-B-32__laion2b_e16 | 1004 | 2.38 | 43.67 | ✅ |
|
||||
| ViT-B-32__laion2b-s34b-b79k | 1001 | 2.29 | 42.5 | ✅ |
|
||||
| ViT-B-16__laion400m_e32 | 975 | 4.98 | 41.03 | ✅ |
|
||||
| ViT-B-16__laion400m_e31 | 991 | 5.04 | 40.91 | ❌ |
|
||||
| ViT-B-32__laion400m_e31 | 999 | 2.28 | 40.3 | ✅ |
|
||||
| ViT-B-32__laion400m_e32 | 1003 | 2.35 | 40.3 | ❌ |
|
||||
| RN50x64__openai | 5079 | 48.79 | 37.92 | ❌ |
|
||||
| ViT-L-14-336__openai | 2616 | 43.45 | 37.7 | ❌ |
|
||||
| ViT-L-14__openai | 2212 | 19.91 | 37.59 | ❌ |
|
||||
| RN50x16__openai | 2221 | 15.87 | 34.75 | ❌ |
|
||||
| ViT-B-16__openai | 985 | 5.03 | 32.1 | ❌ |
|
||||
| RN50x4__openai | 1416 | 5.85 | 32.08 | ❌ |
|
||||
| RN101__openai | 1111 | 3.21 | 30.77 | ❌ |
|
||||
| RN50__openai | 913 | 2.39 | 30.2 | ✅ |
|
||||
| ViT-B-32__openai | 1004 | 2.26 | 29.84 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 85.47 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 85.44 | ✅ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 85.32 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 85.22 | ❌ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 85.15 | ❌ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 84.81 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 84.68 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 84.6 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 84.55 | ✅ |
|
||||
| ViT-H-14-378-quickgelu__dfn5b | 5049 | 108.4 | 84.27 | ❌ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 84.15 | ✅ |
|
||||
| ViT-H-14-quickgelu__dfn5b | 4701 | 38.74 | 83.87 | ❌ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 83.74 | ❌ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 83.61 | ✅ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 83.15 | ❌ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 81.7 | ❌ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 80.91 | ❌ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 80.73 | ✅ |
|
||||
| ViT-L-16-SigLIP-384__webli | 3396 | 47.6 | 80.69 | ❌ |
|
||||
| ViT-L-16-SigLIP-256__webli | 3160 | 23.84 | 80.3 | ❌ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 79.8 | ❌ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 79.71 | ✅ |
|
||||
| ViT-L-14-quickgelu__dfn2b | 2212 | 20.49 | 79.64 | ✅ |
|
||||
| ViT-B-16-SigLIP-384__webli | 1128 | 13.53 | 78.0 | ✅ |
|
||||
| ViT-B-16-SigLIP-512__webli | 1828 | 26.17 | 77.83 | ❌ |
|
||||
| ViT-B-16-SigLIP__webli | 1081 | 5.77 | 76.87 | ✅ |
|
||||
| ViT-B-16-SigLIP-256__webli | 1102 | 7.11 | 76.66 | ❌ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 75.99 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP-384__webli | 4417 | 72.19 | 71.96 | ❌ |
|
||||
| ViT-H-14__laion2b-s32b-b79k | 4676 | 39.06 | 62.06 | ❌ |
|
||||
| ViT-L-14__laion2b-s32b-b82k | 2233 | 20.56 | 53.78 | ❌ |
|
||||
| ViT-L-14__laion400m_e32 | 2218 | 19.73 | 50.13 | ❌ |
|
||||
| ViT-L-14__laion400m_e31 | 2183 | 19.87 | 50.0 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e32 | 1246 | 6.95 | 47.39 | ❌ |
|
||||
| ViT-B-16-plus-240__laion400m_e31 | 1263 | 6.94 | 47.39 | ❌ |
|
||||
| ViT-B-32__laion2b_e16 | 1004 | 2.38 | 46.47 | ✅ |
|
||||
| ViT-B-32__laion2b-s34b-b79k | 1001 | 2.29 | 45.68 | ✅ |
|
||||
| ViT-B-16__laion400m_e31 | 991 | 5.04 | 44.0 | ✅ |
|
||||
| ViT-B-16__laion400m_e32 | 975 | 4.98 | 43.98 | ✅ |
|
||||
| ViT-B-32__laion400m_e32 | 1003 | 2.35 | 43.8 | ❌ |
|
||||
| ViT-B-32__laion400m_e31 | 999 | 2.28 | 43.73 | ✅ |
|
||||
| RN50x64__openai | 5079 | 48.79 | 43.01 | ❌ |
|
||||
| ViT-L-14__openai | 2212 | 19.91 | 42.96 | ❌ |
|
||||
| ViT-L-14-336__openai | 2616 | 43.45 | 41.67 | ❌ |
|
||||
| RN50x16__openai | 2221 | 15.87 | 40.21 | ❌ |
|
||||
| RN50x4__openai | 1416 | 5.85 | 36.06 | ❌ |
|
||||
| ViT-B-16__openai | 985 | 5.03 | 35.67 | ❌ |
|
||||
| RN101__openai | 1111 | 3.21 | 34.62 | ❌ |
|
||||
| ViT-B-32__openai | 1004 | 2.26 | 32.6 | ✅ |
|
||||
| RN50__openai | 913 | 2.39 | 31.79 | ✅ |
|
||||
</details>
|
||||
<details>
|
||||
<summary>Swahili</summary>
|
||||
@@ -1057,8 +1079,8 @@ Memory and execution time estimates were obtained without acceleration on a 7800
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 72.1 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 72.06 | ✅ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 71.84 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 71.7 | ✅ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 71.7 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 71.7 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 71.61 | ❌ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 71.51 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 71.45 | ✅ |
|
||||
@@ -1115,31 +1137,34 @@ Memory and execution time estimates were obtained without acceleration on a 7800
|
||||
<summary>Turkish</summary>
|
||||
| Model | Memory (MiB) | Execution Time (ms) | Recall (%) | Pareto Optimal |
|
||||
|------------------------------------------------------|--------------|---------------------|------------|----------------|
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 81.15 | ✅ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 80.89 | ✅ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 78.11 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 77.51 | ✅ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 77.36 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 77.28 | ❌ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 77.24 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 77.01 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 76.37 | ❌ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 75.92 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 75.69 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 75.68 | ❌ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 75.54 | ✅ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 75.16 | ✅ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 73.83 | ✅ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 70.15 | ✅ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 69.19 | ✅ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 66.72 | ❌ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 64.76 | ❌ |
|
||||
| ViT-H-14-378-quickgelu__dfn5b | 5049 | 108.4 | 38.8 | ❌ |
|
||||
| ViT-H-14-quickgelu__dfn5b | 4701 | 38.74 | 38.48 | ❌ |
|
||||
| ViT-L-16-SigLIP-384__webli | 3396 | 47.6 | 30.83 | ❌ |
|
||||
| ViT-L-16-SigLIP-256__webli | 3160 | 23.84 | 30.28 | ❌ |
|
||||
| ViT-L-14-quickgelu__dfn2b | 2212 | 20.49 | 21.31 | ✅ |
|
||||
| ViT-B-16-SigLIP__webli | 1081 | 5.77 | 20.08 | ✅ |
|
||||
| nllb-clip-large-siglip__mrl | 4248 | 75.44 | 83.91 | ✅ |
|
||||
| nllb-clip-large-siglip__v1 | 4226 | 75.05 | 83.74 | ✅ |
|
||||
| nllb-clip-base-siglip__mrl | 4696 | 16.95 | 81.26 | ✅ |
|
||||
| nllb-clip-base-siglip__v1 | 4675 | 15.17 | 80.21 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-512__webli | 4050 | 107.67 | 79.34 | ✅ |
|
||||
| ViT-SO400M-14-SigLIP2-378__webli | 3940 | 72.25 | 79.22 | ✅ |
|
||||
| XLM-Roberta-Large-ViT-H-14__frozen_laion5b_s13b_b90k | 4014 | 39.14 | 78.9 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-384__webli | 3854 | 56.57 | 78.85 | ✅ |
|
||||
| ViT-SO400M-16-SigLIP2-256__webli | 3611 | 27.84 | 78.29 | ✅ |
|
||||
| ViT-gopt-16-SigLIP2-384__webli | 6585 | 146.84 | 78.27 | ❌ |
|
||||
| ViT-gopt-16-SigLIP2-256__webli | 6475 | 64.51 | 78.0 | ❌ |
|
||||
| ViT-SO400M-14-SigLIP2__webli | 3622 | 27.63 | 77.81 | ✅ |
|
||||
| ViT-L-16-SigLIP2-512__webli | 3358 | 92.59 | 77.67 | ✅ |
|
||||
| ViT-L-16-SigLIP2-384__webli | 3057 | 51.7 | 77.33 | ✅ |
|
||||
| ViT-L-16-SigLIP2-256__webli | 2830 | 23.77 | 76.42 | ✅ |
|
||||
| ViT-B-16-SigLIP-i18n-256__webli | 3029 | 6.87 | 72.44 | ✅ |
|
||||
| XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k | 3030 | 3.2 | 69.84 | ✅ |
|
||||
| ViT-B-16-SigLIP2__webli | 3038 | 5.81 | 69.83 | ❌ |
|
||||
| ViT-B-32-SigLIP2-256__webli | 3061 | 3.31 | 67.13 | ❌ |
|
||||
| ViT-H-14-378-quickgelu__dfn5b | 5049 | 108.4 | 44.43 | ❌ |
|
||||
| ViT-H-14-quickgelu__dfn5b | 4701 | 38.74 | 43.87 | ❌ |
|
||||
| ViT-L-16-SigLIP-384__webli | 3396 | 47.6 | 35.1 | ❌ |
|
||||
| ViT-L-16-SigLIP-256__webli | 3160 | 23.84 | 34.92 | ❌ |
|
||||
| ViT-L-14-quickgelu__dfn2b | 2212 | 20.49 | 25.2 | ✅ |
|
||||
| ViT-B-16-SigLIP-512__webli | 1828 | 26.17 | 24.55 | ✅ |
|
||||
| ViT-B-16-SigLIP__webli | 1081 | 5.77 | 24.13 | ✅ |
|
||||
| ViT-B-16-SigLIP-384__webli | 1128 | 13.53 | 24.08 | ❌ |
|
||||
| ViT-B-16-SigLIP-256__webli | 1102 | 7.11 | 23.95 | ❌ |
|
||||
</details>
|
||||
<details>
|
||||
<summary>Ukrainian</summary>
|
||||
|
||||
@@ -14,14 +14,14 @@ online generators you can use.
|
||||
2. Paste the link to your JSON style in either the **Light Style** or **Dark Style**. (You can add different styles which will help make the map style more appropriate depending on whether you set **Immich** to Light or Dark mode.)
|
||||
3. Save your selections. Reload the map, and enjoy your custom map style!
|
||||
|
||||
## Use Maptiler to build a custom style
|
||||
## Use MapTiler to build a custom style
|
||||
|
||||
Customizing the map style can be done easily using Maptiler, if you do not want to write an entire JSON document by hand.
|
||||
Customizing the map style can be done easily using MapTiler, if you do not want to write an entire JSON document by hand.
|
||||
|
||||
1. Create a free account at https://cloud.maptiler.com
|
||||
2. Once logged in, you can either create a brand new map by clicking on **New Map**, selecting a starter map, and then clicking **Customize**, OR by selecting a **Standard Map** and customizing it from there.
|
||||
3. The **editor** interface is self-explanatory. You can change colors, remove visible layers, or add optional layers (e.g., administrative, topo, hydro, etc.) in the composer.
|
||||
4. Once you have your map composed, click on **Save** at the top right. Give it a unique name to save it to your account.
|
||||
5. Next, **Publish** your style using the **Publish** button at the top right. This will deploy it to production, which means it is able to be exposed over the Internet. Maptiler will present an interactive side-by-side map with the original and your changes prior to publication.<br/>
|
||||
6. Maptiler will warn you that changing the map will change it across all apps using the map. Since no apps are using the map yet, this is okay.
|
||||
7. Clicking on the name of your new map at the top left will bring you to the item's **details** page. From here, copy the link to the JSON style under **Use vector style**. This link will automatically contain your personal API key to Maptiler.
|
||||
5. Next, **Publish** your style using the **Publish** button at the top right. This will deploy it to production, which means it is able to be exposed over the Internet. MapTiler will present an interactive side-by-side map with the original and your changes prior to publication.<br/>
|
||||
6. MapTiler will warn you that changing the map will change it across all apps using the map. Since no apps are using the map yet, this is okay.
|
||||
7. Clicking on the name of your new map at the top left will bring you to the item's **details** page. From here, copy the link to the JSON style under **Use vector style**. This link will automatically contain your personal API key to MapTiler.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Database Queries
|
||||
|
||||
:::danger
|
||||
Keep in mind that mucking around in the database might set the moon on fire. Avoid modifying the database directly when possible, and always have current backups.
|
||||
Keep in mind that mucking around in the database might set the Moon on fire. Avoid modifying the database directly when possible, and always have current backups.
|
||||
:::
|
||||
|
||||
:::tip
|
||||
|
||||
@@ -23,12 +23,12 @@ name: immich_remote_ml
|
||||
services:
|
||||
immich-machine-learning:
|
||||
container_name: immich_machine_learning
|
||||
# For hardware acceleration, add one of -[armnn, cuda, rocm, openvino] to the image tag.
|
||||
# For hardware acceleration, add one of -[armnn, cuda, rocm, openvino, rknn] to the image tag.
|
||||
# Example tag: ${IMMICH_VERSION:-release}-cuda
|
||||
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
|
||||
# extends:
|
||||
# file: hwaccel.ml.yml
|
||||
# service: # set to one of [armnn, cuda, rocm, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable
|
||||
# service: # set to one of [armnn, cuda, rocm, openvino, openvino-wsl, rknn] for accelerated inference - use the `-wsl` version for WSL2 where applicable
|
||||
volumes:
|
||||
- model-cache:/cache
|
||||
restart: always
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Scaling Immich
|
||||
|
||||
Immich is built with modern deployment practices in mind, and the backend is designed to be able to run multiple instances in parallel. When doing this, the only requirement you need to be aware of is that every instance needs to be connected to the shared infrastructure. That means they should all have access to the same Postgres and Redis instances, and have the same files mounted into the containers.
|
||||
Immich is built with modern deployment practices in mind, and the backend is designed to be able to run multiple instances in parallel. When doing this, the only requirement you need to be aware of is that every instance needs to be connected to the shared infrastructure. That means they should all have access to the same Postgres instance, and have the same files mounted into the containers.
|
||||
|
||||
Scaling can be useful for many reasons. Maybe you have a gaming PC that you want to use for transcoding and thumbnail generation, or perhaps you run a Kubernetes cluster across a handful of powerful servers that you want to make use of.
|
||||
|
||||
@@ -16,4 +16,4 @@ By default, each running `immich-server` container comes with multiple internal
|
||||
|
||||
## Scaling down
|
||||
|
||||
In the same way you can scale up to multiple containers, you can also choose to scale down. All state is stored in Postgres, Redis, and the filesystem so there is no risk in stopping a running immich-server container, for example if you want to use your GPU to play some games. As long as there is an API worker running you will still be able to browse Immich, and jobs will wait to be processed until there is a worker available for them.
|
||||
In the same way you can scale up to multiple containers, you can also choose to scale down. All state is stored in Postgres and the filesystem so there is no risk in stopping a running immich-server container, for example if you want to use your GPU to play some games. As long as there is an API worker running you will still be able to browse Immich, and jobs will wait to be processed until there is a worker available for them.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
sidebar_position: 100
|
||||
---
|
||||
|
||||
# Config File
|
||||
|
||||
A config file can be provided as an alternative to the UI configuration.
|
||||
|
||||
@@ -69,39 +69,7 @@ If you get an error `can't set healthcheck.start_interval as feature require Doc
|
||||
|
||||
## Next Steps
|
||||
|
||||
Read the [Post Installation](/docs/install/post-install.mdx) steps or setup optional features below.
|
||||
|
||||
### Setting up optional features
|
||||
|
||||
- [External Libraries](/docs/features/libraries.md): Adding your existing photo library to Immich
|
||||
- [Hardware Transcoding](/docs/features/hardware-transcoding.md): Speeding up video transcoding
|
||||
- [Hardware-Accelerated Machine Learning](/docs/features/ml-hardware-acceleration.md): Speeding up various machine learning tasks in Immich
|
||||
|
||||
### Upgrading
|
||||
|
||||
:::danger Read the release notes
|
||||
Immich is currently under heavy development, which means you can expect [breaking changes][breaking] and bugs. Therefore, we recommend reading the release notes prior to updating and to take special care when using automated tools like [Watchtower][watchtower].
|
||||
|
||||
You can see versions that had breaking changes [here][breaking].
|
||||
:::
|
||||
|
||||
If `IMMICH_VERSION` is set, it will need to be updated to the latest or desired version.
|
||||
|
||||
When a new version of Immich is [released][releases], the application can be upgraded and restarted with the following commands, run in the directory with the `docker-compose.yml` file:
|
||||
|
||||
```bash title="Upgrade and restart Immich"
|
||||
docker compose pull && docker compose up -d
|
||||
```
|
||||
|
||||
To clean up disk space, the old version's obsolete container images can be deleted with the following command:
|
||||
|
||||
```bash title="Clean up unused Docker images"
|
||||
docker image prune
|
||||
```
|
||||
Read the [Post Installation](/docs/install/post-install.mdx) steps and [upgrade instructions](/docs/install/upgrading.md).
|
||||
|
||||
[compose-file]: https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
|
||||
[env-file]: https://github.com/immich-app/immich/releases/latest/download/example.env
|
||||
[watchtower]: https://containrrr.dev/watchtower/
|
||||
[breaking]: https://github.com/immich-app/immich/discussions?discussions_q=label%3Achangelog%3Abreaking-change+sort%3Adate_created
|
||||
[container-auth]: https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#authenticating-to-the-container-registry
|
||||
[releases]: https://github.com/immich-app/immich/releases
|
||||
|
||||
@@ -98,54 +98,6 @@ When `DB_URL` is defined, the `DB_HOSTNAME`, `DB_PORT`, `DB_USERNAME`, `DB_PASSW
|
||||
|
||||
:::
|
||||
|
||||
## Redis
|
||||
|
||||
| Variable | Description | Default | Containers |
|
||||
| :--------------- | :------------- | :-----: | :--------- |
|
||||
| `REDIS_URL` | Redis URL | | server |
|
||||
| `REDIS_SOCKET` | Redis socket | | server |
|
||||
| `REDIS_HOSTNAME` | Redis host | `redis` | server |
|
||||
| `REDIS_PORT` | Redis port | `6379` | server |
|
||||
| `REDIS_USERNAME` | Redis username | | server |
|
||||
| `REDIS_PASSWORD` | Redis password | | server |
|
||||
| `REDIS_DBINDEX` | Redis DB index | `0` | server |
|
||||
|
||||
:::info
|
||||
All `REDIS_` variables must be provided to all Immich workers, including `api` and `microservices`.
|
||||
|
||||
`REDIS_URL` must start with `ioredis://` and then include a `base64` encoded JSON string for the configuration.
|
||||
More information can be found in the upstream [ioredis] documentation.
|
||||
|
||||
When `REDIS_URL` or `REDIS_SOCKET` are defined, the `REDIS_HOSTNAME`, `REDIS_PORT`, `REDIS_USERNAME`, `REDIS_PASSWORD`, and `REDIS_DBINDEX` variables are ignored.
|
||||
:::
|
||||
|
||||
Redis (Sentinel) URL example JSON before encoding:
|
||||
|
||||
<details>
|
||||
<summary>JSON</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"sentinels": [
|
||||
{
|
||||
"host": "redis-sentinel-node-0",
|
||||
"port": 26379
|
||||
},
|
||||
{
|
||||
"host": "redis-sentinel-node-1",
|
||||
"port": 26379
|
||||
},
|
||||
{
|
||||
"host": "redis-sentinel-node-2",
|
||||
"port": 26379
|
||||
}
|
||||
],
|
||||
"name": "redis-sentinel"
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Machine Learning
|
||||
|
||||
| Variable | Description | Default | Containers |
|
||||
@@ -212,16 +164,10 @@ the `_FILE` variable should be set to the path of a file containing the variable
|
||||
| `DB_USERNAME` | `DB_USERNAME_FILE`<sup>\*1</sup> |
|
||||
| `DB_PASSWORD` | `DB_PASSWORD_FILE`<sup>\*1</sup> |
|
||||
| `DB_URL` | `DB_URL_FILE`<sup>\*1</sup> |
|
||||
| `REDIS_PASSWORD` | `REDIS_PASSWORD_FILE`<sup>\*2</sup> |
|
||||
|
||||
\*1: See the [official documentation][docker-secrets-docs] for
|
||||
details on how to use Docker Secrets in the Postgres image.
|
||||
|
||||
\*2: See [this comment][docker-secrets-example] for an example of how
|
||||
to use a Docker secret for the password in the Redis container.
|
||||
|
||||
[tz-list]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
|
||||
[docker-secrets-example]: https://github.com/docker-library/redis/issues/46#issuecomment-335326234
|
||||
[docker-secrets-docs]: https://github.com/docker-library/docs/tree/master/postgres#docker-secrets
|
||||
[docker-secrets]: https://docs.docker.com/engine/swarm/secrets/
|
||||
[ioredis]: https://ioredis.readthedocs.io/en/latest/README/#connect-to-redis
|
||||
|
||||
@@ -41,3 +41,9 @@ A list of common steps to take after installing Immich include:
|
||||
## Step 7 - Setup Server Backups
|
||||
|
||||
<ServerBackup />
|
||||
|
||||
## Setting up optional features
|
||||
|
||||
- [External Libraries](/docs/features/libraries.md): Adding your existing photo library to Immich
|
||||
- [Hardware Transcoding](/docs/features/hardware-transcoding.md): Speeding up video transcoding
|
||||
- [Hardware-Accelerated Machine Learning](/docs/features/ml-hardware-acceleration.md): Speeding up various machine learning tasks in Immich
|
||||
|
||||
@@ -67,10 +67,4 @@ Click "**Edit Rules**" and add the following firewall rules:
|
||||
|
||||
## Next Steps
|
||||
|
||||
Read the [Post Installation](/docs/install/post-install.mdx) steps or setup optional features below.
|
||||
|
||||
### Setting up optional features
|
||||
|
||||
- [External Libraries](/docs/features/libraries.md): Adding your existing photo library to Immich
|
||||
- [Hardware Transcoding](/docs/features/hardware-transcoding.md): Speeding up video transcoding
|
||||
- [Hardware-Accelerated Machine Learning](/docs/features/ml-hardware-acceleration.md): Speeding up various machine learning tasks in Immich
|
||||
Read the [Post Installation](/docs/install/post-install.mdx) steps and [upgrade instructions](/docs/install/upgrading.md).
|
||||
|
||||
@@ -107,8 +107,6 @@ Accept the default option or select the **Machine Learning Image Type** for your
|
||||
|
||||
Immich's default is `postgres` but you should consider setting the **Database Password** to a custom value using only the characters `A-Za-z0-9`.
|
||||
|
||||
The **Redis Password** should be set to a custom value using only the characters `A-Za-z0-9`.
|
||||
|
||||
Accept the **Log Level** default of **Log**.
|
||||
|
||||
Leave **Hugging Face Endpoint** blank. (This is for downloading ML models from a different source.)
|
||||
@@ -242,11 +240,15 @@ className="border rounded-xl"
|
||||
:::info
|
||||
Some Environment Variables are not available for the TrueNAS SCALE app. This is mainly because they can be configured through GUI options in the [Edit Immich screen](#edit-app-settings).
|
||||
|
||||
Some examples are: `IMMICH_VERSION`, `UPLOAD_LOCATION`, `DB_DATA_LOCATION`, `TZ`, `IMMICH_LOG_LEVEL`, `DB_PASSWORD`, `REDIS_PASSWORD`.
|
||||
Some examples are: `IMMICH_VERSION`, `UPLOAD_LOCATION`, `DB_DATA_LOCATION`, `TZ`, `IMMICH_LOG_LEVEL`, `DB_PASSWORD`.
|
||||
:::
|
||||
|
||||
## Updating the App
|
||||
|
||||
:::danger
|
||||
Make sure to read the general [upgrade instructions](/docs/install/upgrading.md).
|
||||
:::
|
||||
|
||||
When updates become available, SCALE alerts and provides easy updates.
|
||||
To update the app to the latest version:
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@ Immich can easily be installed and updated on Unraid via:
|
||||
|
||||
:::
|
||||
|
||||
In order to install Immich from the Unraid CA, you will need an existing Redis and PostgreSQL 14 container, If you do not already have Redis or PostgreSQL you can install them from the Unraid CA, just make sure you choose PostgreSQL **14**.
|
||||
In order to install Immich from the Unraid CA, you will need an existing PostgreSQL 14 container, If you do not already have PostgreSQL you can install it from the Unraid CA, just make sure you choose PostgreSQL **14**.
|
||||
|
||||
Once you have Redis and PostgreSQL running, search for Immich on the Unraid CA, choose either of the templates listed and fill out the example variables.
|
||||
Once you have PostgreSQL running, search for Immich on the Unraid CA, choose either of the templates listed and fill out the example variables.
|
||||
|
||||
For more information about setting up the community image see [here](https://github.com/imagegenius/docker-immich#application-setup)
|
||||
|
||||
@@ -45,63 +45,63 @@ width="70%"
|
||||
alt="Select Plugins > Compose.Manager > Add New Stack > Label it Immich"
|
||||
/>
|
||||
|
||||
3. Select the cogwheel ⚙️ next to Immich and click "**Edit Stack**"
|
||||
4. Click "**Compose File**" and then paste the entire contents of the [Immich Docker Compose](https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml) file into the Unraid editor. Remove any text that may be in the text area by default. Note that Unraid v6.12.10 uses version 24.0.9 of the Docker Engine, which does not support healthcheck `start_interval` as defined in the `database` service of the Docker compose file (version 25 or higher is needed). This parameter defines an initial waiting period before starting health checks, to give the container time to start up. Commenting out the `start_interval` and `start_period` parameters will allow the containers to start up normally. The only downside to this is that the database container will not receive an initial health check until `interval` time has passed.
|
||||
3. Select the cogwheel ⚙️ next to Immich and click "**Edit Stack**"
|
||||
4. Click "**Compose File**" and then paste the entire contents of the [Immich Docker Compose](https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml) file into the Unraid editor. Remove any text that may be in the text area by default. Note that Unraid v6.12.10 uses version 24.0.9 of the Docker Engine, which does not support healthcheck `start_interval` as defined in the `database` service of the Docker compose file (version 25 or higher is needed). This parameter defines an initial waiting period before starting health checks, to give the container time to start up. Commenting out the `start_interval` and `start_period` parameters will allow the containers to start up normally. The only downside to this is that the database container will not receive an initial health check until `interval` time has passed.
|
||||
|
||||
<details >
|
||||
<summary>Using an existing Postgres container? Click me! Otherwise proceed to step 5.</summary>
|
||||
<ul>
|
||||
<li>Comment out the database service</li>
|
||||
<img
|
||||
src={require('./img/unraid02.webp').default}
|
||||
width="50%"
|
||||
alt="Comment out database service in the compose file"
|
||||
/>
|
||||
<li>Comment out the database dependency for <b>each service</b> <i>(example in screenshot below only shows 2 of the services - ensure you do this for all services)</i></li>
|
||||
<img
|
||||
src={require('./img/unraid03.webp').default}
|
||||
width="50%"
|
||||
alt="Comment out every reference to the database service in the compose file"
|
||||
/>
|
||||
<li>Comment out the volumes</li>
|
||||
<img
|
||||
src={require('./img/unraid04.webp').default}
|
||||
width="20%"
|
||||
alt="Comment out database volume"
|
||||
/>
|
||||
</ul>
|
||||
</details>
|
||||
<details >
|
||||
<summary>Using an existing Postgres container? Click me! Otherwise proceed to step 5.</summary>
|
||||
<ul>
|
||||
<li>Comment out the database service</li>
|
||||
<img
|
||||
src={require('./img/unraid02.webp').default}
|
||||
width="50%"
|
||||
alt="Comment out database service in the compose file"
|
||||
/>
|
||||
<li>Comment out the database dependency for <b>each service</b> <i>(example in screenshot below only shows 2 of the services - ensure you do this for all services)</i></li>
|
||||
<img
|
||||
src={require('./img/unraid03.webp').default}
|
||||
width="50%"
|
||||
alt="Comment out every reference to the database service in the compose file"
|
||||
/>
|
||||
<li>Comment out the volumes</li>
|
||||
<img
|
||||
src={require('./img/unraid04.webp').default}
|
||||
width="20%"
|
||||
alt="Comment out database volume"
|
||||
/>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
5. Click "**Save Changes**", you will be prompted to edit stack UI labels, just leave this blank and click "**Ok**"
|
||||
6. Select the cog ⚙️ next to Immich, click "**Edit Stack**", then click "**Env File**"
|
||||
7. Paste the entire contents of the [Immich example.env](https://github.com/immich-app/immich/releases/latest/download/example.env) file into the Unraid editor, then **before saving** edit the following:
|
||||
5. Click "**Save Changes**", you will be prompted to edit stack UI labels, just leave this blank and click "**Ok**"
|
||||
6. Select the cog ⚙️ next to Immich, click "**Edit Stack**", then click "**Env File**"
|
||||
7. Paste the entire contents of the [Immich example.env](https://github.com/immich-app/immich/releases/latest/download/example.env) file into the Unraid editor, then **before saving** edit the following:
|
||||
|
||||
- `UPLOAD_LOCATION`: Create a folder in your Images Unraid share and place the **absolute** location here > For example my _"images"_ share has a folder within it called _"immich"_. If I browse to this directory in the terminal and type `pwd` the output is `/mnt/user/images/immich`. This is the exact value I need to enter as my `UPLOAD_LOCATION`
|
||||
- `DB_DATA_LOCATION`: Change this to use an Unraid share (preferably a cache pool, e.g. `/mnt/user/appdata/postgresql/data`). This uses the `appdata` share. Do also create the `postgresql` folder, by running `mkdir /mnt/user/{share_location}/postgresql/data`. If left at default it will try to use Unraid's `/boot/config/plugins/compose.manager/projects/[stack_name]/postgres` folder which it doesn't have permissions to, resulting in this container continuously restarting.
|
||||
- `UPLOAD_LOCATION`: Create a folder in your Images Unraid share and place the **absolute** location here > For example my _"images"_ share has a folder within it called _"immich"_. If I browse to this directory in the terminal and type `pwd` the output is `/mnt/user/images/immich`. This is the exact value I need to enter as my `UPLOAD_LOCATION`
|
||||
- `DB_DATA_LOCATION`: Change this to use an Unraid share (preferably a cache pool, e.g. `/mnt/user/appdata/postgresql/data`). This uses the `appdata` share. Do also create the `postgresql` folder, by running `mkdir /mnt/user/{share_location}/postgresql/data`. If left at default it will try to use Unraid's `/boot/config/plugins/compose.manager/projects/[stack_name]/postgres` folder which it doesn't have permissions to, resulting in this container continuously restarting.
|
||||
|
||||
<img
|
||||
src={require('./img/unraid05.webp').default}
|
||||
width="70%"
|
||||
alt="Absolute location of where you want immich images stored"
|
||||
/>
|
||||
<img
|
||||
src={require('./img/unraid05.webp').default}
|
||||
width="70%"
|
||||
alt="Absolute location of where you want immich images stored"
|
||||
/>
|
||||
|
||||
<details >
|
||||
<summary>Using an existing Postgres container? Click me! Otherwise proceed to step 8.</summary>
|
||||
<p>Update the following database variables as relevant to your Postgres container:</p>
|
||||
<ul>
|
||||
<li><code>DB_HOSTNAME</code></li>
|
||||
<li><code>DB_USERNAME</code></li>
|
||||
<li><code>DB_PASSWORD</code></li>
|
||||
<li><code>DB_DATABASE_NAME</code></li>
|
||||
<li><code>DB_PORT</code></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details >
|
||||
<summary>Using an existing Postgres container? Click me! Otherwise proceed to step 8.</summary>
|
||||
<p>Update the following database variables as relevant to your Postgres container:</p>
|
||||
<ul>
|
||||
<li><code>DB_HOSTNAME</code></li>
|
||||
<li><code>DB_USERNAME</code></li>
|
||||
<li><code>DB_PASSWORD</code></li>
|
||||
<li><code>DB_DATABASE_NAME</code></li>
|
||||
<li><code>DB_PORT</code></li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
8. Click "**Save Changes**" followed by "**Compose Up**" and Unraid will begin to create the Immich containers in a popup window. Once complete you will see a message on the popup window stating _"Connection Closed"_. Click "**Done**" and go to the Unraid "**Docker**" page
|
||||
8. Click "**Save Changes**" followed by "**Compose Up**" and Unraid will begin to create the Immich containers in a popup window. Once complete you will see a message on the popup window stating _"Connection Closed"_. Click "**Done**" and go to the Unraid "**Docker**" page
|
||||
|
||||
> Note: This can take several minutes depending on your Internet speed and Unraid hardware
|
||||
> Note: This can take several minutes depending on your Internet speed and Unraid hardware
|
||||
|
||||
9. Once on the Docker page you will see several Immich containers, one of them will be labelled `immich_server` and will have a port mapping. Visit the `IP:PORT` displayed in your web browser and you should see the Immich admin setup page.
|
||||
9. Once on the Docker page you will see several Immich containers, one of them will be labelled `immich_server` and will have a port mapping. Visit the `IP:PORT` displayed in your web browser and you should see the Immich admin setup page.
|
||||
|
||||
<img
|
||||
src={require('./img/unraid06.webp').default}
|
||||
@@ -122,7 +122,7 @@ alt="Go to Docker Tab and visit the address listed next to immich-web"
|
||||
width="90%"
|
||||
alt="Go to Docker Tab and visit the address listed next to immich-web"
|
||||
/>
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
:::tip
|
||||
@@ -131,6 +131,10 @@ For more information on how to use the application once installed, please refer
|
||||
|
||||
## Updating Steps
|
||||
|
||||
:::danger
|
||||
Make sure to read the general [upgrade instructions](/docs/install/upgrading.md).
|
||||
:::
|
||||
|
||||
Updating is extremely easy however it's important to be aware that containers managed via the Docker Compose Manager plugin do not integrate with Unraid's native dockerman UI, the label "_update ready_" will always be present on containers installed via the Docker Compose Manager.
|
||||
|
||||
<img
|
||||
|
||||
29
docs/docs/install/upgrading.md
Normal file
29
docs/docs/install/upgrading.md
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
sidebar_position: 95
|
||||
---
|
||||
|
||||
# Upgrading
|
||||
|
||||
:::danger Read the release notes
|
||||
Immich is currently under heavy development, which means you can expect [breaking changes][breaking] and bugs. You should read the release notes prior to updating and take special care when using automated tools like [Watchtower][watchtower].
|
||||
|
||||
You can see versions that had breaking changes [here][breaking].
|
||||
:::
|
||||
|
||||
When a new version of Immich is [released][releases], you should read the release notes and account for any breaking changes noted (as mentioned above).
|
||||
If you use `IMMICH_VERSION` in your `.env` file, it will need to be updated to the latest or desired version.
|
||||
After that, the application can be upgraded and restarted with the following commands, run in the directory with the `docker-compose.yml` file:
|
||||
|
||||
```bash title="Upgrade and restart Immich"
|
||||
docker compose pull && docker compose up -d
|
||||
```
|
||||
|
||||
To clean up disk space, the old version's obsolete container images can be deleted with the following command:
|
||||
|
||||
```bash title="Clean up unused Docker images"
|
||||
docker image prune
|
||||
```
|
||||
|
||||
[watchtower]: https://containrrr.dev/watchtower/
|
||||
[breaking]: https://github.com/immich-app/immich/discussions?discussions_q=label%3Achangelog%3Abreaking-change+sort%3Adate_created
|
||||
[releases]: https://github.com/immich-app/immich/releases
|
||||
@@ -1,2 +1,7 @@
|
||||
Now that you have imported some pictures, you should setup server backups to preserve your memories.
|
||||
You can do so by following our [backup guide](/docs/administration/backup-and-restore.md).
|
||||
|
||||
:::danger
|
||||
Immich is still under heavy development _and_ handles very important data.
|
||||
It is essential that you set up good backups, and test them.
|
||||
:::
|
||||
|
||||
5324
docs/package-lock.json
generated
5324
docs/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -40,8 +40,9 @@ const projects: CommunityProjectProps[] = [
|
||||
},
|
||||
{
|
||||
title: 'Lightroom Immich Plugin: lrc-immich-plugin',
|
||||
description: 'Another Lightroom plugin to publish or export photos from Lightroom to Immich.',
|
||||
url: 'https://github.com/bmachek/lrc-immich-plugin',
|
||||
description:
|
||||
'Lightroom plugin to publish, export photos from Lightroom to Immich. Import from Immich to Lightroom is also supported.',
|
||||
url: 'https://blog.fokuspunk.de/lrc-immich-plugin/',
|
||||
},
|
||||
{
|
||||
title: 'Immich Duplicate Finder',
|
||||
|
||||
5
docs/src/pages/errors.md
Normal file
5
docs/src/pages/errors.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Errors
|
||||
|
||||
## TypeORM Upgrade
|
||||
|
||||
The upgrade to Immich `v2.x.x` has a required upgrade path to `v1.132.0+`. This means it is required to start up the application at least once on version `1.132.0` (or later). Doing so will complete database schema upgrades that are required for `v2.0.0`. After Immich has successfully booted on this version, shut the system down and try the `v2.x.x` upgrade again.
|
||||
@@ -4,6 +4,7 @@ import Layout from '@theme/Layout';
|
||||
import { discordPath, discordViewBox } from '@site/src/components/svg-paths';
|
||||
import ThemedImage from '@theme/ThemedImage';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiAndroid } from '@mdi/js';
|
||||
function HomepageHeader() {
|
||||
return (
|
||||
<header>
|
||||
@@ -88,11 +89,18 @@ function HomepageHeader() {
|
||||
<img className="h-24" alt="Get it on Google Play" src="/img/google-play-badge.png" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="h-24">
|
||||
<a href="https://apps.apple.com/sg/app/immich/id1613945652">
|
||||
<img className="h-24 sm:p-3.5 p-3" alt="Download on the App Store" src="/img/ios-app-store-badge.svg" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="h-24">
|
||||
<a href="https://github.com/immich-app/immich/releases/latest">
|
||||
<img className="h-24 sm:p-3.5 p-3" alt="Download APK" src="/img/download-apk-github.svg" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<ThemedImage
|
||||
sources={{ dark: '/img/app-qr-code-dark.svg', light: '/img/app-qr-code-light.svg' }}
|
||||
|
||||
@@ -76,6 +76,7 @@ import {
|
||||
mdiWeb,
|
||||
mdiDatabaseOutline,
|
||||
mdiLinkEdit,
|
||||
mdiTagFaces,
|
||||
mdiMovieOpenPlayOutline,
|
||||
} from '@mdi/js';
|
||||
import Layout from '@theme/Layout';
|
||||
@@ -83,6 +84,8 @@ import React from 'react';
|
||||
import { Item, Timeline } from '../components/timeline';
|
||||
|
||||
const releases = {
|
||||
'v1.130.0': new Date(2025, 2, 25),
|
||||
'v1.127.0': new Date(2025, 1, 26),
|
||||
'v1.122.0': new Date(2024, 11, 5),
|
||||
'v1.120.0': new Date(2024, 10, 6),
|
||||
'v1.114.0': new Date(2024, 8, 6),
|
||||
@@ -242,6 +245,13 @@ const roadmap: Item[] = [
|
||||
];
|
||||
|
||||
const milestones: Item[] = [
|
||||
withRelease({
|
||||
icon: mdiFolderMultiple,
|
||||
iconColor: 'brown',
|
||||
title: 'Folders view in the mobile app',
|
||||
description: 'Browse your photos and videos in their folder structure inside the mobile app',
|
||||
release: 'v1.130.0',
|
||||
}),
|
||||
{
|
||||
icon: mdiStar,
|
||||
iconColor: 'gold',
|
||||
@@ -249,6 +259,14 @@ const milestones: Item[] = [
|
||||
description: 'Reached 60K Stars on GitHub!',
|
||||
getDateLabel: withLanguage(new Date(2025, 2, 4)),
|
||||
},
|
||||
withRelease({
|
||||
icon: mdiTagFaces,
|
||||
iconColor: 'teal',
|
||||
title: 'Manual face tagging',
|
||||
description:
|
||||
'Manually tag or remove faces in photos and videos, even when automatic detection misses or misidentifies them.',
|
||||
release: 'v1.127.0',
|
||||
}),
|
||||
withRelease({
|
||||
icon: mdiLinkEdit,
|
||||
iconColor: 'crimson',
|
||||
@@ -266,8 +284,8 @@ const milestones: Item[] = [
|
||||
withRelease({
|
||||
icon: mdiDatabaseOutline,
|
||||
iconColor: 'brown',
|
||||
title: 'Automatic database backups',
|
||||
description: 'Database backups are now integrated into the Immich server',
|
||||
title: 'Automatic database dumps',
|
||||
description: 'Database dumps are now integrated into the Immich server',
|
||||
release: 'v1.120.0',
|
||||
}),
|
||||
{
|
||||
@@ -300,7 +318,7 @@ const milestones: Item[] = [
|
||||
withRelease({
|
||||
icon: mdiFolderMultiple,
|
||||
iconColor: 'brown',
|
||||
title: 'Folders',
|
||||
title: 'Folders view',
|
||||
description: 'Browse your photos and videos in their folder structure',
|
||||
release: 'v1.113.0',
|
||||
}),
|
||||
|
||||
5
docs/static/.well-known/security.txt
vendored
Normal file
5
docs/static/.well-known/security.txt
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
Policy: https://github.com/immich-app/immich/blob/main/SECURITY.md
|
||||
Contact: mailto:security@immich.app
|
||||
Preferred-Languages: en
|
||||
Expires: 2026-05-01T23:59:00.000Z
|
||||
Canonical: https://immich.app/.well-known/security.txt
|
||||
40
docs/static/archived-versions.json
vendored
40
docs/static/archived-versions.json
vendored
@@ -1,4 +1,44 @@
|
||||
[
|
||||
{
|
||||
"label": "v1.132.3",
|
||||
"url": "https://v1.132.3.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.132.2",
|
||||
"url": "https://v1.132.2.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.132.1",
|
||||
"url": "https://v1.132.1.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.132.0",
|
||||
"url": "https://v1.132.0.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.131.3",
|
||||
"url": "https://v1.131.3.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.131.2",
|
||||
"url": "https://v1.131.2.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.131.1",
|
||||
"url": "https://v1.131.1.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.131.0",
|
||||
"url": "https://v1.131.0.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.130.3",
|
||||
"url": "https://v1.130.3.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.130.2",
|
||||
"url": "https://v1.130.2.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.130.1",
|
||||
"url": "https://v1.130.1.archive.immich.app"
|
||||
|
||||
13
docs/static/img/download-apk-github.svg
vendored
Normal file
13
docs/static/img/download-apk-github.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 14 KiB |
@@ -28,14 +28,10 @@ services:
|
||||
extra_hosts:
|
||||
- 'auth-server:host-gateway'
|
||||
depends_on:
|
||||
- redis
|
||||
- database
|
||||
ports:
|
||||
- 2285:2285
|
||||
|
||||
redis:
|
||||
image: redis:6.2-alpine@sha256:148bb5411c184abd288d9aaed139c98123eeb8824c5d3fce03cf721db58066d8
|
||||
|
||||
database:
|
||||
image: tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52
|
||||
command: -c fsync=off -c shared_preload_libraries=vectors.so
|
||||
|
||||
@@ -1,39 +1,29 @@
|
||||
import { FlatCompat } from '@eslint/eslintrc';
|
||||
import js from '@eslint/js';
|
||||
import typescriptEslint from '@typescript-eslint/eslint-plugin';
|
||||
import tsParser from '@typescript-eslint/parser';
|
||||
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
|
||||
import eslintPluginUnicorn from 'eslint-plugin-unicorn';
|
||||
import globals from 'globals';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import typescriptEslint from 'typescript-eslint';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: __dirname,
|
||||
recommendedConfig: js.configs.recommended,
|
||||
allConfig: js.configs.all,
|
||||
});
|
||||
|
||||
export default [
|
||||
export default typescriptEslint.config([
|
||||
eslintPluginUnicorn.configs.recommended,
|
||||
eslintPluginPrettierRecommended,
|
||||
js.configs.recommended,
|
||||
typescriptEslint.configs.recommended,
|
||||
{
|
||||
ignores: ['eslint.config.mjs'],
|
||||
},
|
||||
...compat.extends(
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:prettier/recommended',
|
||||
'plugin:unicorn/recommended',
|
||||
),
|
||||
{
|
||||
plugins: {
|
||||
'@typescript-eslint': typescriptEslint,
|
||||
},
|
||||
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.node,
|
||||
},
|
||||
|
||||
parser: tsParser,
|
||||
parser: typescriptEslint.parser,
|
||||
ecmaVersion: 5,
|
||||
sourceType: 'module',
|
||||
|
||||
@@ -62,4 +52,4 @@ export default [
|
||||
'object-shorthand': ['error', 'always'],
|
||||
},
|
||||
},
|
||||
];
|
||||
]);
|
||||
|
||||
3441
e2e/package-lock.json
generated
3441
e2e/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "immich-e2e",
|
||||
"version": "1.130.1",
|
||||
"version": "1.132.3",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
@@ -25,18 +25,16 @@
|
||||
"@immich/sdk": "file:../open-api/typescript-sdk",
|
||||
"@playwright/test": "^1.44.1",
|
||||
"@types/luxon": "^3.4.2",
|
||||
"@types/node": "^22.13.10",
|
||||
"@types/node": "^22.14.1",
|
||||
"@types/oidc-provider": "^8.5.1",
|
||||
"@types/pg": "^8.11.0",
|
||||
"@types/pngjs": "^6.0.4",
|
||||
"@types/supertest": "^6.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
||||
"@typescript-eslint/parser": "^8.15.0",
|
||||
"@vitest/coverage-v8": "^3.0.0",
|
||||
"eslint": "^9.14.0",
|
||||
"eslint-config-prettier": "^10.0.0",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"eslint-plugin-unicorn": "^56.0.1",
|
||||
"eslint-plugin-unicorn": "^57.0.0",
|
||||
"exiftool-vendored": "^28.3.1",
|
||||
"globals": "^16.0.0",
|
||||
"jose": "^5.6.3",
|
||||
@@ -49,6 +47,7 @@
|
||||
"socket.io-client": "^4.7.4",
|
||||
"supertest": "^7.0.0",
|
||||
"typescript": "^5.3.3",
|
||||
"typescript-eslint": "^8.28.0",
|
||||
"utimes": "^5.2.1",
|
||||
"vitest": "^3.0.0"
|
||||
},
|
||||
|
||||
@@ -1141,7 +1141,7 @@ describe('/asset', () => {
|
||||
fNumber: 8,
|
||||
focalLength: 97,
|
||||
iso: 100,
|
||||
lensModel: 'E PZ 18-105mm F4 G OSS',
|
||||
lensModel: 'Sony E PZ 18-105mm F4 G OSS',
|
||||
fileSizeInByte: 25_001_984,
|
||||
dateTimeOriginal: '2016-09-27T10:51:44+00:00',
|
||||
orientation: '1',
|
||||
@@ -1163,7 +1163,7 @@ describe('/asset', () => {
|
||||
fNumber: 22,
|
||||
focalLength: 25,
|
||||
iso: 100,
|
||||
lensModel: 'E 25mm F2',
|
||||
lensModel: 'Zeiss Batis 25mm F2',
|
||||
fileSizeInByte: 49_512_448,
|
||||
dateTimeOriginal: '2016-01-08T14:08:01+00:00',
|
||||
orientation: '1',
|
||||
@@ -1234,7 +1234,7 @@ describe('/asset', () => {
|
||||
focalLength: 18.3,
|
||||
iso: 100,
|
||||
latitude: 36.613_24,
|
||||
lensModel: 'GR LENS 18.3mm F2.8',
|
||||
lensModel: '18.3mm F2.8',
|
||||
longitude: -121.897_85,
|
||||
make: 'RICOH IMAGING COMPANY, LTD.',
|
||||
model: 'RICOH GR III',
|
||||
@@ -1257,6 +1257,7 @@ describe('/asset', () => {
|
||||
|
||||
for (const { id, status } of assets) {
|
||||
expect(status).toBe(AssetMediaStatus.Created);
|
||||
// longer timeout as the thumbnail generation from full-size raw files can take a while
|
||||
await utils.waitForWebsocketEvent({ event: 'assetUpload', id });
|
||||
}
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
import { deleteAssets, getAuditFiles, updateAsset, type LoginResponseDto } from '@immich/sdk';
|
||||
import { asBearerAuth, utils } from 'src/utils';
|
||||
import { beforeAll, describe, expect, it } from 'vitest';
|
||||
|
||||
describe('/audits', () => {
|
||||
let admin: LoginResponseDto;
|
||||
|
||||
beforeAll(async () => {
|
||||
await utils.resetDatabase();
|
||||
await utils.resetFilesystem();
|
||||
|
||||
admin = await utils.adminSetup();
|
||||
});
|
||||
|
||||
// TODO: Enable these tests again once #7436 is resolved as these were flaky
|
||||
describe.skip('GET :/file-report', () => {
|
||||
it('excludes assets without issues from report', async () => {
|
||||
const [trashedAsset, archivedAsset] = await Promise.all([
|
||||
utils.createAsset(admin.accessToken),
|
||||
utils.createAsset(admin.accessToken),
|
||||
utils.createAsset(admin.accessToken),
|
||||
]);
|
||||
|
||||
await Promise.all([
|
||||
deleteAssets({ assetBulkDeleteDto: { ids: [trashedAsset.id] } }, { headers: asBearerAuth(admin.accessToken) }),
|
||||
updateAsset(
|
||||
{
|
||||
id: archivedAsset.id,
|
||||
updateAssetDto: { isArchived: true },
|
||||
},
|
||||
{ headers: asBearerAuth(admin.accessToken) },
|
||||
),
|
||||
]);
|
||||
|
||||
const body = await getAuditFiles({
|
||||
headers: asBearerAuth(admin.accessToken),
|
||||
});
|
||||
|
||||
expect(body.orphans).toHaveLength(0);
|
||||
expect(body.extras).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -5,7 +5,7 @@ import { app, utils } from 'src/utils';
|
||||
import request from 'supertest';
|
||||
import { beforeEach, describe, expect, it } from 'vitest';
|
||||
|
||||
const { name, email, password } = signupDto.admin;
|
||||
const { email, password } = signupDto.admin;
|
||||
|
||||
describe(`/auth/admin-sign-up`, () => {
|
||||
beforeEach(async () => {
|
||||
@@ -13,33 +13,6 @@ describe(`/auth/admin-sign-up`, () => {
|
||||
});
|
||||
|
||||
describe('POST /auth/admin-sign-up', () => {
|
||||
const invalid = [
|
||||
{
|
||||
should: 'require an email address',
|
||||
data: { name, password },
|
||||
},
|
||||
{
|
||||
should: 'require a password',
|
||||
data: { name, email },
|
||||
},
|
||||
{
|
||||
should: 'require a name',
|
||||
data: { email, password },
|
||||
},
|
||||
{
|
||||
should: 'require a valid email',
|
||||
data: { name, email: 'immich', password },
|
||||
},
|
||||
];
|
||||
|
||||
for (const { should, data } of invalid) {
|
||||
it(`should ${should}`, async () => {
|
||||
const { status, body } = await request(app).post('/auth/admin-sign-up').send(data);
|
||||
expect(status).toEqual(400);
|
||||
expect(body).toEqual(errorDto.badRequest());
|
||||
});
|
||||
}
|
||||
|
||||
it(`should sign up the admin`, async () => {
|
||||
const { status, body } = await request(app).post('/auth/admin-sign-up').send(signupDto.admin);
|
||||
expect(status).toBe(201);
|
||||
@@ -57,14 +30,6 @@ describe(`/auth/admin-sign-up`, () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should transform email to lower case', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/auth/admin-sign-up')
|
||||
.send({ ...signupDto.admin, email: 'aDmIn@IMMICH.cloud' });
|
||||
expect(status).toEqual(201);
|
||||
expect(body).toEqual(signupResponseDto.admin);
|
||||
});
|
||||
|
||||
it('should not allow a second admin to sign up', async () => {
|
||||
await signUpAdmin({ signUpDto: signupDto.admin });
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ describe('/jobs', () => {
|
||||
}
|
||||
|
||||
await utils.jobCommand(admin.accessToken, JobName.MetadataExtraction, {
|
||||
command: JobCommand.Empty,
|
||||
command: JobCommand.Clear,
|
||||
force: false,
|
||||
});
|
||||
|
||||
@@ -160,7 +160,7 @@ describe('/jobs', () => {
|
||||
expect(assetBefore.thumbhash).toBeNull();
|
||||
|
||||
await utils.jobCommand(admin.accessToken, JobName.ThumbnailGeneration, {
|
||||
command: JobCommand.Empty,
|
||||
command: JobCommand.Clear,
|
||||
force: false,
|
||||
});
|
||||
|
||||
|
||||
@@ -329,7 +329,7 @@ describe('/libraries', () => {
|
||||
const library = await utils.createLibrary(admin.accessToken, {
|
||||
ownerId: admin.userId,
|
||||
importPaths: [`${testAssetDirInternal}/temp`],
|
||||
exclusionPatterns: ['**/directoryA'],
|
||||
exclusionPatterns: ['**/directoryA/**'],
|
||||
});
|
||||
|
||||
await utils.scan(admin.accessToken, library.id);
|
||||
@@ -337,7 +337,82 @@ describe('/libraries', () => {
|
||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
||||
|
||||
expect(assets.count).toBe(1);
|
||||
expect(assets.items[0].originalPath.includes('directoryB'));
|
||||
|
||||
expect(assets.items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ originalPath: expect.stringContaining('directoryB/assetB.png') }),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should scan external library with multiple exclusion patterns', async () => {
|
||||
const library = await utils.createLibrary(admin.accessToken, {
|
||||
ownerId: admin.userId,
|
||||
importPaths: [`${testAssetDirInternal}/temp`],
|
||||
exclusionPatterns: ['**/directoryA/**', '**/directoryB/**'],
|
||||
});
|
||||
|
||||
await utils.scan(admin.accessToken, library.id);
|
||||
|
||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
||||
|
||||
expect(assets.count).toBe(0);
|
||||
|
||||
expect(assets.items).toEqual([]);
|
||||
});
|
||||
|
||||
it('should remove assets covered by a new exclusion pattern', async () => {
|
||||
const library = await utils.createLibrary(admin.accessToken, {
|
||||
ownerId: admin.userId,
|
||||
importPaths: [`${testAssetDirInternal}/temp`],
|
||||
});
|
||||
|
||||
await utils.scan(admin.accessToken, library.id);
|
||||
|
||||
{
|
||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
||||
|
||||
expect(assets.count).toBe(2);
|
||||
|
||||
expect(assets.items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ originalPath: expect.stringContaining('directoryA/assetA.png') }),
|
||||
expect.objectContaining({ originalPath: expect.stringContaining('directoryB/assetB.png') }),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
await utils.updateLibrary(admin.accessToken, library.id, {
|
||||
exclusionPatterns: ['**/directoryA/**'],
|
||||
});
|
||||
|
||||
await utils.scan(admin.accessToken, library.id);
|
||||
|
||||
{
|
||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
||||
|
||||
expect(assets.count).toBe(1);
|
||||
|
||||
expect(assets.items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ originalPath: expect.stringContaining('directoryB/assetB.png') }),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
await utils.updateLibrary(admin.accessToken, library.id, {
|
||||
exclusionPatterns: ['**/directoryA/**', '**/directoryB/**'],
|
||||
});
|
||||
|
||||
await utils.scan(admin.accessToken, library.id);
|
||||
|
||||
{
|
||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
||||
|
||||
expect(assets.count).toBe(0);
|
||||
|
||||
expect(assets.items).toEqual([]);
|
||||
}
|
||||
});
|
||||
|
||||
it('should scan multiple import paths', async () => {
|
||||
@@ -454,6 +529,133 @@ describe('/libraries', () => {
|
||||
utils.removeImageFile(`${testAssetDir}/temp/folder${char}2/asset2.png`);
|
||||
});
|
||||
|
||||
it('should respect exclusion patterns when using multiple import paths', async () => {
|
||||
// https://github.com/immich-app/immich/issues/17121
|
||||
const library = await utils.createLibrary(admin.accessToken, {
|
||||
ownerId: admin.userId,
|
||||
importPaths: [`${testAssetDirInternal}/temp/exclusion/`, `${testAssetDirInternal}/temp/exclusion2/`],
|
||||
});
|
||||
|
||||
const excludedFolder = `Raw`;
|
||||
|
||||
utils.createImageFile(`${testAssetDir}/temp/exclusion/asset1.png`);
|
||||
utils.createImageFile(`${testAssetDir}/temp/exclusion/${excludedFolder}/asset2.png`);
|
||||
|
||||
await utils.scan(admin.accessToken, library.id);
|
||||
|
||||
{
|
||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
||||
|
||||
expect(assets.items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
|
||||
expect.objectContaining({ originalPath: expect.stringContaining(`${excludedFolder}/asset2.png`) }),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
await utils.scan(admin.accessToken, library.id);
|
||||
|
||||
{
|
||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
||||
|
||||
expect(assets.items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
|
||||
expect.objectContaining({ originalPath: expect.stringContaining(`${excludedFolder}/asset2.png`) }),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
await utils.updateLibrary(admin.accessToken, library.id, { exclusionPatterns: [`**/${excludedFolder}/**`] });
|
||||
await utils.scan(admin.accessToken, library.id);
|
||||
|
||||
{
|
||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
||||
|
||||
expect(assets.items).toEqual([
|
||||
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
|
||||
]);
|
||||
}
|
||||
|
||||
await utils.scan(admin.accessToken, library.id);
|
||||
|
||||
{
|
||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
||||
|
||||
expect(assets.items).toEqual([
|
||||
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
|
||||
]);
|
||||
}
|
||||
|
||||
utils.removeImageFile(`${testAssetDir}/temp/exclusion/asset1.png`);
|
||||
utils.removeImageFile(`${testAssetDir}/temp/exclusion/${excludedFolder}/asset2.png`);
|
||||
});
|
||||
|
||||
const annoyingExclusionPatterns = ['@', '#', '$', '%', '^', '&', '='];
|
||||
|
||||
it.each(annoyingExclusionPatterns)('should support exclusion patterns with %s', async (char) => {
|
||||
const library = await utils.createLibrary(admin.accessToken, {
|
||||
ownerId: admin.userId,
|
||||
importPaths: [`${testAssetDirInternal}/temp/exclusion/`],
|
||||
});
|
||||
|
||||
const excludedFolder = `${char}folder`;
|
||||
|
||||
utils.createImageFile(`${testAssetDir}/temp/exclusion/asset1.png`);
|
||||
utils.createImageFile(`${testAssetDir}/temp/exclusion/${excludedFolder}/asset2.png`);
|
||||
|
||||
await utils.scan(admin.accessToken, library.id);
|
||||
|
||||
{
|
||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
||||
|
||||
expect(assets.items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
|
||||
expect.objectContaining({ originalPath: expect.stringContaining(`${excludedFolder}/asset2.png`) }),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
await utils.scan(admin.accessToken, library.id);
|
||||
|
||||
{
|
||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
||||
|
||||
expect(assets.items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
|
||||
expect.objectContaining({ originalPath: expect.stringContaining(`${excludedFolder}/asset2.png`) }),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
await utils.updateLibrary(admin.accessToken, library.id, { exclusionPatterns: [`**/${excludedFolder}/**`] });
|
||||
await utils.scan(admin.accessToken, library.id);
|
||||
|
||||
{
|
||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
||||
|
||||
expect(assets.items).toEqual([
|
||||
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
|
||||
]);
|
||||
}
|
||||
|
||||
await utils.scan(admin.accessToken, library.id);
|
||||
|
||||
{
|
||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
||||
|
||||
expect(assets.items).toEqual([
|
||||
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
|
||||
]);
|
||||
}
|
||||
|
||||
utils.removeImageFile(`${testAssetDir}/temp/exclusion/asset1.png`);
|
||||
utils.removeImageFile(`${testAssetDir}/temp/exclusion/${excludedFolder}/asset2.png`);
|
||||
});
|
||||
|
||||
it('should reimport a modified file', async () => {
|
||||
const library = await utils.createLibrary(admin.accessToken, {
|
||||
ownerId: admin.userId,
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
startOAuth,
|
||||
updateConfig,
|
||||
} from '@immich/sdk';
|
||||
import { createHash, randomBytes } from 'node:crypto';
|
||||
import { errorDto } from 'src/responses';
|
||||
import { OAuthClient, OAuthUser } from 'src/setup/auth-server';
|
||||
import { app, asBearerAuth, baseUrl, utils } from 'src/utils';
|
||||
@@ -21,18 +22,30 @@ const mobileOverrideRedirectUri = 'https://photos.immich.app/oauth/mobile-redire
|
||||
|
||||
const redirect = async (url: string, cookies?: string[]) => {
|
||||
const { headers } = await request(url)
|
||||
.get('/')
|
||||
.get('')
|
||||
.set('Cookie', cookies || []);
|
||||
return { cookies: (headers['set-cookie'] as unknown as string[]) || [], location: headers.location };
|
||||
};
|
||||
|
||||
// Function to generate a code challenge from the verifier
|
||||
const generateCodeChallenge = async (codeVerifier: string): Promise<string> => {
|
||||
const hashed = createHash('sha256').update(codeVerifier).digest();
|
||||
return hashed.toString('base64url');
|
||||
};
|
||||
|
||||
const loginWithOAuth = async (sub: OAuthUser | string, redirectUri?: string) => {
|
||||
const { url } = await startOAuth({ oAuthConfigDto: { redirectUri: redirectUri ?? `${baseUrl}/auth/login` } });
|
||||
const state = randomBytes(16).toString('base64url');
|
||||
const codeVerifier = randomBytes(64).toString('base64url');
|
||||
const codeChallenge = await generateCodeChallenge(codeVerifier);
|
||||
|
||||
const { url } = await startOAuth({
|
||||
oAuthConfigDto: { redirectUri: redirectUri ?? `${baseUrl}/auth/login`, state, codeChallenge },
|
||||
});
|
||||
|
||||
// login
|
||||
const response1 = await redirect(url.replace(authServer.internal, authServer.external));
|
||||
const response2 = await request(authServer.external + response1.location)
|
||||
.post('/')
|
||||
.post('')
|
||||
.set('Cookie', response1.cookies)
|
||||
.type('form')
|
||||
.send({ prompt: 'login', login: sub, password: 'password' });
|
||||
@@ -40,7 +53,7 @@ const loginWithOAuth = async (sub: OAuthUser | string, redirectUri?: string) =>
|
||||
// approve
|
||||
const response3 = await redirect(response2.header.location, response1.cookies);
|
||||
const response4 = await request(authServer.external + response3.location)
|
||||
.post('/')
|
||||
.post('')
|
||||
.type('form')
|
||||
.set('Cookie', response3.cookies)
|
||||
.send({ prompt: 'consent' });
|
||||
@@ -51,9 +64,9 @@ const loginWithOAuth = async (sub: OAuthUser | string, redirectUri?: string) =>
|
||||
expect(redirectUrl).toBeDefined();
|
||||
const params = new URL(redirectUrl).searchParams;
|
||||
expect(params.get('code')).toBeDefined();
|
||||
expect(params.get('state')).toBeDefined();
|
||||
expect(params.get('state')).toBe(state);
|
||||
|
||||
return redirectUrl;
|
||||
return { url: redirectUrl, state, codeVerifier };
|
||||
};
|
||||
|
||||
const setupOAuth = async (token: string, dto: Partial<SystemConfigOAuthDto>) => {
|
||||
@@ -119,9 +132,42 @@ describe(`/oauth`, () => {
|
||||
expect(body).toEqual(errorDto.badRequest(['url should not be empty']));
|
||||
});
|
||||
|
||||
it('should auto register the user by default', async () => {
|
||||
const url = await loginWithOAuth('oauth-auto-register');
|
||||
it(`should throw an error if the state is not provided`, async () => {
|
||||
const { url } = await loginWithOAuth('oauth-auto-register');
|
||||
const { status, body } = await request(app).post('/oauth/callback').send({ url });
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest('OAuth state is missing'));
|
||||
});
|
||||
|
||||
it(`should throw an error if the state mismatches`, async () => {
|
||||
const callbackParams = await loginWithOAuth('oauth-auto-register');
|
||||
const { state } = await loginWithOAuth('oauth-auto-register');
|
||||
const { status } = await request(app)
|
||||
.post('/oauth/callback')
|
||||
.send({ ...callbackParams, state });
|
||||
expect(status).toBeGreaterThanOrEqual(400);
|
||||
});
|
||||
|
||||
it(`should throw an error if the codeVerifier is not provided`, async () => {
|
||||
const { url, state } = await loginWithOAuth('oauth-auto-register');
|
||||
const { status, body } = await request(app).post('/oauth/callback').send({ url, state });
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest('OAuth code verifier is missing'));
|
||||
});
|
||||
|
||||
it(`should throw an error if the codeVerifier doesn't match the challenge`, async () => {
|
||||
const callbackParams = await loginWithOAuth('oauth-auto-register');
|
||||
const { codeVerifier } = await loginWithOAuth('oauth-auto-register');
|
||||
const { status, body } = await request(app)
|
||||
.post('/oauth/callback')
|
||||
.send({ ...callbackParams, codeVerifier });
|
||||
console.log(body);
|
||||
expect(status).toBeGreaterThanOrEqual(400);
|
||||
});
|
||||
|
||||
it('should auto register the user by default', async () => {
|
||||
const callbackParams = await loginWithOAuth('oauth-auto-register');
|
||||
const { status, body } = await request(app).post('/oauth/callback').send(callbackParams);
|
||||
expect(status).toBe(201);
|
||||
expect(body).toMatchObject({
|
||||
accessToken: expect.any(String),
|
||||
@@ -132,16 +178,30 @@ describe(`/oauth`, () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow passing state and codeVerifier via cookies', async () => {
|
||||
const { url, state, codeVerifier } = await loginWithOAuth('oauth-auto-register');
|
||||
const { status, body } = await request(app)
|
||||
.post('/oauth/callback')
|
||||
.set('Cookie', [`immich_oauth_state=${state}`, `immich_oauth_code_verifier=${codeVerifier}`])
|
||||
.send({ url });
|
||||
expect(status).toBe(201);
|
||||
expect(body).toMatchObject({
|
||||
accessToken: expect.any(String),
|
||||
userId: expect.any(String),
|
||||
userEmail: 'oauth-auto-register@immich.app',
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle a user without an email', async () => {
|
||||
const url = await loginWithOAuth(OAuthUser.NO_EMAIL);
|
||||
const { status, body } = await request(app).post('/oauth/callback').send({ url });
|
||||
const callbackParams = await loginWithOAuth(OAuthUser.NO_EMAIL);
|
||||
const { status, body } = await request(app).post('/oauth/callback').send(callbackParams);
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest('OAuth profile does not have an email address'));
|
||||
});
|
||||
|
||||
it('should set the quota from a claim', async () => {
|
||||
const url = await loginWithOAuth(OAuthUser.WITH_QUOTA);
|
||||
const { status, body } = await request(app).post('/oauth/callback').send({ url });
|
||||
const callbackParams = await loginWithOAuth(OAuthUser.WITH_QUOTA);
|
||||
const { status, body } = await request(app).post('/oauth/callback').send(callbackParams);
|
||||
expect(status).toBe(201);
|
||||
expect(body).toMatchObject({
|
||||
accessToken: expect.any(String),
|
||||
@@ -154,8 +214,8 @@ describe(`/oauth`, () => {
|
||||
});
|
||||
|
||||
it('should set the storage label from a claim', async () => {
|
||||
const url = await loginWithOAuth(OAuthUser.WITH_USERNAME);
|
||||
const { status, body } = await request(app).post('/oauth/callback').send({ url });
|
||||
const callbackParams = await loginWithOAuth(OAuthUser.WITH_USERNAME);
|
||||
const { status, body } = await request(app).post('/oauth/callback').send(callbackParams);
|
||||
expect(status).toBe(201);
|
||||
expect(body).toMatchObject({
|
||||
accessToken: expect.any(String),
|
||||
@@ -176,8 +236,8 @@ describe(`/oauth`, () => {
|
||||
buttonText: 'Login with Immich',
|
||||
signingAlgorithm: 'RS256',
|
||||
});
|
||||
const url = await loginWithOAuth('oauth-RS256-token');
|
||||
const { status, body } = await request(app).post('/oauth/callback').send({ url });
|
||||
const callbackParams = await loginWithOAuth('oauth-RS256-token');
|
||||
const { status, body } = await request(app).post('/oauth/callback').send(callbackParams);
|
||||
expect(status).toBe(201);
|
||||
expect(body).toMatchObject({
|
||||
accessToken: expect.any(String),
|
||||
@@ -196,8 +256,8 @@ describe(`/oauth`, () => {
|
||||
buttonText: 'Login with Immich',
|
||||
profileSigningAlgorithm: 'RS256',
|
||||
});
|
||||
const url = await loginWithOAuth('oauth-signed-profile');
|
||||
const { status, body } = await request(app).post('/oauth/callback').send({ url });
|
||||
const callbackParams = await loginWithOAuth('oauth-signed-profile');
|
||||
const { status, body } = await request(app).post('/oauth/callback').send(callbackParams);
|
||||
expect(status).toBe(201);
|
||||
expect(body).toMatchObject({
|
||||
userId: expect.any(String),
|
||||
@@ -213,8 +273,8 @@ describe(`/oauth`, () => {
|
||||
buttonText: 'Login with Immich',
|
||||
signingAlgorithm: 'something-that-does-not-work',
|
||||
});
|
||||
const url = await loginWithOAuth('oauth-signed-bad');
|
||||
const { status, body } = await request(app).post('/oauth/callback').send({ url });
|
||||
const callbackParams = await loginWithOAuth('oauth-signed-bad');
|
||||
const { status, body } = await request(app).post('/oauth/callback').send(callbackParams);
|
||||
expect(status).toBe(500);
|
||||
expect(body).toMatchObject({
|
||||
error: 'Internal Server Error',
|
||||
@@ -235,8 +295,8 @@ describe(`/oauth`, () => {
|
||||
});
|
||||
|
||||
it('should not auto register the user', async () => {
|
||||
const url = await loginWithOAuth('oauth-no-auto-register');
|
||||
const { status, body } = await request(app).post('/oauth/callback').send({ url });
|
||||
const callbackParams = await loginWithOAuth('oauth-no-auto-register');
|
||||
const { status, body } = await request(app).post('/oauth/callback').send(callbackParams);
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest('User does not exist and auto registering is disabled.'));
|
||||
});
|
||||
@@ -247,8 +307,8 @@ describe(`/oauth`, () => {
|
||||
email: 'oauth-user3@immich.app',
|
||||
password: 'password',
|
||||
});
|
||||
const url = await loginWithOAuth('oauth-user3');
|
||||
const { status, body } = await request(app).post('/oauth/callback').send({ url });
|
||||
const callbackParams = await loginWithOAuth('oauth-user3');
|
||||
const { status, body } = await request(app).post('/oauth/callback').send(callbackParams);
|
||||
expect(status).toBe(201);
|
||||
expect(body).toMatchObject({
|
||||
userId,
|
||||
@@ -286,13 +346,15 @@ describe(`/oauth`, () => {
|
||||
});
|
||||
|
||||
it('should auto register the user by default', async () => {
|
||||
const url = await loginWithOAuth('oauth-mobile-override', 'app.immich:///oauth-callback');
|
||||
expect(url).toEqual(expect.stringContaining(mobileOverrideRedirectUri));
|
||||
const callbackParams = await loginWithOAuth('oauth-mobile-override', 'app.immich:///oauth-callback');
|
||||
expect(callbackParams.url).toEqual(expect.stringContaining(mobileOverrideRedirectUri));
|
||||
|
||||
// simulate redirecting back to mobile app
|
||||
const redirectUri = url.replace(mobileOverrideRedirectUri, 'app.immich:///oauth-callback');
|
||||
const url = callbackParams.url.replace(mobileOverrideRedirectUri, 'app.immich:///oauth-callback');
|
||||
|
||||
const { status, body } = await request(app).post('/oauth/callback').send({ url: redirectUri });
|
||||
const { status, body } = await request(app)
|
||||
.post('/oauth/callback')
|
||||
.send({ ...callbackParams, url });
|
||||
expect(status).toBe(201);
|
||||
expect(body).toMatchObject({
|
||||
accessToken: expect.any(String),
|
||||
|
||||
@@ -117,7 +117,7 @@ describe('/shared-links', () => {
|
||||
const resp = await request(shareUrl).get(`/${linkWithAssets.key}`);
|
||||
expect(resp.status).toBe(200);
|
||||
expect(resp.header['content-type']).toContain('text/html');
|
||||
expect(resp.text).toContain(`<meta property="og:image" content="http://`);
|
||||
expect(resp.text).toContain(`<meta property="og:image" content="https://my.immich.app`);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -246,15 +246,7 @@ describe('/shared-links', () => {
|
||||
const { status, body } = await request(app).get('/shared-links/me').query({ key: linkWithMetadata.key });
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body.assets).toHaveLength(1);
|
||||
expect(body.assets[0]).toEqual(
|
||||
expect.objectContaining({
|
||||
originalFileName: 'example.png',
|
||||
localDateTime: expect.any(String),
|
||||
fileCreatedAt: expect.any(String),
|
||||
exifInfo: expect.any(Object),
|
||||
}),
|
||||
);
|
||||
expect(body.assets).toHaveLength(0);
|
||||
expect(body.album).toBeDefined();
|
||||
});
|
||||
|
||||
|
||||
@@ -215,6 +215,19 @@ describe('/admin/users', () => {
|
||||
const user = await getMyUser({ headers: asBearerAuth(token.accessToken) });
|
||||
expect(user).toMatchObject({ email: nonAdmin.userEmail });
|
||||
});
|
||||
|
||||
it('should update the avatar color', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/admin/users/${admin.userId}`)
|
||||
.send({ avatarColor: 'orange' })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({ avatarColor: 'orange' });
|
||||
|
||||
const after = await getUserAdmin({ id: admin.userId }, { headers: asBearerAuth(admin.accessToken) });
|
||||
expect(after).toMatchObject({ avatarColor: 'orange' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /admin/users/:id/preferences', () => {
|
||||
@@ -240,19 +253,6 @@ describe('/admin/users', () => {
|
||||
expect(after).toMatchObject({ memories: { enabled: false } });
|
||||
});
|
||||
|
||||
it('should update the avatar color', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/admin/users/${admin.userId}/preferences`)
|
||||
.send({ avatar: { color: 'orange' } })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({ avatar: { color: 'orange' } });
|
||||
|
||||
const after = await getUserPreferencesAdmin({ id: admin.userId }, { headers: asBearerAuth(admin.accessToken) });
|
||||
expect(after).toMatchObject({ avatar: { color: 'orange' } });
|
||||
});
|
||||
|
||||
it('should update download archive size', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/admin/users/${admin.userId}/preferences`)
|
||||
|
||||
@@ -31,33 +31,7 @@ describe('/users', () => {
|
||||
);
|
||||
});
|
||||
|
||||
describe('GET /users', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get('/users');
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should get users', async () => {
|
||||
const { status, body } = await request(app).get('/users').set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toEqual(200);
|
||||
expect(body).toHaveLength(2);
|
||||
expect(body).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ email: 'admin@immich.cloud' }),
|
||||
expect.objectContaining({ email: 'user2@immich.cloud' }),
|
||||
]),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /users/me', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get(`/users/me`);
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should not work for shared links', async () => {
|
||||
const album = await utils.createAlbum(admin.accessToken, { albumName: 'Album' });
|
||||
const sharedLink = await utils.createSharedLink(admin.accessToken, {
|
||||
@@ -99,24 +73,6 @@ describe('/users', () => {
|
||||
});
|
||||
|
||||
describe('PUT /users/me', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).put(`/users/me`);
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
for (const key of ['email', 'name']) {
|
||||
it(`should not allow null ${key}`, async () => {
|
||||
const dto = { [key]: null };
|
||||
const { status, body } = await request(app)
|
||||
.put(`/users/me`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send(dto);
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest());
|
||||
});
|
||||
}
|
||||
|
||||
it('should update first and last name', async () => {
|
||||
const before = await getMyUser({ headers: asBearerAuth(admin.accessToken) });
|
||||
|
||||
@@ -183,6 +139,19 @@ describe('/users', () => {
|
||||
profileChangedAt: expect.anything(),
|
||||
});
|
||||
});
|
||||
|
||||
it('should update avatar color', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/users/me`)
|
||||
.send({ avatarColor: 'blue' })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({ avatarColor: 'blue' });
|
||||
|
||||
const after = await getMyUser({ headers: asBearerAuth(admin.accessToken) });
|
||||
expect(after).toMatchObject({ avatarColor: 'blue' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /users/me/preferences', () => {
|
||||
@@ -202,19 +171,6 @@ describe('/users', () => {
|
||||
expect(after).toMatchObject({ memories: { enabled: false } });
|
||||
});
|
||||
|
||||
it('should update avatar color', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/users/me/preferences`)
|
||||
.send({ avatar: { color: 'blue' } })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({ avatar: { color: 'blue' } });
|
||||
|
||||
const after = await getMyPreferences({ headers: asBearerAuth(admin.accessToken) });
|
||||
expect(after).toMatchObject({ avatar: { color: 'blue' } });
|
||||
});
|
||||
|
||||
it('should require an integer for download archive size', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/users/me/preferences`)
|
||||
@@ -269,11 +225,6 @@ describe('/users', () => {
|
||||
});
|
||||
|
||||
describe('GET /users/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status } = await request(app).get(`/users/${admin.userId}`);
|
||||
expect(status).toEqual(401);
|
||||
});
|
||||
|
||||
it('should get the user', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/users/${admin.userId}`)
|
||||
@@ -292,12 +243,6 @@ describe('/users', () => {
|
||||
});
|
||||
|
||||
describe('GET /server/license', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get('/users/me/license');
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should return the user license', async () => {
|
||||
await request(app)
|
||||
.put('/users/me/license')
|
||||
@@ -315,11 +260,6 @@ describe('/users', () => {
|
||||
});
|
||||
|
||||
describe('PUT /users/me/license', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status } = await request(app).put(`/users/me/license`);
|
||||
expect(status).toEqual(401);
|
||||
});
|
||||
|
||||
it('should set the user license', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/users/me/license`)
|
||||
|
||||
@@ -22,7 +22,7 @@ const tests: Test[] = [
|
||||
},
|
||||
{
|
||||
test: 'should support paths with an asterisk',
|
||||
paths: [`/photos\*/image1.jpg`],
|
||||
paths: [`/photos*/image1.jpg`],
|
||||
files: {
|
||||
'/photos*/image1.jpg': true,
|
||||
'/photos*/image2.jpg': false,
|
||||
@@ -40,7 +40,7 @@ const tests: Test[] = [
|
||||
},
|
||||
{
|
||||
test: 'should support paths with a single quote',
|
||||
paths: [`/photos\'/image1.jpg`],
|
||||
paths: [`/photos'/image1.jpg`],
|
||||
files: {
|
||||
"/photos'/image1.jpg": true,
|
||||
"/photos'/image2.jpg": false,
|
||||
@@ -49,7 +49,7 @@ const tests: Test[] = [
|
||||
},
|
||||
{
|
||||
test: 'should support paths with a double quote',
|
||||
paths: [`/photos\"/image1.jpg`],
|
||||
paths: [`/photos"/image1.jpg`],
|
||||
files: {
|
||||
'/photos"/image1.jpg': true,
|
||||
'/photos"/image2.jpg': false,
|
||||
@@ -67,7 +67,7 @@ const tests: Test[] = [
|
||||
},
|
||||
{
|
||||
test: 'should support paths with an opening brace',
|
||||
paths: [`/photos\{/image1.jpg`],
|
||||
paths: [`/photos{/image1.jpg`],
|
||||
files: {
|
||||
'/photos{/image1.jpg': true,
|
||||
'/photos{/image2.jpg': false,
|
||||
@@ -76,7 +76,7 @@ const tests: Test[] = [
|
||||
},
|
||||
{
|
||||
test: 'should support paths with a closing brace',
|
||||
paths: [`/photos\}/image1.jpg`],
|
||||
paths: [`/photos}/image1.jpg`],
|
||||
files: {
|
||||
'/photos}/image1.jpg': true,
|
||||
'/photos}/image2.jpg': false,
|
||||
|
||||
@@ -537,6 +537,7 @@ export const utils = {
|
||||
},
|
||||
|
||||
waitForQueueFinish: (accessToken: string, queue: keyof AllJobStatusResponseDto, ms?: number) => {
|
||||
// eslint-disable-next-line no-async-promise-executor
|
||||
return new Promise<void>(async (resolve, reject) => {
|
||||
const timeout = setTimeout(() => reject(new Error('Timed out waiting for queue to empty')), ms || 10_000);
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ test.describe('Registration', () => {
|
||||
|
||||
// login
|
||||
await expect(page).toHaveTitle(/Login/);
|
||||
await page.goto('/auth/login');
|
||||
await page.goto('/auth/login?autoLaunch=0');
|
||||
await page.getByLabel('Email').fill('admin@immich.app');
|
||||
await page.getByLabel('Password').fill('password');
|
||||
await page.getByRole('button', { name: 'Login' }).click();
|
||||
@@ -59,7 +59,7 @@ test.describe('Registration', () => {
|
||||
await context.clearCookies();
|
||||
|
||||
// login
|
||||
await page.goto('/auth/login');
|
||||
await page.goto('/auth/login?autoLaunch=0');
|
||||
await page.getByLabel('Email').fill('user@immich.cloud');
|
||||
await page.getByLabel('Password').fill('password');
|
||||
await page.getByRole('button', { name: 'Login' }).click();
|
||||
@@ -72,7 +72,7 @@ test.describe('Registration', () => {
|
||||
await page.getByRole('button', { name: 'Change password' }).click();
|
||||
|
||||
// login with new password
|
||||
await expect(page).toHaveURL('/auth/login');
|
||||
await expect(page).toHaveURL('/auth/login?autoLaunch=0');
|
||||
await page.getByLabel('Email').fill('user@immich.cloud');
|
||||
await page.getByLabel('Password').fill('new-password');
|
||||
await page.getByRole('button', { name: 'Login' }).click();
|
||||
|
||||
@@ -8,35 +8,23 @@ function imageLocator(page: Page) {
|
||||
test.describe('Photo Viewer', () => {
|
||||
let admin: LoginResponseDto;
|
||||
let asset: AssetMediaResponseDto;
|
||||
let rawAsset: AssetMediaResponseDto;
|
||||
|
||||
test.beforeAll(async () => {
|
||||
utils.initSdk();
|
||||
await utils.resetDatabase();
|
||||
admin = await utils.adminSetup();
|
||||
asset = await utils.createAsset(admin.accessToken);
|
||||
rawAsset = await utils.createAsset(admin.accessToken, { assetData: { filename: 'test.arw' } });
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ context, page }) => {
|
||||
// before each test, login as user
|
||||
await utils.setAuthCookies(context, admin.accessToken);
|
||||
await page.goto('/photos');
|
||||
await page.waitForLoadState('networkidle');
|
||||
});
|
||||
|
||||
test('initially shows a loading spinner', async ({ page }) => {
|
||||
await page.route(`/api/assets/${asset.id}/thumbnail**`, async (route) => {
|
||||
// slow down the request for thumbnail, so spinner has chance to show up
|
||||
await new Promise((f) => setTimeout(f, 2000));
|
||||
await route.continue();
|
||||
});
|
||||
await page.goto(`/photos/${asset.id}`);
|
||||
await page.waitForLoadState('load');
|
||||
// this is the spinner
|
||||
await page.waitForSelector('svg[role=status]');
|
||||
await expect(page.getByTestId('loading-spinner')).toBeVisible();
|
||||
});
|
||||
|
||||
test('loads high resolution photo when zoomed', async ({ page }) => {
|
||||
test('loads original photo when zoomed', async ({ page }) => {
|
||||
await page.goto(`/photos/${asset.id}`);
|
||||
await expect.poll(async () => await imageLocator(page).getAttribute('src')).toContain('thumbnail');
|
||||
const box = await imageLocator(page).boundingBox();
|
||||
@@ -47,6 +35,17 @@ test.describe('Photo Viewer', () => {
|
||||
await expect.poll(async () => await imageLocator(page).getAttribute('src')).toContain('original');
|
||||
});
|
||||
|
||||
test('loads fullsize image when zoomed and original is web-incompatible', async ({ page }) => {
|
||||
await page.goto(`/photos/${rawAsset.id}`);
|
||||
await expect.poll(async () => await imageLocator(page).getAttribute('src')).toContain('thumbnail');
|
||||
const box = await imageLocator(page).boundingBox();
|
||||
expect(box).toBeTruthy();
|
||||
const { x, y, width, height } = box!;
|
||||
await page.mouse.move(x + width / 2, y + height / 2);
|
||||
await page.mouse.wheel(0, -1);
|
||||
await expect.poll(async () => await imageLocator(page).getAttribute('src')).toContain('fullsize');
|
||||
});
|
||||
|
||||
test('reloads photo when checksum changes', async ({ page }) => {
|
||||
await page.goto(`/photos/${asset.id}`);
|
||||
await expect.poll(async () => await imageLocator(page).getAttribute('src')).toContain('thumbnail');
|
||||
|
||||
@@ -48,14 +48,14 @@ test.describe('Shared Links', () => {
|
||||
await page.waitForSelector('[data-group] svg');
|
||||
await page.getByRole('checkbox').click();
|
||||
await page.getByRole('button', { name: 'Download' }).click();
|
||||
await page.getByText('DOWNLOADING', { exact: true }).waitFor();
|
||||
await page.waitForEvent('download');
|
||||
});
|
||||
|
||||
test('download all from shared link', async ({ page }) => {
|
||||
await page.goto(`/share/${sharedLink.key}`);
|
||||
await page.getByRole('heading', { name: 'Test Album' }).waitFor();
|
||||
await page.getByRole('button', { name: 'Download' }).click();
|
||||
await page.getByText('DOWNLOADING', { exact: true }).waitFor();
|
||||
await page.waitForEvent('download');
|
||||
});
|
||||
|
||||
test('enter password for a shared link', async ({ page }) => {
|
||||
|
||||
513
i18n/ar.json
513
i18n/ar.json
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,7 @@
|
||||
"account_settings": "Налады ўліковага запісу",
|
||||
"acknowledge": "Пацвердзіць",
|
||||
"action": "Дзеянне",
|
||||
"action_common_update": "Абнавіць",
|
||||
"actions": "Дзеянні",
|
||||
"active": "Актыўны",
|
||||
"activity": "Актыўнасць",
|
||||
@@ -20,8 +21,10 @@
|
||||
"add_partner": "Дадаць партнёра",
|
||||
"add_path": "Дадаць шлях",
|
||||
"add_photos": "Дадаць фота",
|
||||
"add_to": "Дадаць у...",
|
||||
"add_to": "Дадаць у…",
|
||||
"add_to_album": "Дадаць у альбом",
|
||||
"add_to_album_bottom_sheet_added": "Дададзена да {album}",
|
||||
"add_to_album_bottom_sheet_already_exists": "Ужо знаходзіцца ў {album}",
|
||||
"add_to_shared_album": "Дадаць у агульны альбом",
|
||||
"add_url": "Дадаць URL",
|
||||
"added_to_archive": "Дададзена ў архіў",
|
||||
@@ -41,6 +44,7 @@
|
||||
"backup_settings": "Налады рэзервовага капіявання",
|
||||
"backup_settings_description": "Кіраванне наладкамі рэзервовага капіявання базы даных",
|
||||
"check_all": "Праверыць усе",
|
||||
"cleanup": "Ачыстка",
|
||||
"cleared_jobs": "Ачышчаны заданні для: {job}",
|
||||
"config_set_by_file": "Канфігурацыя ў зараз усталявана праз файл канфігурацыі",
|
||||
"confirm_delete_library": "Вы ўпэўнены што жадаеце выдаліць {library} бібліятэку?",
|
||||
|
||||
@@ -162,7 +162,6 @@
|
||||
"no_pattern_added": "Няма добавен модел",
|
||||
"note_apply_storage_label_previous_assets": "Забележка: За да приложите етикета за съхранение към предварително качени файлове, стартирайте",
|
||||
"note_cannot_be_changed_later": "ВНИМАНИЕ: Това не може да бъде променено по-късно!",
|
||||
"note_unlimited_quota": "Бележка: Въведете 0 за да нямате лимит на квотата",
|
||||
"notification_email_from_address": "От адрес",
|
||||
"notification_email_from_address_description": "Електронна поща на изпращача, например: \"Immich Photo Server <noreply@example.com>\"",
|
||||
"notification_email_host_description": "Хост на сървъра за електронна поща (например: smtp.immich.app)",
|
||||
@@ -923,7 +922,6 @@
|
||||
"no_shared_albums_message": "Създайте албум, за да споделяте снимки и видеоклипове с хората в мрежата си",
|
||||
"not_in_any_album": "Не е в никой албум",
|
||||
"note_apply_storage_label_to_previously_uploaded assets": "Забележка: За да приложите етикета за съхранение към предварително качени активи, стартирайте",
|
||||
"note_unlimited_quota": "Забележка: Въведете 0 за неограничена квота",
|
||||
"notes": "Бележки",
|
||||
"notification_toggle_setting_description": "Активиране на имейл известия",
|
||||
"notifications": "Известия",
|
||||
@@ -1374,4 +1372,4 @@
|
||||
"yes": "Да",
|
||||
"you_dont_have_any_shared_links": "Нямате споделени връзки",
|
||||
"zoom_image": "Увеличаване на изображението"
|
||||
}
|
||||
}
|
||||
|
||||
32
i18n/bi.json
32
i18n/bi.json
@@ -1,20 +1,22 @@
|
||||
{
|
||||
"account": "",
|
||||
"account_settings": "",
|
||||
"acknowledge": "",
|
||||
"about": "abaot",
|
||||
"account": "Akaont",
|
||||
"account_settings": "Seting blo Akaont",
|
||||
"acknowledge": "Akcept",
|
||||
"action": "",
|
||||
"actions": "",
|
||||
"active": "",
|
||||
"activity": "",
|
||||
"add": "",
|
||||
"add_a_description": "",
|
||||
"add_a_location": "",
|
||||
"add_a_name": "",
|
||||
"add_a_title": "",
|
||||
"add_exclusion_pattern": "",
|
||||
"add_import_path": "",
|
||||
"add_location": "",
|
||||
"add_more_users": "",
|
||||
"active": "Stap Mekem",
|
||||
"activity": "Wanem hemi Mekem",
|
||||
"activity_changed": "WAnem hemi Mekem hemi",
|
||||
"add": "Ad",
|
||||
"add_a_description": "Putem Description blo hem",
|
||||
"add_a_location": "Putem place blo hem",
|
||||
"add_a_name": "Putem nam blo hem",
|
||||
"add_a_title": "Putem wan name blo hem",
|
||||
"add_exclusion_pattern": "Putem wan paten wae hemi karem aot",
|
||||
"add_import_path": "Putem wan pat blo import",
|
||||
"add_location": "Putem wan place blo hem",
|
||||
"add_more_users": "Putem mor man",
|
||||
"add_partner": "",
|
||||
"add_path": "",
|
||||
"add_photos": "",
|
||||
@@ -116,7 +118,6 @@
|
||||
"no_pattern_added": "",
|
||||
"note_apply_storage_label_previous_assets": "",
|
||||
"note_cannot_be_changed_later": "",
|
||||
"note_unlimited_quota": "",
|
||||
"notification_email_from_address": "",
|
||||
"notification_email_from_address_description": "",
|
||||
"notification_email_host_description": "",
|
||||
@@ -612,7 +613,6 @@
|
||||
"no_shared_albums_message": "",
|
||||
"not_in_any_album": "",
|
||||
"note_apply_storage_label_to_previously_uploaded assets": "",
|
||||
"note_unlimited_quota": "",
|
||||
"notes": "",
|
||||
"notification_toggle_setting_description": "",
|
||||
"notifications": "",
|
||||
|
||||
534
i18n/ca.json
534
i18n/ca.json
File diff suppressed because it is too large
Load Diff
542
i18n/cs.json
542
i18n/cs.json
File diff suppressed because it is too large
Load Diff
514
i18n/da.json
514
i18n/da.json
@@ -4,6 +4,7 @@
|
||||
"account_settings": "Kontoindstillinger",
|
||||
"acknowledge": "Godkend",
|
||||
"action": "Handling",
|
||||
"action_common_update": "Opdater",
|
||||
"actions": "Handlinger",
|
||||
"active": "Aktive",
|
||||
"activity": "Aktivitet",
|
||||
@@ -13,6 +14,7 @@
|
||||
"add_a_location": "Tilføj en placering",
|
||||
"add_a_name": "Tilføj et navn",
|
||||
"add_a_title": "Tilføj en titel",
|
||||
"add_endpoint": "Tilføj endepunkt",
|
||||
"add_exclusion_pattern": "Tilføj udelukkelsesmønster",
|
||||
"add_import_path": "Tilføj importsti",
|
||||
"add_location": "Tilføj placering",
|
||||
@@ -22,6 +24,8 @@
|
||||
"add_photos": "Tilføj billeder",
|
||||
"add_to": "Tilføj til…",
|
||||
"add_to_album": "Tilføj til album",
|
||||
"add_to_album_bottom_sheet_added": "Tilføjet til {album}",
|
||||
"add_to_album_bottom_sheet_already_exists": "Allerede i {album}",
|
||||
"add_to_shared_album": "Tilføj til delt album",
|
||||
"add_url": "Tilføj URL",
|
||||
"added_to_archive": "Tilføjet til arkiv",
|
||||
@@ -66,8 +70,10 @@
|
||||
"forcing_refresh_library_files": "Tvinger genopfriskning af alle biblioteksfiler",
|
||||
"image_format": "Format",
|
||||
"image_format_description": "WebP producerer mindre filer end JPEG, men er langsommere at komprimere.",
|
||||
"image_fullsize_description": "Fuld størrelses billede uden metadata, brugt når zoomet ind",
|
||||
"image_fullsize_enabled": "Aktiver fuld størrelses billede generering",
|
||||
"image_prefer_embedded_preview": "Foretræk indlejret forhåndsvisning",
|
||||
"image_prefer_embedded_preview_setting_description": "Brug indlejrede forhåndsvisninger i RAW fotos som input til billedbehandling, når det er tilgængeligt. Dette kan give mere nøjagtige farver for nogle billeder, men kvaliteten af forhåndsvisningen er kameraafhængig, og billedet kan have flere komprimeringsartefakter.",
|
||||
"image_prefer_embedded_preview_setting_description": "Brug indlejrede forhåndsvisninger i RAW fotos som input til billedbehandling og når det er tilgængeligt. Dette kan give mere nøjagtige farver for nogle billeder, men kvaliteten af forhåndsvisningen er kameraafhængig, og billedet kan have flere komprimeringsartefakter.",
|
||||
"image_prefer_wide_gamut": "Foretrækker bred farveskala",
|
||||
"image_prefer_wide_gamut_setting_description": "Brug Display P3 til miniaturebilleder. Dette bevarer billeder med brede farveskalaers dynamik bedre, men billeder kan komme til at se anderledes ud på gamle enheder med en gammel browserversion. sRGB-billeder bliver beholdt som sRGB for at undgå farveskift.",
|
||||
"image_preview_description": "Mellemstørrelse billede med fjernet metadata, der bruges, når du ser en enkelt mediefil og til machine learning",
|
||||
@@ -162,7 +168,6 @@
|
||||
"no_pattern_added": "Intet mønster tilføjet",
|
||||
"note_apply_storage_label_previous_assets": "Bemærk: For at anvende Lagringsmærkatet på tidligere uploadede mediefiler, kør",
|
||||
"note_cannot_be_changed_later": "BEMÆRK: Dette kan ikke ændres senere!",
|
||||
"note_unlimited_quota": "Bemærk: Indsæt 0 for uendelig kvote",
|
||||
"notification_email_from_address": "Fra adressse",
|
||||
"notification_email_from_address_description": "Afsenderemailadresse, for eksempel: \"Immich Billedserver <noreply@example.com>\"",
|
||||
"notification_email_host_description": "Host af emailserver (fx smtp.immich.app)",
|
||||
@@ -363,6 +368,17 @@
|
||||
"admin_password": "Administratoradgangskode",
|
||||
"administration": "Administration",
|
||||
"advanced": "Avanceret",
|
||||
"advanced_settings_enable_alternate_media_filter_subtitle": "Brug denne valgmulighed for at filtrere media under synkronisering baseret på alternative kriterier. Prøv kun denne hvis du har problemer med at appen ikke opdager alle albums.",
|
||||
"advanced_settings_log_level_title": "Logniveau: {}",
|
||||
"advanced_settings_prefer_remote_subtitle": "Nogle enheder tager meget lang tid om at indlæse miniaturebilleder af elementer på enheden. Aktiver denne indstilling for i stedetat indlæse elementer fra serveren.",
|
||||
"advanced_settings_prefer_remote_title": "Foretræk elementer på serveren",
|
||||
"advanced_settings_proxy_headers_subtitle": "Define proxy headers Immich should send with each network request",
|
||||
"advanced_settings_proxy_headers_title": "Proxy Headers",
|
||||
"advanced_settings_self_signed_ssl_subtitle": "Spring verificering af SSL-certifikat over for serverens endelokation. Kræves for selvsignerede certifikater.",
|
||||
"advanced_settings_self_signed_ssl_title": "Tillad selvsignerede certifikater",
|
||||
"advanced_settings_tile_subtitle": "Avancerede brugerindstillinger",
|
||||
"advanced_settings_troubleshooting_subtitle": "Slå ekstra funktioner for fejlsøgning til",
|
||||
"advanced_settings_troubleshooting_title": "Fejlsøgning",
|
||||
"age_months": "Alder {months, plural, one {# måned} other {# måneder}}",
|
||||
"age_year_months": "Alder 1 år, {months, plural, one {# måned} other {# måneder}}",
|
||||
"age_years": "{years, plural, other {Alder #}}",
|
||||
@@ -371,6 +387,8 @@
|
||||
"album_cover_updated": "Albumcover opdateret",
|
||||
"album_delete_confirmation": "Er du sikker på at du vil slette albummet {album}?",
|
||||
"album_delete_confirmation_description": "Hvis dette album er delt, vil andre brugere ikke længere kunne få adgang til det.",
|
||||
"album_info_card_backup_album_excluded": "EKSKLUDERET",
|
||||
"album_info_card_backup_album_included": "INKLUDERET",
|
||||
"album_info_updated": "Albuminfo opdateret",
|
||||
"album_leave": "Forlad albummet?",
|
||||
"album_leave_confirmation": "Er du sikker på at du vil forlade {album}?",
|
||||
@@ -379,10 +397,22 @@
|
||||
"album_remove_user": "Fjern bruger?",
|
||||
"album_remove_user_confirmation": "Er du sikker på at du vil fjerne {user}?",
|
||||
"album_share_no_users": "Det ser ud til at du har delt denne album med alle brugere, eller du har ikke nogen brugere til at dele med.",
|
||||
"album_thumbnail_card_item": "1 genstand",
|
||||
"album_thumbnail_card_items": "{} genstande",
|
||||
"album_thumbnail_card_shared": ". Delt",
|
||||
"album_thumbnail_shared_by": "Delt af {}",
|
||||
"album_updated": "Album opdateret",
|
||||
"album_updated_setting_description": "Modtag en emailnotifikation når et delt album får nye mediefiler",
|
||||
"album_user_left": "Forlod {album}",
|
||||
"album_user_removed": "Fjernede {user}",
|
||||
"album_viewer_appbar_delete_confirm": "Er du sikker på, du vil slette dette album fra din bruger?",
|
||||
"album_viewer_appbar_share_err_delete": "Fejlede sletning af album",
|
||||
"album_viewer_appbar_share_err_leave": "Fejlede i at forlade album",
|
||||
"album_viewer_appbar_share_err_remove": "Der er problemer med at fjerne elementer fra album",
|
||||
"album_viewer_appbar_share_err_title": "Fejlede i at ændre albumtitel",
|
||||
"album_viewer_appbar_share_leave": "Forlad album",
|
||||
"album_viewer_appbar_share_to": "Del til",
|
||||
"album_viewer_page_share_add_users": "Tilføj brugere",
|
||||
"album_with_link_access": "Lad alle med linket se billeder og personer i dette album.",
|
||||
"albums": "Albummer",
|
||||
"albums_count": "{count, plural, one {{count, number} Album} other {{count, number} Albummer}}",
|
||||
@@ -400,42 +430,133 @@
|
||||
"api_key_description": "Denne værdi vises kun én gang. Venligst kopiér den før du lukker vinduet.",
|
||||
"api_key_empty": "Din API-nøgle-navn burde ikke være tom",
|
||||
"api_keys": "API-nøgler",
|
||||
"app_bar_signout_dialog_content": "Er du sikker på, du vil logge ud?",
|
||||
"app_bar_signout_dialog_ok": "Ja",
|
||||
"app_bar_signout_dialog_title": "Log ud",
|
||||
"app_settings": "Appindstillinger",
|
||||
"appears_in": "Optræder i",
|
||||
"archive": "Arkiv",
|
||||
"archive_or_unarchive_photo": "Arkivér eller dearkivér billede",
|
||||
"archive_page_no_archived_assets": "Ingen arkiverede elementer blev fundet",
|
||||
"archive_page_title": "Arkivér ({})",
|
||||
"archive_size": "Arkiv størelse",
|
||||
"archive_size_description": "Konfigurer arkivstørrelsen for downloads (i GiB)",
|
||||
"archived": "Arkiveret",
|
||||
"archived_count": "{count, plural, other {Arkiveret #}}",
|
||||
"are_these_the_same_person": "Er disse den samme person?",
|
||||
"are_you_sure_to_do_this": "Er du sikker på, at du vil gøre det her?",
|
||||
"asset_action_delete_err_read_only": "Kan ikke slette kun læselige elementer. Springer over",
|
||||
"asset_action_share_err_offline": "Kan ikke hente offline element(er). Springer over",
|
||||
"asset_added_to_album": "Tilføjet til album",
|
||||
"asset_adding_to_album": "Tilføjer til album…",
|
||||
"asset_description_updated": "Mediefilsbeskrivelse er blevet opdateret",
|
||||
"asset_filename_is_offline": "Mediefil {filename} er offline",
|
||||
"asset_has_unassigned_faces": "Aktivet har ikke-tildelte ansigter",
|
||||
"asset_hashing": "Hashing…",
|
||||
"asset_list_group_by_sub_title": "Gruppér efter",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamisk layout",
|
||||
"asset_list_layout_settings_group_automatically": "Automatisk",
|
||||
"asset_list_layout_settings_group_by": "Gruppér elementer pr. ",
|
||||
"asset_list_layout_settings_group_by_month_day": "Måned + dag",
|
||||
"asset_list_layout_sub_title": "Layout",
|
||||
"asset_list_settings_subtitle": "Indstillinger for billedgitterlayout",
|
||||
"asset_list_settings_title": "Billedgitter",
|
||||
"asset_offline": "Mediefil offline",
|
||||
"asset_offline_description": "Denne eksterne mediefil kan ikke længere findes på drevet. Kontakt venligst din Immich-administrator for hjælp.",
|
||||
"asset_restored_successfully": "Elementet blev gendannet succesfuldt",
|
||||
"asset_skipped": "Sprunget over",
|
||||
"asset_skipped_in_trash": "I skraldespand",
|
||||
"asset_uploaded": "Uploadet",
|
||||
"asset_uploading": "Uploader…",
|
||||
"asset_viewer_settings_subtitle": "Administrer indstillinger for gallerifremviser",
|
||||
"asset_viewer_settings_title": "Billedviser",
|
||||
"assets": "elementer",
|
||||
"assets_added_count": "Tilføjet {count, plural, one {# mediefil} other {# mediefiler}}",
|
||||
"assets_added_to_album_count": "{count, plural, one {# mediefil} other {# mediefiler}} tilføjet til albummet",
|
||||
"assets_added_to_name_count": "Tilføjet {count, plural, one {# mediefil} other {# mediefiler}} til {hasName, select, true {<b>{name}</b>} other {nyt album}}",
|
||||
"assets_count": "{count, plural, one {# mediefil} other {# mediefiler}}",
|
||||
"assets_deleted_permanently": "{} element(er) blev fjernet permanent",
|
||||
"assets_deleted_permanently_from_server": "{} element(er) blev fjernet permanent fra serveren",
|
||||
"assets_moved_to_trash_count": "Flyttede {count, plural, one {# mediefil} other {# mediefiler}} til papirkurven",
|
||||
"assets_permanently_deleted_count": "{count, plural, one {# mediefil} other {# mediefiler}} slettet permanent",
|
||||
"assets_removed_count": "Fjernede {count, plural, one {# mediefil} other {# mediefiler}}",
|
||||
"assets_removed_permanently_from_device": "{} element(er) blev fjernet permanent fra din enhed",
|
||||
"assets_restore_confirmation": "Er du sikker på, at du vil gendanne alle dine mediafiler i papirkurven? Du kan ikke fortryde denne handling! Bemærk, at offline mediefiler ikke kan gendannes på denne måde.",
|
||||
"assets_restored_count": "{count, plural, one {# mediefil} other {# mediefiler}} gendannet",
|
||||
"assets_restored_successfully": "{} element(er) blev gendannet succesfuldt",
|
||||
"assets_trashed": "{} element(er) blev smidt i papirkurven",
|
||||
"assets_trashed_count": "{count, plural, one {# mediefil} other {# mediefiler}} smidt i papirkurven",
|
||||
"assets_trashed_from_server": "{} element(er) blev smidt i serverens papirkurv",
|
||||
"assets_were_part_of_album_count": "mediefil{count, plural, one {mediefil} other {mediefiler}} er allerede en del af albummet",
|
||||
"authorized_devices": "Tilladte enheder",
|
||||
"automatic_endpoint_switching_subtitle": "Forbind lokalt over det anviste WiFi, når det er tilgængeligt og brug alternative forbindelser andre stæder",
|
||||
"automatic_endpoint_switching_title": "Automatisk skift af URL",
|
||||
"back": "Tilbage",
|
||||
"back_close_deselect": "Tilbage, luk eller fravælg",
|
||||
"background_location_permission": "Tilladelse til baggrundsplacering",
|
||||
"background_location_permission_content": "For at skifte netværk, når appen kører i baggrunden, skal Immich *altid* have præcis placeringsadgang, så appen kan læse WiFi-netværkets navn",
|
||||
"backup_album_selection_page_albums_device": "Albummer på enhed ({})",
|
||||
"backup_album_selection_page_albums_tap": "Tryk en gang for at inkludere, tryk to gange for at ekskludere",
|
||||
"backup_album_selection_page_assets_scatter": "Elementer kan være spredt på tværs af flere albummer. Albummer kan således inkluderes eller udelukkes under sikkerhedskopieringsprocessen.",
|
||||
"backup_album_selection_page_select_albums": "Vælg albummer",
|
||||
"backup_album_selection_page_selection_info": "Oplysninger om valgte",
|
||||
"backup_album_selection_page_total_assets": "Samlede unikke elementer",
|
||||
"backup_all": "Alt",
|
||||
"backup_background_service_backup_failed_message": "Sikkerhedskopiering af elementer fejlede. Forsøger igen...",
|
||||
"backup_background_service_connection_failed_message": "Forbindelsen til serveren blev tabt. Forsøger igen...",
|
||||
"backup_background_service_current_upload_notification": "Uploader {}",
|
||||
"backup_background_service_default_notification": "Søger efter nye elementer...",
|
||||
"backup_background_service_error_title": "Fejl med sikkerhedskopiering",
|
||||
"backup_background_service_in_progress_notification": "Tager sikkerhedskopi af dine elementer...",
|
||||
"backup_background_service_upload_failure_notification": "Fejlede med uploade af {}",
|
||||
"backup_controller_page_albums": "Sikkerhedskopiér albummer",
|
||||
"backup_controller_page_background_app_refresh_disabled_content": "Slå baggrundsopdatering af applikationen til i Indstillinger > Generelt > Baggrundsopdatering af applikationer, for at bruge sikkerhedskopi i baggrunden.",
|
||||
"backup_controller_page_background_app_refresh_disabled_title": "Baggrundsopdatering af app er slået fra",
|
||||
"backup_controller_page_background_app_refresh_enable_button_text": "Gå til indstillinger",
|
||||
"backup_controller_page_background_battery_info_link": "Vis mig hvordan",
|
||||
"backup_controller_page_background_battery_info_message": "For den bedste oplevelse med sikkerhedskopiering i baggrunden, bør du slå batterioptimering, der begrænder baggrundsaktivitet, fra.\n\nSiden dette er afhængigt af enheden, bør du undersøge denne information leveret af din enheds producent.",
|
||||
"backup_controller_page_background_battery_info_ok": "OK",
|
||||
"backup_controller_page_background_battery_info_title": "Batterioptimering",
|
||||
"backup_controller_page_background_charging": "Kun under opladning",
|
||||
"backup_controller_page_background_configure_error": "Fejlede konfigureringen af sikkerhedskopiering i baggrunden",
|
||||
"backup_controller_page_background_delay": "Udskyd sikkerhedskopi af nye elementer: {}",
|
||||
"backup_controller_page_background_description": "Slå sikkerhedskopiering i baggrunden til, for automatisk at tage sikkerhedskopi af nye elementer, uden at skulle åbne appen",
|
||||
"backup_controller_page_background_is_off": "Automatisk sikkerhedskopiering i baggrunden er slået fra",
|
||||
"backup_controller_page_background_is_on": "Automatisk sikkerhedskopiering i baggrunden er slået til",
|
||||
"backup_controller_page_background_turn_off": "Slå sikkerhedskopiering i baggrunden fra",
|
||||
"backup_controller_page_background_turn_on": "Slå sikkerhedskopiering i baggrunden til",
|
||||
"backup_controller_page_background_wifi": "Kun med WiFi",
|
||||
"backup_controller_page_backup": "Sikkerhedskopier",
|
||||
"backup_controller_page_backup_selected": "Valgte: ",
|
||||
"backup_controller_page_backup_sub": "Sikkerhedskopierede billeder og videoer",
|
||||
"backup_controller_page_created": "Oprettet den: {}",
|
||||
"backup_controller_page_desc_backup": "Slå sikkerhedskopiering til automatisk at uploade nye elementer til serveren.",
|
||||
"backup_controller_page_excluded": "Ekskluderet: ",
|
||||
"backup_controller_page_failed": "Felet ({})",
|
||||
"backup_controller_page_filename": "Filnavn: {} [{}]",
|
||||
"backup_controller_page_id": "ID: {}",
|
||||
"backup_controller_page_info": "Sikkerhedskopieringsinformation",
|
||||
"backup_controller_page_none_selected": "Ingen valgte",
|
||||
"backup_controller_page_remainder": "Tilbageværende",
|
||||
"backup_controller_page_remainder_sub": "Tilbageværende billeder og albummer, at sikkerhedskopiere, fra valgte",
|
||||
"backup_controller_page_server_storage": "Serverlager",
|
||||
"backup_controller_page_start_backup": "Start sikkerhedskopiering",
|
||||
"backup_controller_page_status_off": "Sikkerhedskopiering er slået fra",
|
||||
"backup_controller_page_status_on": "Sikkerhedskopiering er slået til",
|
||||
"backup_controller_page_storage_format": "{} af {} brugt",
|
||||
"backup_controller_page_to_backup": "Albummer at sikkerhedskopiere",
|
||||
"backup_controller_page_total_sub": "Alle unikke billeder og videoer fra valgte albummer",
|
||||
"backup_controller_page_turn_off": "Slå sikkerhedskopiering fra",
|
||||
"backup_controller_page_turn_on": "Slå sikkerhedskopiering til",
|
||||
"backup_controller_page_uploading_file_info": "Uploader filinformation",
|
||||
"backup_err_only_album": "Kan ikke slette det eneste album",
|
||||
"backup_info_card_assets": "elementer",
|
||||
"backup_manual_cancelled": "Annulleret",
|
||||
"backup_manual_in_progress": "Upload er allerede undervejs. Prøv igen efter noget tid",
|
||||
"backup_manual_success": "Succes",
|
||||
"backup_manual_title": "Uploadstatus",
|
||||
"backup_options_page_title": "Backupindstillinger",
|
||||
"backup_setting_subtitle": "Administrer indstillnger for upload i forgrund og baggrund",
|
||||
"backward": "Baglæns",
|
||||
"birthdate_saved": "Fødselsdatoen blev gemt",
|
||||
"birthdate_set_description": "Fødselsdato bruges til at beregne alderen på denne person på tidspunktet for et billede.",
|
||||
@@ -447,24 +568,52 @@
|
||||
"bulk_keep_duplicates_confirmation": "Er du sikker på, at du vil beholde {count, plural, one {# duplicate asset} other {# duplicate assets}}? Dette vil løse alle dubletgrupper uden at slette noget.",
|
||||
"bulk_trash_duplicates_confirmation": "Er du sikker på, at du vil masseslette {count, plural, one {# duplikeret objekt} other {# duplikerede objekter}}? Dette vil beholde det største objekt i hver gruppe og slette alle andre dubletter.",
|
||||
"buy": "Køb Immich",
|
||||
"cache_settings_album_thumbnails": "Biblioteksminiaturebilleder ({} elementer)",
|
||||
"cache_settings_clear_cache_button": "Fjern cache",
|
||||
"cache_settings_clear_cache_button_title": "Fjern appens cache. Dette vil i stor grad påvirke appens ydeevne indtil cachen er genopbygget.",
|
||||
"cache_settings_duplicated_assets_clear_button": "RYD",
|
||||
"cache_settings_duplicated_assets_subtitle": "Billeder og videoer der er sortlistet af appen",
|
||||
"cache_settings_duplicated_assets_title": "Dublikerede elementer ({})",
|
||||
"cache_settings_image_cache_size": "Størrelse af billedecache ({} elementer)",
|
||||
"cache_settings_statistics_album": "Biblioteksminiaturer",
|
||||
"cache_settings_statistics_assets": "{} elementer ({})",
|
||||
"cache_settings_statistics_full": "Fulde billeder",
|
||||
"cache_settings_statistics_shared": "Miniaturebilleder til delte albummer",
|
||||
"cache_settings_statistics_thumbnail": "Miniaturebilleder",
|
||||
"cache_settings_statistics_title": "Cacheforbrug",
|
||||
"cache_settings_subtitle": "Håndter cache-adfærden for Immich-appen.",
|
||||
"cache_settings_thumbnail_size": "Størrelse af miniaturebillede cache ({} elementer)",
|
||||
"cache_settings_tile_subtitle": "Kontroller den lokale lagerplads",
|
||||
"cache_settings_tile_title": "Lokal lagerplads",
|
||||
"cache_settings_title": "Cache-indstillinger",
|
||||
"camera": "Kamera",
|
||||
"camera_brand": "Kameramærke",
|
||||
"camera_model": "Kameramodel",
|
||||
"cancel": "Annullér",
|
||||
"cancel_search": "Annullér søgning",
|
||||
"canceled": "Canceled",
|
||||
"cannot_merge_people": "Kan ikke sammenflette personer",
|
||||
"cannot_undo_this_action": "Du kan ikke fortryde denne handling!",
|
||||
"cannot_update_the_description": "Kan ikke opdatere beskrivelsen",
|
||||
"change_date": "Ændr dato",
|
||||
"change_display_order": "Ændrer visningsrækkefølge",
|
||||
"change_expiration_time": "Ændr udløbstidspunkt",
|
||||
"change_location": "Ændr sted",
|
||||
"change_name": "Ændr navn",
|
||||
"change_name_successfully": "Navn er ændret",
|
||||
"change_password": "Skift kodeord",
|
||||
"change_password_description": "Dette er enten første gang du tilmelder dig, eller en ændring af kodeordet blev bestilt. Indtast dit nye kodeord herunder.",
|
||||
"change_password_form_confirm_password": "Bekræft kodeord",
|
||||
"change_password_form_description": "Hej {name},\n\nDette er enten første gang du logger ind eller også er der lavet en anmodning om at ændre dit kodeord. Indtast venligst et nyt kodeord nedenfor.",
|
||||
"change_password_form_new_password": "Nyt kodeord",
|
||||
"change_password_form_password_mismatch": "Kodeord er ikke ens",
|
||||
"change_password_form_reenter_new_password": "Gentag nyt kodeord",
|
||||
"change_your_password": "Skift dit kodeord",
|
||||
"changed_visibility_successfully": "Synlighed blev ændret",
|
||||
"check_all": "Markér alle",
|
||||
"check_corrupt_asset_backup": "Tjek for korrupte sikkerhedskopier af elementer",
|
||||
"check_corrupt_asset_backup_button": "Foretag kontrol",
|
||||
"check_corrupt_asset_backup_description": "Kør kun denne kontrol via Wi-Fi, og når alle elementer er blevet sikkerhedskopieret. Proceduren kan tage et par minutter.",
|
||||
"check_logs": "Tjek logfiler",
|
||||
"choose_matching_people_to_merge": "Vælg matchende personer til sammenfletning",
|
||||
"city": "By",
|
||||
@@ -473,6 +622,14 @@
|
||||
"clear_all_recent_searches": "Ryd alle seneste søgninger",
|
||||
"clear_message": "Ryd bedsked",
|
||||
"clear_value": "Ryd værdi",
|
||||
"client_cert_dialog_msg_confirm": "OK",
|
||||
"client_cert_enter_password": "Enter Password",
|
||||
"client_cert_import": "Import",
|
||||
"client_cert_import_success_msg": "Client certificate is imported",
|
||||
"client_cert_invalid_msg": "Invalid certificate file or wrong password",
|
||||
"client_cert_remove_msg": "Client certificate is removed",
|
||||
"client_cert_subtitle": "Supports PKCS12 (.p12, .pfx) format only. Certificate Import/Remove is available only before login",
|
||||
"client_cert_title": "SSL Client Certificate",
|
||||
"clockwise": "Med uret",
|
||||
"close": "Luk",
|
||||
"collapse": "Klap sammen",
|
||||
@@ -483,6 +640,9 @@
|
||||
"comment_options": "Kommentarindstillinger",
|
||||
"comments_and_likes": "Kommentarer og likes",
|
||||
"comments_are_disabled": "Kommentarer er slået fra",
|
||||
"common_create_new_album": "Opret et nyt album",
|
||||
"common_server_error": "Tjek din internetforbindelse, sørg for at serveren er tilgængelig og at app- og serversioner er kompatible.",
|
||||
"completed": "Completed",
|
||||
"confirm": "Bekræft",
|
||||
"confirm_admin_password": "Bekræft administratoradgangskode",
|
||||
"confirm_delete_face": "Er du sikker på, du vil slette {name}s ansigt fra denne mediefil?",
|
||||
@@ -492,6 +652,15 @@
|
||||
"contain": "Inddæm",
|
||||
"context": "Kontekst",
|
||||
"continue": "Fortsæt",
|
||||
"control_bottom_app_bar_album_info_shared": "{} genstande • Delt",
|
||||
"control_bottom_app_bar_create_new_album": "Opret nyt album",
|
||||
"control_bottom_app_bar_delete_from_immich": "Slet fra Immich",
|
||||
"control_bottom_app_bar_delete_from_local": "Slet fra enhed",
|
||||
"control_bottom_app_bar_edit_location": "Rediger placering",
|
||||
"control_bottom_app_bar_edit_time": "Rediger tid og dato",
|
||||
"control_bottom_app_bar_share_link": "Share Link",
|
||||
"control_bottom_app_bar_share_to": "Del til",
|
||||
"control_bottom_app_bar_trash_from_immich": "Flyt til papirkurv",
|
||||
"copied_image_to_clipboard": "Kopierede billede til clipboard.",
|
||||
"copied_to_clipboard": "Kopieret til udklipsholder!",
|
||||
"copy_error": "Kopifejl",
|
||||
@@ -506,24 +675,34 @@
|
||||
"covers": "Omslag",
|
||||
"create": "Opret",
|
||||
"create_album": "Opret album",
|
||||
"create_album_page_untitled": "Uden titel",
|
||||
"create_library": "Opret bibliotek",
|
||||
"create_link": "Opret link",
|
||||
"create_link_to_share": "Opret link for at dele",
|
||||
"create_link_to_share_description": "Tillad alle med linket at se de(t) valgte billede(r)",
|
||||
"create_new": "OPRET NY",
|
||||
"create_new_person": "Opret ny person",
|
||||
"create_new_person_hint": "Tildel valgte aktiver til en ny person",
|
||||
"create_new_user": "Opret ny bruger",
|
||||
"create_shared_album_page_share_add_assets": "TILFØJ ELEMENT",
|
||||
"create_shared_album_page_share_select_photos": "Vælg billeder",
|
||||
"create_tag": "Opret tag",
|
||||
"create_tag_description": "Opret et nyt tag. For indlejrede tags skal du indtaste den fulde sti til tagget inklusive skråstreger.",
|
||||
"create_user": "Opret bruger",
|
||||
"created": "Oprettet",
|
||||
"crop": "Beskær",
|
||||
"curated_object_page_title": "Ting",
|
||||
"current_device": "Nuværende enhed",
|
||||
"current_server_address": "Nuværende serveraddresse",
|
||||
"custom_locale": "Brugerdefineret lokale",
|
||||
"custom_locale_description": "Formatér datoer og tal baseret på sproget og regionen",
|
||||
"daily_title_text_date": "E, dd MMM",
|
||||
"daily_title_text_date_year": "E, dd MMM, yyyy",
|
||||
"dark": "Mørk",
|
||||
"date_after": "Dato efter",
|
||||
"date_and_time": "Dato og klokkeslæt",
|
||||
"date_before": "Dato før",
|
||||
"date_format": "E d. LLL y • hh:mm",
|
||||
"date_of_birth_saved": "Fødselsdatoen blev gemt korrekt",
|
||||
"date_range": "Datointerval",
|
||||
"day": "Dag",
|
||||
@@ -537,19 +716,30 @@
|
||||
"delete": "Slet",
|
||||
"delete_album": "Slet album",
|
||||
"delete_api_key_prompt": "Er du sikker på, at du vil slette denne API-nøgle?",
|
||||
"delete_dialog_alert": "Disse elementer vil blive slettet permanent fra Immich og din enhed",
|
||||
"delete_dialog_alert_local": "Disse elementer slettes permanent fra din enhed, men vil stadig være tilgængelige på serveren",
|
||||
"delete_dialog_alert_local_non_backed_up": "Nogle af elementerne har ingen backup på serveren og vil blive slettet permanent fra din enhed",
|
||||
"delete_dialog_alert_remote": "Disse elementer slettes permanent fra serveren",
|
||||
"delete_dialog_ok_force": "Slet alligevel",
|
||||
"delete_dialog_title": "Slet permanent",
|
||||
"delete_duplicates_confirmation": "Er du sikker på, at du vil slette disse dubletter permanent?",
|
||||
"delete_face": "Slet ansigt",
|
||||
"delete_key": "Slet nøgle",
|
||||
"delete_library": "Slet bibliotek",
|
||||
"delete_link": "Slet link",
|
||||
"delete_local_dialog_ok_backed_up_only": "Slet kun backup",
|
||||
"delete_local_dialog_ok_force": "Slet alligevel",
|
||||
"delete_others": "Slet andre",
|
||||
"delete_shared_link": "Slet delt link",
|
||||
"delete_shared_link_dialog_title": "Slet delt link",
|
||||
"delete_tag": "Slet tag",
|
||||
"delete_tag_confirmation_prompt": "Er du sikker på, at du vil slette {tagName}-tagget?",
|
||||
"delete_user": "Slet bruger",
|
||||
"deleted_shared_link": "Slettede delt link",
|
||||
"deletes_missing_assets": "Sletter aktiver, der mangler fra disken",
|
||||
"description": "Beskrivelse",
|
||||
"description_input_hint_text": "Tilføj en beskrivelse...",
|
||||
"description_input_submit_error": "Fejl med at opdatere beskrivelsen. Tjek loggen for flere detaljer",
|
||||
"details": "DETALJER",
|
||||
"direction": "Retning",
|
||||
"disabled": "Deaktiveret",
|
||||
@@ -566,12 +756,26 @@
|
||||
"documentation": "Dokumentation",
|
||||
"done": "Færdig",
|
||||
"download": "Hent",
|
||||
"download_canceled": "Download annulleret",
|
||||
"download_complete": "Download fuldført",
|
||||
"download_enqueue": "Donload sat i kø",
|
||||
"download_error": "Fejl med download",
|
||||
"download_failed": "Download mislykkes",
|
||||
"download_filename": "fil: {}",
|
||||
"download_finished": "Download afsluttet",
|
||||
"download_include_embedded_motion_videos": "Indlejrede videoer",
|
||||
"download_include_embedded_motion_videos_description": "Inkluder videoer indlejret i levende billeder som en separat fil",
|
||||
"download_notfound": "Download ikke fundet",
|
||||
"download_paused": "Download pauset",
|
||||
"download_settings": "Download",
|
||||
"download_settings_description": "Administrer indstillinger relateret til mediefil-downloads",
|
||||
"download_started": "Download startet",
|
||||
"download_sucess": "Download færdig",
|
||||
"download_sucess_android": "Mediet er blevet downloadet til DCIM/Immich",
|
||||
"download_waiting_to_retry": "Afventer at prøve igen",
|
||||
"downloading": "Downloader",
|
||||
"downloading_asset_filename": "Downloader mediefil {filename}",
|
||||
"downloading_media": "Download medier",
|
||||
"drop_files_to_upload": "Slip filer hvor som helst for at uploade dem",
|
||||
"duplicates": "Duplikater",
|
||||
"duplicates_description": "Løs hver gruppe ved at angive, hvilke, hvis nogen, er dubletter",
|
||||
@@ -588,6 +792,7 @@
|
||||
"edit_key": "Redigér nøgle",
|
||||
"edit_link": "Rediger link",
|
||||
"edit_location": "Rediger placering",
|
||||
"edit_location_dialog_title": "Placering",
|
||||
"edit_name": "Rediger navn",
|
||||
"edit_people": "Redigér personer",
|
||||
"edit_tag": "Rediger tag",
|
||||
@@ -600,14 +805,19 @@
|
||||
"editor_crop_tool_h2_aspect_ratios": "Størrelsesforhold",
|
||||
"editor_crop_tool_h2_rotation": "Rotation",
|
||||
"email": "E-mail",
|
||||
"empty_folder": "This folder is empty",
|
||||
"empty_trash": "Tøm papirkurv",
|
||||
"empty_trash_confirmation": "Er du sikker på, at du vil tømme papirkurven? Dette vil fjerne alle objekter i papirkurven permanent fra Immich.\nDu kan ikke fortryde denne handling!",
|
||||
"enable": "Aktivér",
|
||||
"enabled": "Aktiveret",
|
||||
"end_date": "Slutdato",
|
||||
"enqueued": "Enqueued",
|
||||
"enter_wifi_name": "Indtast WiFi-navn",
|
||||
"error": "Fejl",
|
||||
"error_change_sort_album": "Ændring af sorteringsrækkefølgen mislykkedes",
|
||||
"error_delete_face": "Fejl ved sletning af ansigt fra mediefil",
|
||||
"error_loading_image": "Fejl ved indlæsning af billede",
|
||||
"error_saving_image": "Fejl: {}",
|
||||
"error_title": "Fejl - Noget gik galt",
|
||||
"errors": {
|
||||
"cannot_navigate_next_asset": "Kan ikke navigere til næste mediefil",
|
||||
@@ -736,8 +946,21 @@
|
||||
"unable_to_upload_file": "Filen kunne ikke uploades"
|
||||
},
|
||||
"exif": "Exif",
|
||||
"exif_bottom_sheet_description": "Tilføj beskrivelse...",
|
||||
"exif_bottom_sheet_details": "DETALJER",
|
||||
"exif_bottom_sheet_location": "LOKATION",
|
||||
"exif_bottom_sheet_people": "PERSONER",
|
||||
"exif_bottom_sheet_person_add_person": "Tilføj navn",
|
||||
"exif_bottom_sheet_person_age": "Age {}",
|
||||
"exif_bottom_sheet_person_age_months": "Age {} months",
|
||||
"exif_bottom_sheet_person_age_year_months": "Age 1 year, {} months",
|
||||
"exif_bottom_sheet_person_age_years": "Age {}",
|
||||
"exit_slideshow": "Afslut slideshow",
|
||||
"expand_all": "Udvid alle",
|
||||
"experimental_settings_new_asset_list_subtitle": "Under udarbejdelse",
|
||||
"experimental_settings_new_asset_list_title": "Aktiver eksperimentelt fotogitter",
|
||||
"experimental_settings_subtitle": "Brug på eget ansvar!",
|
||||
"experimental_settings_title": "Eksperimentelle",
|
||||
"expire_after": "Udløb efter",
|
||||
"expired": "Udløbet",
|
||||
"expires_date": "Udløber {date}",
|
||||
@@ -748,11 +971,16 @@
|
||||
"extension": "Udvidelse",
|
||||
"external": "Ekstern",
|
||||
"external_libraries": "Eksterne biblioteker",
|
||||
"external_network": "Eksternt netværk",
|
||||
"external_network_sheet_info": "Nå der er ikke er forbundet til det foretrukne WiFi-netværk, vil appen forbinde til den første URL, den kan forbinde til, på listen nedenfor. Startende med i toppen",
|
||||
"face_unassigned": "Ikke tildelt",
|
||||
"failed": "Failed",
|
||||
"failed_to_load_assets": "Kunne ikke indlæse mediefiler",
|
||||
"failed_to_load_folder": "Failed to load folder",
|
||||
"favorite": "Favorit",
|
||||
"favorite_or_unfavorite_photo": "Tilføj eller fjern fra yndlingsbilleder",
|
||||
"favorites": "Favoritter",
|
||||
"favorites_page_no_favorites": "Ingen favoritter blev fundet",
|
||||
"feature_photo_updated": "Forsidebillede uploadet",
|
||||
"features": "Funktioner",
|
||||
"features_setting_description": "Administrer app-funktioner",
|
||||
@@ -760,25 +988,38 @@
|
||||
"file_name_or_extension": "Filnavn eller filtype",
|
||||
"filename": "Filnavn",
|
||||
"filetype": "Filtype",
|
||||
"filter": "Filter",
|
||||
"filter_people": "Filtrér personer",
|
||||
"find_them_fast": "Find dem hurtigt med søgning via navn",
|
||||
"fix_incorrect_match": "Fix forkert match",
|
||||
"folder": "Folder",
|
||||
"folder_not_found": "Folder not found",
|
||||
"folders": "Mapper",
|
||||
"folders_feature_description": "Gennemse mappevisningen efter fotos og videoer på filsystemet",
|
||||
"forward": "Fremad",
|
||||
"general": "Generel",
|
||||
"get_help": "Få hjælp",
|
||||
"get_wifiname_error": "Kunne ikke hente Wi-Fi-navn. Sørg for, at du har givet de nødvendige tilladelser og er forbundet til et Wi-Fi-netværk",
|
||||
"getting_started": "Kom godt i gang",
|
||||
"go_back": "Gå tilbage",
|
||||
"go_to_folder": "Gå til mappe",
|
||||
"go_to_search": "Gå til søgning",
|
||||
"grant_permission": "Giv tilladelse",
|
||||
"group_albums_by": "Gruppér albummer efter...",
|
||||
"group_country": "Gruppér efter land",
|
||||
"group_no": "Ingen gruppering",
|
||||
"group_owner": "Grupper efter ejer",
|
||||
"group_places_by": "Gruppér steder efter...",
|
||||
"group_year": "Grupper efter år",
|
||||
"haptic_feedback_switch": "Slå haptisk feedback til",
|
||||
"haptic_feedback_title": "Haptisk feedback",
|
||||
"has_quota": "Har kvote",
|
||||
"header_settings_add_header_tip": "Add Header",
|
||||
"header_settings_field_validator_msg": "Value cannot be empty",
|
||||
"header_settings_header_name_input": "Header name",
|
||||
"header_settings_header_value_input": "Header value",
|
||||
"headers_settings_tile_subtitle": "Define proxy headers the app should send with each network request",
|
||||
"headers_settings_tile_title": "Custom proxy headers",
|
||||
"hi_user": "Hej {name} ({email})",
|
||||
"hide_all_people": "Skjul alle personer",
|
||||
"hide_gallery": "Skjul galleri",
|
||||
@@ -786,8 +1027,24 @@
|
||||
"hide_password": "Skjul adgangskode",
|
||||
"hide_person": "Skjul person",
|
||||
"hide_unnamed_people": "Skjul unavngivne personer",
|
||||
"home_page_add_to_album_conflicts": "Tilføjede {added} elementer til album {album}. {failed} elementer er allerede i albummet.",
|
||||
"home_page_add_to_album_err_local": "Kan endnu ikke tilføje lokale elementer til album. Springer over..",
|
||||
"home_page_add_to_album_success": "Tilføjede {added} elementer til album {album}.",
|
||||
"home_page_album_err_partner": "Kan endnu ikke tilføje partners elementer til album. Springer over",
|
||||
"home_page_archive_err_local": "Kan ikke arkivere lokalt element endnu.. Springer over",
|
||||
"home_page_archive_err_partner": "Kan endnu ikke arkivere partners elementer. Springer over",
|
||||
"home_page_building_timeline": "Bygger tidslinjen",
|
||||
"home_page_delete_err_partner": "Kan endnu ikke slette partners elementer. Springer over",
|
||||
"home_page_delete_remote_err_local": "Lokale elementer i fjernsletningssektion. Springer over",
|
||||
"home_page_favorite_err_local": "Kan endnu ikke gøre lokale elementer til favoritter. Springer over..",
|
||||
"home_page_favorite_err_partner": "Kan endnu ikke tilføje partners elementer som favoritter. Springer over",
|
||||
"home_page_first_time_notice": "Hvis det er din første gang i appen, bedes du vælge en sikkerhedskopi af albummer så tidlinjen kan blive fyldt med billeder og videoer fra albummerne.",
|
||||
"home_page_share_err_local": "Kan ikke dele lokale elementer via link, springer over",
|
||||
"home_page_upload_err_limit": "Det er kun muligt at lave sikkerhedskopi af 30 elementer ad gangen. Springer over",
|
||||
"host": "Host",
|
||||
"hour": "Time",
|
||||
"ignore_icloud_photos": "Ignorer iCloud-billeder",
|
||||
"ignore_icloud_photos_description": "Billeder der er gemt på iCloud vil ikke blive uploadet til Immich-serveren",
|
||||
"image": "Billede",
|
||||
"image_alt_text_date": "{isVideo, select, true {Video} other {Image}} taget den {date}",
|
||||
"image_alt_text_date_1_person": "{isVideo, select, true {Video} other {Image}} taget med {person1} den {date}",
|
||||
@@ -799,6 +1056,10 @@
|
||||
"image_alt_text_date_place_2_people": "{isVideo, select, true {Video} other {Image}} taget i {city}, {country} med {person1} og {person2} den {date}",
|
||||
"image_alt_text_date_place_3_people": "{isVideo, select, true {Video} other {Image}} taget i {city}, {country} med {person1}, {person2}, og {person3} den {date}",
|
||||
"image_alt_text_date_place_4_or_more_people": "{isVideo, select, true {Video} other {Image}} taget i {city}, {country} med {person1}, {person2}, og {additionalCount, number} andre den {date}",
|
||||
"image_saved_successfully": "Billede gemt",
|
||||
"image_viewer_page_state_provider_download_started": "Download startet",
|
||||
"image_viewer_page_state_provider_download_success": "Download succesfuld",
|
||||
"image_viewer_page_state_provider_share_error": "Delingsfejl",
|
||||
"immich_logo": "Immich logo",
|
||||
"immich_web_interface": "Immich webinterface",
|
||||
"import_from_json": "Importér fra JSON",
|
||||
@@ -817,6 +1078,8 @@
|
||||
"night_at_midnight": "Hver nat ved midnat",
|
||||
"night_at_twoam": "Hver nat kl. 2"
|
||||
},
|
||||
"invalid_date": "Invalid date",
|
||||
"invalid_date_format": "Invalid date format",
|
||||
"invite_people": "Inviter personer",
|
||||
"invite_to_album": "Inviter til album",
|
||||
"items_count": "{count, plural, one {# element} other {# elementer}}",
|
||||
@@ -837,6 +1100,12 @@
|
||||
"level": "Niveau",
|
||||
"library": "Bibliotek",
|
||||
"library_options": "Biblioteksindstillinger",
|
||||
"library_page_device_albums": "Albummer på enhed",
|
||||
"library_page_new_album": "Nyt album",
|
||||
"library_page_sort_asset_count": "Antal af elementer\n",
|
||||
"library_page_sort_created": "Senest oprettet",
|
||||
"library_page_sort_last_modified": "Sidst redigeret",
|
||||
"library_page_sort_title": "Albumtitel",
|
||||
"light": "Lys",
|
||||
"like_deleted": "Ligesom slettet",
|
||||
"link_motion_video": "Link bevægelsesvideo",
|
||||
@@ -846,12 +1115,42 @@
|
||||
"list": "Liste",
|
||||
"loading": "Indlæser",
|
||||
"loading_search_results_failed": "Indlæsning af søgeresultater fejlede",
|
||||
"local_network": "Lokalt netværk",
|
||||
"local_network_sheet_info": "Appen vil oprette forbindelse til serveren via denne URL, når du bruger det angivne WiFi-netværk",
|
||||
"location_permission": "Tilladelse til placering",
|
||||
"location_permission_content": "For automatisk at skifte netværk, skal Immich *altid* have præcis placeringsadgang, så appen kan læse WiFi-netværkets navn",
|
||||
"location_picker_choose_on_map": "Vælg på kort",
|
||||
"location_picker_latitude_error": "Indtast en gyldig breddegrad",
|
||||
"location_picker_latitude_hint": "Indtast din breddegrad her",
|
||||
"location_picker_longitude_error": "Indtast en gyldig længdegrad",
|
||||
"location_picker_longitude_hint": "Indtast din længdegrad her",
|
||||
"log_out": "Log ud",
|
||||
"log_out_all_devices": "Log ud af alle enheder",
|
||||
"logged_out_all_devices": "Logget ud af alle enheder",
|
||||
"logged_out_device": "Logget ud af enhed",
|
||||
"login": "Log ind",
|
||||
"login_disabled": "Login er blevet deaktiveret",
|
||||
"login_form_api_exception": "API-undtagelse. Tjek serverens URL og prøv igen. ",
|
||||
"login_form_back_button_text": "Tilbage",
|
||||
"login_form_email_hint": "din-e-mail@e-mail.com",
|
||||
"login_form_endpoint_hint": "http://din-server-ip:port",
|
||||
"login_form_endpoint_url": "Server Endpoint URL",
|
||||
"login_form_err_http": "Angiv venligst http:// eller https://",
|
||||
"login_form_err_invalid_email": "Ugyldig e-mail",
|
||||
"login_form_err_invalid_url": "Ugyldig webadresse",
|
||||
"login_form_err_leading_whitespace": "Mellemrum før",
|
||||
"login_form_err_trailing_whitespace": "Mellemrum efter",
|
||||
"login_form_failed_get_oauth_server_config": "Fejl med at logge på med OAuth. Tjek serveres webadresse",
|
||||
"login_form_failed_get_oauth_server_disable": "OAuth er ikke tilgængelig på denne server",
|
||||
"login_form_failed_login": "Der opstod en vejl ved at logge ind. Tjek server webadressen, e-mailen og kodeordet",
|
||||
"login_form_handshake_exception": "Der opstod en fejl med at oprette forbindelse til serveren. Aktiver selvsignerede certifikater i indstillingerne, hvis du bruger et selv signeret certifikat.",
|
||||
"login_form_password_hint": "kodeord",
|
||||
"login_form_save_login": "Forbliv logget ind",
|
||||
"login_form_server_empty": "Indtast server-URL.",
|
||||
"login_form_server_error": "Kunne ikke forbinde til serveren.",
|
||||
"login_has_been_disabled": "Login er blevet deaktiveret.",
|
||||
"login_password_changed_error": "Der opstod en fejl i opdateringen af dit kodeord",
|
||||
"login_password_changed_success": "Kodeordet blev opdateret",
|
||||
"logout_all_device_confirmation": "Er du sikker på, at du vil logge ud af alle enheder?",
|
||||
"logout_this_device_confirmation": "Er du sikker på, at du vil logge denne enhed ud?",
|
||||
"longitude": "Længde",
|
||||
@@ -868,13 +1167,40 @@
|
||||
"manage_your_devices": "Administrér dine enheder der er logget ind",
|
||||
"manage_your_oauth_connection": "Administrér din OAuth-tilslutning",
|
||||
"map": "Kort",
|
||||
"map_assets_in_bound": "{} billede",
|
||||
"map_assets_in_bounds": "{} billeder",
|
||||
"map_cannot_get_user_location": "Kan ikke finde brugerens placering",
|
||||
"map_location_dialog_yes": "Ja",
|
||||
"map_location_picker_page_use_location": "Brug denne placering",
|
||||
"map_location_service_disabled_content": "Placeringstjenesten skal aktiveres for at vise elementer fra din nuværende placering. Vil du aktivere den nu?",
|
||||
"map_location_service_disabled_title": "Placeringstjenesten er deaktiveret",
|
||||
"map_marker_for_images": "Kortmarkør for billeder taget i {city}, {country}",
|
||||
"map_marker_with_image": "Kortmarkør med billede",
|
||||
"map_no_assets_in_bounds": "Der er ingen billeder i dette område",
|
||||
"map_no_location_permission_content": "Der kræves tilladelse til placeringen for at vise elementer fra din nuværende placering. Vil du give tilladelse?",
|
||||
"map_no_location_permission_title": "Placeringstilladelse blev afvist",
|
||||
"map_settings": "Kortindstillinger",
|
||||
"map_settings_dark_mode": "Mørk tilstand",
|
||||
"map_settings_date_range_option_day": "Sidste 24 timer",
|
||||
"map_settings_date_range_option_days": "Sidste {} dage",
|
||||
"map_settings_date_range_option_year": "Sidste år",
|
||||
"map_settings_date_range_option_years": "Sidste {} år",
|
||||
"map_settings_dialog_title": "Kortindstillinger",
|
||||
"map_settings_include_show_archived": "Inkluder arkiveret",
|
||||
"map_settings_include_show_partners": "Inkluder partnere",
|
||||
"map_settings_only_show_favorites": "Vis kun favoritter",
|
||||
"map_settings_theme_settings": "Korttema",
|
||||
"map_zoom_to_see_photos": "Zoom ud for at vise billeder",
|
||||
"matches": "Parringer",
|
||||
"media_type": "Medietype",
|
||||
"memories": "Minder",
|
||||
"memories_all_caught_up": "Ajour",
|
||||
"memories_check_back_tomorrow": "Kom tilbage i morgen for at se nye minder",
|
||||
"memories_setting_description": "Administrér hvad du ser i dine minder",
|
||||
"memories_start_over": "Start forfra",
|
||||
"memories_swipe_to_close": "Stryg op for at lukke",
|
||||
"memories_year_ago": "A year ago",
|
||||
"memories_years_ago": "{} years ago",
|
||||
"memory": "Minde",
|
||||
"memory_lane_title": "Minder {title}",
|
||||
"menu": "Menu",
|
||||
@@ -889,12 +1215,17 @@
|
||||
"missing": "Mangler",
|
||||
"model": "Model",
|
||||
"month": "Måned",
|
||||
"monthly_title_text_date_format": "MMMM y",
|
||||
"more": "Mere",
|
||||
"moved_to_trash": "Flyttet til skraldespand",
|
||||
"multiselect_grid_edit_date_time_err_read_only": "Kan ikke redigere datoen på kun læselige elementer. Springer over",
|
||||
"multiselect_grid_edit_gps_err_read_only": "Kan ikke redigere lokation af kun læselige elementer. Springer over",
|
||||
"mute_memories": "Dæmp minder",
|
||||
"my_albums": "Mine albummer",
|
||||
"name": "Navn",
|
||||
"name_or_nickname": "Navn eller kælenavn",
|
||||
"networking_settings": "Netværk",
|
||||
"networking_subtitle": "Administrer serverens endepunktindstillinger",
|
||||
"never": "aldrig",
|
||||
"new_album": "Nyt album",
|
||||
"new_api_key": "Ny API-nøgle",
|
||||
@@ -911,6 +1242,7 @@
|
||||
"no_albums_yet": "Det ser ud til, at du ikke har nogen album endnu.",
|
||||
"no_archived_assets_message": "Arkivér billeder og videoer for at gemme dem væk fra din Billede oversigt",
|
||||
"no_assets_message": "KLIK FOR AT UPLOADE DIT FØRSTE BILLEDE",
|
||||
"no_assets_to_show": "Ingen elementer at vise",
|
||||
"no_duplicates_found": "Ingen duplikater fundet.",
|
||||
"no_exif_info_available": "Ingen tilgængelig exif information",
|
||||
"no_explore_results_message": "Upload flere billeder for at udforske din samling.",
|
||||
@@ -922,9 +1254,13 @@
|
||||
"no_results_description": "Prøv et synonym eller et mere generelt søgeord",
|
||||
"no_shared_albums_message": "Opret et album for at dele billeder og videoer med personer i dit netværk",
|
||||
"not_in_any_album": "Ikke i noget album",
|
||||
"not_selected": "Not selected",
|
||||
"note_apply_storage_label_to_previously_uploaded assets": "Bemærk: For at anvende Lagringsmærkat på tidligere uploadede medier, kør",
|
||||
"note_unlimited_quota": "Bemærk: Indsæt 0 for ubegrænset kvote",
|
||||
"notes": "Noter",
|
||||
"notification_permission_dialog_content": "Gå til indstillinger for at slå notifikationer til.",
|
||||
"notification_permission_list_tile_content": "Tillad at bruge notifikationer.",
|
||||
"notification_permission_list_tile_enable_button": "Slå notifikationer til",
|
||||
"notification_permission_list_tile_title": "Notifikationstilladelser",
|
||||
"notification_toggle_setting_description": "Aktivér emailnotifikationer",
|
||||
"notifications": "Notifikationer",
|
||||
"notifications_setting_description": "Administrér notifikationer",
|
||||
@@ -935,6 +1271,7 @@
|
||||
"offline_paths_description": "Disse resultater kan være på grund af manuel sletning af filer, som ikke er en del af et eksternt bibliotek.",
|
||||
"ok": "Ok",
|
||||
"oldest_first": "Ældste først",
|
||||
"on_this_device": "På denne enhed",
|
||||
"onboarding": "Introduktion",
|
||||
"onboarding_privacy_description": "Følgende (valgfrie) funktioner er afhængige af eksterne tjenester, og kan til enhver tid deaktiveres i administrationsindstillingerne.",
|
||||
"onboarding_theme_description": "Vælg et farvetema til din instans. Du kan ændre dette senere i dine indstillinger.",
|
||||
@@ -958,6 +1295,14 @@
|
||||
"partner_can_access": "{partner} kan tilgå",
|
||||
"partner_can_access_assets": "Alle dine billeder og videoer, bortset fra dem i Arkivet og Slettet",
|
||||
"partner_can_access_location": "Stedet, hvor dine billeder blev taget",
|
||||
"partner_list_user_photos": "{user}s billeder",
|
||||
"partner_list_view_all": "Se alle",
|
||||
"partner_page_empty_message": "Dine billeder er endnu ikke delt med en partner.",
|
||||
"partner_page_no_more_users": "Der er ikke flere brugere at tilføje",
|
||||
"partner_page_partner_add_failed": "Kunne ikke tilføje en partner",
|
||||
"partner_page_select_partner": "Vælg partner",
|
||||
"partner_page_shared_to_title": "Delt til",
|
||||
"partner_page_stop_sharing_content": "{} vil ikke længere have adgang til dine billeder.",
|
||||
"partner_sharing": "Partnerdeling",
|
||||
"partners": "Partnere",
|
||||
"password": "Kodeord",
|
||||
@@ -986,6 +1331,14 @@
|
||||
"permanently_delete_assets_prompt": "Er du sikker på, at du permanent vil slette {count, plural, one {dette aktiv?} other {disse <b>#</b> aktiver?}} Dette vil også fjerne {count, plural, one {det fra dets} other {dem fra deres}} album(er).",
|
||||
"permanently_deleted_asset": "Permanent slettet medie",
|
||||
"permanently_deleted_assets_count": "{count, plural, one {# aktiv} other {# aktiver}} permanent slettet",
|
||||
"permission_onboarding_back": "Tilbage",
|
||||
"permission_onboarding_continue_anyway": "Fortsæt alligevel",
|
||||
"permission_onboarding_get_started": "Kom i gang",
|
||||
"permission_onboarding_go_to_settings": "Gå til indstillinger",
|
||||
"permission_onboarding_permission_denied": "Tilladelse afvist. For at bruge Immich, skal der gives tilladelse til at se billeder og videoer i indstillinger.",
|
||||
"permission_onboarding_permission_granted": "Tilladelse givet! Du er nu klar.",
|
||||
"permission_onboarding_permission_limited": "Tilladelse begrænset. For at lade Immich lave sikkerhedskopi og styre hele dit galleri, skal der gives tilladelse til billeder og videoer i indstillinger.",
|
||||
"permission_onboarding_request": "Immich kræver tilliadelse til at se dine billeder og videoer.",
|
||||
"person": "Person",
|
||||
"person_birthdate": "Født den {date}",
|
||||
"person_hidden": "{name}{hidden, select, true { (skjult)} other {}}",
|
||||
@@ -1003,6 +1356,8 @@
|
||||
"play_motion_photo": "Afspil bevægelsesbillede",
|
||||
"play_or_pause_video": "Afspil eller pause video",
|
||||
"port": "Port",
|
||||
"preferences_settings_subtitle": "Administrer app-præferencer",
|
||||
"preferences_settings_title": "Præferencer",
|
||||
"preset": "Forudindstilling",
|
||||
"preview": "Forhåndsvisning",
|
||||
"previous": "Forrige",
|
||||
@@ -1010,6 +1365,13 @@
|
||||
"previous_or_next_photo": "Forrige eller næste billede",
|
||||
"primary": "Primære",
|
||||
"privacy": "Privatliv",
|
||||
"profile_drawer_app_logs": "Log",
|
||||
"profile_drawer_client_out_of_date_major": "Mobilapp er forældet. Opdater venligst til den nyeste større version",
|
||||
"profile_drawer_client_out_of_date_minor": "Mobilapp er forældet. Opdater venligst til den nyeste mindre version",
|
||||
"profile_drawer_client_server_up_to_date": "Klient og server er ajour",
|
||||
"profile_drawer_github": "GitHub",
|
||||
"profile_drawer_server_out_of_date_major": "Server er forældet. Opdater venligst til den nyeste større version",
|
||||
"profile_drawer_server_out_of_date_minor": "Server er forældet. Opdater venligst til den nyeste mindre version",
|
||||
"profile_image_of_user": "Profilbillede af {user}",
|
||||
"profile_picture_set": "Profilbillede indstillet.",
|
||||
"public_album": "Offentligt album",
|
||||
@@ -1059,6 +1421,8 @@
|
||||
"recent": "For nylig",
|
||||
"recent-albums": "Seneste albums",
|
||||
"recent_searches": "Seneste søgninger",
|
||||
"recently_added": "Senest tilføjet",
|
||||
"recently_added_page_title": "Nyligt tilføjet",
|
||||
"refresh": "Opdatér",
|
||||
"refresh_encoded_videos": "Opdater kodede videoer",
|
||||
"refresh_faces": "Opdater ansigter",
|
||||
@@ -1115,10 +1479,12 @@
|
||||
"role_editor": "Redaktør",
|
||||
"role_viewer": "Seer",
|
||||
"save": "Gem",
|
||||
"save_to_gallery": "Gem til galleri",
|
||||
"saved_api_key": "Gemt API-nøgle",
|
||||
"saved_profile": "Gemte profil",
|
||||
"saved_settings": "Gemte indstillinger",
|
||||
"say_something": "Skriv noget",
|
||||
"scaffold_body_error_occurred": "Der opstod en fejl",
|
||||
"scan_all_libraries": "Skan alle biblioteker",
|
||||
"scan_library": "Skan",
|
||||
"scan_settings": "Skanningsindstillinger",
|
||||
@@ -1134,16 +1500,45 @@
|
||||
"search_camera_model": "Søg efter kameramodel...",
|
||||
"search_city": "Søg efter by...",
|
||||
"search_country": "Søg efter land...",
|
||||
"search_filter_apply": "Tilføj filter",
|
||||
"search_filter_camera_title": "Vælg type af kamera",
|
||||
"search_filter_date": "Dato",
|
||||
"search_filter_date_interval": "{start} til { slut}",
|
||||
"search_filter_date_title": "Vælg et datointerval",
|
||||
"search_filter_display_option_not_in_album": "Ikke i album",
|
||||
"search_filter_display_options": "Visningsindstillinger",
|
||||
"search_filter_filename": "Search by file name",
|
||||
"search_filter_location": "Lokation",
|
||||
"search_filter_location_title": "Vælg lokation",
|
||||
"search_filter_media_type": "Medietype",
|
||||
"search_filter_media_type_title": "Vælg medietype",
|
||||
"search_filter_people_title": "Vælg personer",
|
||||
"search_for": "Søg efter",
|
||||
"search_for_existing_person": "Søg efter eksisterende person",
|
||||
"search_no_more_result": "No more results",
|
||||
"search_no_people": "Ingen personer",
|
||||
"search_no_people_named": "Ingen personer med navnet \"{name}\"",
|
||||
"search_no_result": "No results found, try a different search term or combination",
|
||||
"search_options": "Søgemuligheder",
|
||||
"search_page_categories": "Kategorier",
|
||||
"search_page_motion_photos": "Bevægelsesbilleder",
|
||||
"search_page_no_objects": "Ingen elementer er tilgængelige",
|
||||
"search_page_no_places": "Ingen placeringsinformation er tilgængelig",
|
||||
"search_page_screenshots": "Skærmbilleder",
|
||||
"search_page_search_photos_videos": "Søg i dine billeder og videoer",
|
||||
"search_page_selfies": "Selfier",
|
||||
"search_page_things": "Ting",
|
||||
"search_page_view_all_button": "Vis alt",
|
||||
"search_page_your_activity": "Din aktivitet",
|
||||
"search_page_your_map": "Dit kort",
|
||||
"search_people": "Søg i personer",
|
||||
"search_places": "Søg i steder",
|
||||
"search_rating": "Søg efter vurdering...",
|
||||
"search_result_page_new_search_hint": "Ny søgning",
|
||||
"search_settings": "søgeindstillinger",
|
||||
"search_state": "Søg efter lansdel...",
|
||||
"search_suggestion_list_smart_search_hint_1": "Smart søgnining er slået til som standard. For at søge efter metadata brug syntaksen",
|
||||
"search_suggestion_list_smart_search_hint_2": "m:dit-søgeord",
|
||||
"search_tags": "Søg tags...",
|
||||
"search_timezone": "Søg i tidszone...",
|
||||
"search_type": "Søg efter type",
|
||||
@@ -1164,10 +1559,14 @@
|
||||
"select_new_face": "Vælg nyt ansigt",
|
||||
"select_photos": "Vælg billeder",
|
||||
"select_trash_all": "Vælg smid alle ud",
|
||||
"select_user_for_sharing_page_err_album": "Fejlede i at oprette et nyt album",
|
||||
"selected": "Valgt",
|
||||
"selected_count": "{count, plural, one {# valgt} other {# valgte}}",
|
||||
"send_message": "Send besked",
|
||||
"send_welcome_email": "Send velkomstemail",
|
||||
"server_endpoint": "Server endepunkt",
|
||||
"server_info_box_app_version": "Applikationsversion",
|
||||
"server_info_box_server_url": "Server URL",
|
||||
"server_offline": "Server Offline",
|
||||
"server_online": "Server Online",
|
||||
"server_stats": "Serverstatus",
|
||||
@@ -1179,22 +1578,91 @@
|
||||
"set_date_of_birth": "Indstil fødselsdato",
|
||||
"set_profile_picture": "Indstil profilbillede",
|
||||
"set_slideshow_to_fullscreen": "Sæt diasshow til fuldskærmsvisning",
|
||||
"setting_image_viewer_help": "Detaljeret visning indlæser miniaturebilleder først. Herefter indlæses mediumstørrelse forhåndsvisning af billedet (hvis dette er slået til), for til sidst at vise originalen (hvis dette er slået til).",
|
||||
"setting_image_viewer_original_subtitle": "Slå indlæsning af originalbillede i fuld størrelse til (stort!). Deaktiver for at reducere dataforbruget (både på netværket og for enhedscache).",
|
||||
"setting_image_viewer_original_title": "Indlæs originalbillede",
|
||||
"setting_image_viewer_preview_subtitle": "Slå indlæsning af et mediumstørrelse billede til. Slå fra for enten direkte at indlæse originalen eller kun at bruge miniaturebilledet.",
|
||||
"setting_image_viewer_preview_title": "Indlæs forhåndsvisning af billedet",
|
||||
"setting_image_viewer_title": "Images",
|
||||
"setting_languages_apply": "Anvend",
|
||||
"setting_languages_subtitle": "Ændrer app-sprog",
|
||||
"setting_languages_title": "Sprog",
|
||||
"setting_notifications_notify_failures_grace_period": "Giv besked om fejl med sikkerhedskopiering i baggrunden: {}",
|
||||
"setting_notifications_notify_hours": "{} timer",
|
||||
"setting_notifications_notify_immediately": "med det samme",
|
||||
"setting_notifications_notify_minutes": "{} minutter",
|
||||
"setting_notifications_notify_never": "aldrig",
|
||||
"setting_notifications_notify_seconds": "{} sekunder",
|
||||
"setting_notifications_single_progress_subtitle": "Detaljeret uploadstatus pr. element",
|
||||
"setting_notifications_single_progress_title": "Vis detaljeret baggrundsuploadstatus",
|
||||
"setting_notifications_subtitle": "Tilpas dine notifikationspræferencer",
|
||||
"setting_notifications_total_progress_subtitle": "Samlet uploadstatus (færdige/samlet antal elementer)",
|
||||
"setting_notifications_total_progress_title": "Vis samlet baggrundsuploadstatus",
|
||||
"setting_video_viewer_looping_title": "Looping",
|
||||
"setting_video_viewer_original_video_subtitle": "When streaming a video from the server, play the original even when a transcode is available. May lead to buffering. Videos available locally are played in original quality regardless of this setting.",
|
||||
"setting_video_viewer_original_video_title": "Force original video",
|
||||
"settings": "Indstillinger",
|
||||
"settings_require_restart": "Genstart venligst Immich for at anvende denne ændring",
|
||||
"settings_saved": "Indstillinger er gemt",
|
||||
"share": "Del",
|
||||
"share_add_photos": "Tilføj billeder",
|
||||
"share_assets_selected": "{} valgt",
|
||||
"share_dialog_preparing": "Forbereder...",
|
||||
"shared": "Delt",
|
||||
"shared_album_activities_input_disable": "Kommentarer er deaktiveret",
|
||||
"shared_album_activity_remove_content": "Vil du slette denne aktivitet?",
|
||||
"shared_album_activity_remove_title": "Slet aktivitet",
|
||||
"shared_album_section_people_action_error": "Der opstod en fejl i fjernelsen fra albummet",
|
||||
"shared_album_section_people_action_leave": "Fjern brugere fra albummet",
|
||||
"shared_album_section_people_action_remove_user": "Fjern brugere fra albummet",
|
||||
"shared_album_section_people_title": "PERSONER",
|
||||
"shared_by": "Delt af",
|
||||
"shared_by_user": "Delt af {user}",
|
||||
"shared_by_you": "Delt af dig",
|
||||
"shared_from_partner": "Billeder fra {partner}",
|
||||
"shared_intent_upload_button_progress_text": "{} / {} Uploaded",
|
||||
"shared_link_app_bar_title": "Delte links",
|
||||
"shared_link_clipboard_copied_massage": "Kopieret til udklipsholderen",
|
||||
"shared_link_clipboard_text": "Link: {}\nkodeord: {}",
|
||||
"shared_link_create_error": "Der opstod en fejl i oprettelsen af et delt link",
|
||||
"shared_link_edit_description_hint": "Indtast beskrivelse",
|
||||
"shared_link_edit_expire_after_option_day": "1 dag",
|
||||
"shared_link_edit_expire_after_option_days": "{} dage",
|
||||
"shared_link_edit_expire_after_option_hour": "1 time",
|
||||
"shared_link_edit_expire_after_option_hours": "{} timer",
|
||||
"shared_link_edit_expire_after_option_minute": "1 minut",
|
||||
"shared_link_edit_expire_after_option_minutes": "{} minutter",
|
||||
"shared_link_edit_expire_after_option_months": "{} måneder",
|
||||
"shared_link_edit_expire_after_option_year": "{} år",
|
||||
"shared_link_edit_password_hint": "Indtast kodeordet",
|
||||
"shared_link_edit_submit_button": "Opdater link",
|
||||
"shared_link_error_server_url_fetch": "Kan ikke finde server URL",
|
||||
"shared_link_expires_day": "Udløber om {} dag",
|
||||
"shared_link_expires_days": "Udløber om {} dage",
|
||||
"shared_link_expires_hour": "Udløber om {} time",
|
||||
"shared_link_expires_hours": "Udløber om {} timer",
|
||||
"shared_link_expires_minute": "Udløber om {} minut",
|
||||
"shared_link_expires_minutes": "Udløber om {} minutter",
|
||||
"shared_link_expires_never": "Udløber aldrig",
|
||||
"shared_link_expires_second": "Udløber om {} sekund",
|
||||
"shared_link_expires_seconds": "Udløber om {} sekunder",
|
||||
"shared_link_individual_shared": "Individuelt delt",
|
||||
"shared_link_info_chip_metadata": "EXIF",
|
||||
"shared_link_manage_links": "Håndter delte links",
|
||||
"shared_link_options": "Muligheder for delt link",
|
||||
"shared_links": "Delte links",
|
||||
"shared_links_description": "Del billeder og videoer med et link",
|
||||
"shared_photos_and_videos_count": "{assetCount, plural, other {# delte billeder & videoer.}}",
|
||||
"shared_with_me": "Delt med mig",
|
||||
"shared_with_partner": "Delt med {partner}",
|
||||
"sharing": "Delte",
|
||||
"sharing_enter_password": "Indtast venligst adgangskoden for at se denne side.",
|
||||
"sharing_page_album": "Delt albums",
|
||||
"sharing_page_description": "Opret delte albummer for at dele billeder og video med personer på dit netværk.",
|
||||
"sharing_page_empty_list": "TOM LISTE",
|
||||
"sharing_sidebar_description": "Vis et link til deling i sidemenuen",
|
||||
"sharing_silver_appbar_create_shared_album": "Opret delt album",
|
||||
"sharing_silver_appbar_share_partner": "Del med partner",
|
||||
"shift_to_permanent_delete": "tryk på ⇧ for at slette aktiv permanent",
|
||||
"show_album_options": "Vis albumindstillinger",
|
||||
"show_albums": "Vis albummer",
|
||||
@@ -1261,6 +1729,9 @@
|
||||
"support_third_party_description": "Din Immich-installation blev sammensat af en tredjepart. Problemer, du oplever, kan være forårsaget af denne udvikler, så rejs venligst problemer med dem i første omgang ved at bruge nedenstående links.",
|
||||
"swap_merge_direction": "Byt retning for sammenfletning",
|
||||
"sync": "Synkronisér",
|
||||
"sync_albums": "Synkroniser albummer",
|
||||
"sync_albums_manual_subtitle": "Synkroniser alle uploadet billeder og videoer til de valgte backupalbummer",
|
||||
"sync_upload_album_setting_subtitle": "Opret og upload dine billeder og videoer til de valgte albummer i Immich",
|
||||
"tag": "Tag",
|
||||
"tag_assets": "Tag mediefiler",
|
||||
"tag_created": "Oprettet tag: {tag}",
|
||||
@@ -1274,6 +1745,19 @@
|
||||
"theme": "Tema",
|
||||
"theme_selection": "Temavalg",
|
||||
"theme_selection_description": "Indstil automatisk temaet til lyst eller mørkt baseret på din browsers systempræference",
|
||||
"theme_setting_asset_list_storage_indicator_title": "Vis opbevaringsindikator på filer",
|
||||
"theme_setting_asset_list_tiles_per_row_title": "Antal elementer per række ({})",
|
||||
"theme_setting_colorful_interface_subtitle": "Tilføj primær farve til baggrundsoverflader.",
|
||||
"theme_setting_colorful_interface_title": "Farverig grænseflade",
|
||||
"theme_setting_image_viewer_quality_subtitle": "Juster kvaliteten i billedfremviseren",
|
||||
"theme_setting_image_viewer_quality_title": "Billedfremviserkvalitet",
|
||||
"theme_setting_primary_color_subtitle": "Vælg en farve til primære handlinger og accenter.",
|
||||
"theme_setting_primary_color_title": "Primær farve",
|
||||
"theme_setting_system_primary_color_title": "Brug systemfarver",
|
||||
"theme_setting_system_theme_switch": "Automatisk (Følg systemindstillinger)",
|
||||
"theme_setting_theme_subtitle": "Vælg appens temaindstilling",
|
||||
"theme_setting_three_stage_loading_subtitle": "Tre-trins indlæsning kan øge ydeevnen, men kan ligeledes føre til højere netværksbelastning",
|
||||
"theme_setting_three_stage_loading_title": "Slå tre-trins indlæsning til",
|
||||
"they_will_be_merged_together": "De vil blive slået sammen",
|
||||
"third_party_resources": "Tredjepartsressourcer",
|
||||
"time_based_memories": "Tidsbaserede minder",
|
||||
@@ -1293,7 +1777,15 @@
|
||||
"trash_all": "Smid alle ud",
|
||||
"trash_count": "Slet {count, number}",
|
||||
"trash_delete_asset": "Flyt mediefil til Papirkurv",
|
||||
"trash_emptied": "Tømte papirkurven",
|
||||
"trash_no_results_message": "Billeder og videoer markeret til sletning vil blive vist her.",
|
||||
"trash_page_delete_all": "Slet alt",
|
||||
"trash_page_empty_trash_dialog_content": "Vil du tømme papirkurven? Disse elementer vil blive permanent fjernet fra Immich",
|
||||
"trash_page_info": "Slettede elementer vil blive slettet permanent efter {} dage",
|
||||
"trash_page_no_assets": "Ingen slettede elementer",
|
||||
"trash_page_restore_all": "Gendan alt",
|
||||
"trash_page_select_assets_btn": "Vælg elementer",
|
||||
"trash_page_title": "Papirkurv ({})",
|
||||
"trashed_items_will_be_permanently_deleted_after": "Mediefiler i skraldespanden vil blive slettet permanent efter {days, plural, one {# dag} other {# dage}}.",
|
||||
"type": "Type",
|
||||
"unarchive": "Afakivér",
|
||||
@@ -1322,6 +1814,8 @@
|
||||
"updated_password": "Opdaterede adgangskode",
|
||||
"upload": "Upload",
|
||||
"upload_concurrency": "Upload samtidighed",
|
||||
"upload_dialog_info": "Vil du sikkerhedskopiere de(t) valgte element(er) til serveren?",
|
||||
"upload_dialog_title": "Upload element",
|
||||
"upload_errors": "Upload afsluttet med {count, plural, one {# fejl} other {# fejl}}. Opdater siden for at se nye uploadaktiver.",
|
||||
"upload_progress": "Resterende {remaining, number} - Behandlet {processed, number}/{total, number}",
|
||||
"upload_skipped_duplicates": "Sprang over {count, plural, one {# duplet aktiv} other {# duplikerede aktiver}}",
|
||||
@@ -1329,8 +1823,11 @@
|
||||
"upload_status_errors": "Fejl",
|
||||
"upload_status_uploaded": "Uploadet",
|
||||
"upload_success": "Upload gennemført. Opdater siden for at se nye uploadaktiver.",
|
||||
"upload_to_immich": "Upload to Immich ({})",
|
||||
"uploading": "Uploading",
|
||||
"url": "URL",
|
||||
"usage": "Forbrug",
|
||||
"use_current_connection": "brug nuværende forbindelse",
|
||||
"use_custom_date_range": "Brug tilpasset datointerval i stedet",
|
||||
"user": "Bruger",
|
||||
"user_id": "Bruger-ID",
|
||||
@@ -1345,10 +1842,16 @@
|
||||
"users": "Brugere",
|
||||
"utilities": "Værktøjer",
|
||||
"validate": "Validér",
|
||||
"validate_endpoint_error": "Indtast en gyldig URL",
|
||||
"variables": "Variabler",
|
||||
"version": "Version",
|
||||
"version_announcement_closing": "Din ven, Alex",
|
||||
"version_announcement_message": "Hej! En ny version af Immich er tilgængelig. Brug venligst lidt tid på at læse <link>udgivelsesbemærkningerne</link> for at sikre, at din opsætning er opdateret for at forhindre fejlkonfigurationer, især hvis du bruger WatchTower eller en mekanisme, der håndterer automatisk opdatering af din Immich-instans.",
|
||||
"version_announcement_overlay_release_notes": "udgivelsesnoterne",
|
||||
"version_announcement_overlay_text_1": "Hej ven, der er en ny version af",
|
||||
"version_announcement_overlay_text_2": ". Besøg venligst ",
|
||||
"version_announcement_overlay_text_3": " for at sikre dig, at din dockercompose- og .env-fil er opdateret, så der undgås fejlkonfiguration, specielt hvis du bruger WatchTower eller lignede.",
|
||||
"version_announcement_overlay_title": "Ny serverversion er tilgængelig 🎉",
|
||||
"version_history": "Versionshistorik",
|
||||
"version_history_item": "Installerede {version} den {date}",
|
||||
"video": "Video",
|
||||
@@ -1367,15 +1870,20 @@
|
||||
"view_next_asset": "Se næste medie",
|
||||
"view_previous_asset": "Se forrige medie",
|
||||
"view_stack": "Vis stak",
|
||||
"viewer_remove_from_stack": "Fjern fra stak",
|
||||
"viewer_stack_use_as_main_asset": "Brug som hovedelement",
|
||||
"viewer_unstack": "Fjern fra stak",
|
||||
"visibility_changed": "Synlighed ændret for {count, plural, one {# person} other {# personer}}",
|
||||
"waiting": "Venter",
|
||||
"warning": "Advarsel",
|
||||
"week": "Uge",
|
||||
"welcome": "Velkommen",
|
||||
"welcome_to_immich": "Velkommen til Immich",
|
||||
"wifi_name": "WiFi-navn",
|
||||
"year": "År",
|
||||
"years_ago": "{years, plural, one {# år} other {# år}} siden",
|
||||
"yes": "Ja",
|
||||
"you_dont_have_any_shared_links": "Du har ikke nogen delte links",
|
||||
"your_wifi_name": "Dit WiFi-navn",
|
||||
"zoom_image": "Zoom billede"
|
||||
}
|
||||
|
||||
532
i18n/de.json
532
i18n/de.json
File diff suppressed because it is too large
Load Diff
541
i18n/el.json
541
i18n/el.json
File diff suppressed because it is too large
Load Diff
580
i18n/en.json
580
i18n/en.json
File diff suppressed because it is too large
Load Diff
572
i18n/es.json
572
i18n/es.json
File diff suppressed because it is too large
Load Diff
229
i18n/et.json
229
i18n/et.json
@@ -4,6 +4,7 @@
|
||||
"account_settings": "Konto seaded",
|
||||
"acknowledge": "Sain aru",
|
||||
"action": "Tegevus",
|
||||
"action_common_update": "Uuenda",
|
||||
"actions": "Tegevused",
|
||||
"active": "Aktiivne",
|
||||
"activity": "Aktiivsus",
|
||||
@@ -13,6 +14,7 @@
|
||||
"add_a_location": "Lisa asukoht",
|
||||
"add_a_name": "Lisa nimi",
|
||||
"add_a_title": "Lisa pealkiri",
|
||||
"add_endpoint": "Lisa lõpp-punkt",
|
||||
"add_exclusion_pattern": "Lisa välistamismuster",
|
||||
"add_import_path": "Lisa imporditee",
|
||||
"add_location": "Lisa asukoht",
|
||||
@@ -22,6 +24,8 @@
|
||||
"add_photos": "Lisa fotosid",
|
||||
"add_to": "Lisa kohta…",
|
||||
"add_to_album": "Lisa albumisse",
|
||||
"add_to_album_bottom_sheet_added": "Lisatud albumisse {album}",
|
||||
"add_to_album_bottom_sheet_already_exists": "On juba albumis {album}",
|
||||
"add_to_shared_album": "Lisa jagatud albumisse",
|
||||
"add_url": "Lisa URL",
|
||||
"added_to_archive": "Lisatud arhiivi",
|
||||
@@ -35,11 +39,11 @@
|
||||
"authentication_settings_disable_all": "Kas oled kindel, et soovid kõik sisselogimismeetodid välja lülitada? Sisselogimine lülitatakse täielikult välja.",
|
||||
"authentication_settings_reenable": "Et taas lubada, kasuta <link>serveri käsku</link>.",
|
||||
"background_task_job": "Tausttegumid",
|
||||
"backup_database": "Varunda andmebaas",
|
||||
"backup_database_enable_description": "Luba andmebaasi varundamine",
|
||||
"backup_keep_last_amount": "Varukoopiate arv, mida alles hoida",
|
||||
"backup_settings": "Varundamise seaded",
|
||||
"backup_settings_description": "Halda andmebaasi varundamise seadeid",
|
||||
"backup_database": "Loo andmebaasi tõmmis",
|
||||
"backup_database_enable_description": "Luba andmebaasi tõmmised",
|
||||
"backup_keep_last_amount": "Eelmiste tõmmiste arv, mida alles hoida",
|
||||
"backup_settings": "Andmebaasi tõmmiste seaded",
|
||||
"backup_settings_description": "Halda andmebaasi tõmmiste seadeid. Märkus: Neid tööteid ei jälgita ning ebaõnnestumisest ei hoiatata.",
|
||||
"check_all": "Märgi kõik",
|
||||
"cleanup": "Koristus",
|
||||
"cleared_jobs": "Tööted eemaldatud: {job}",
|
||||
@@ -66,6 +70,11 @@
|
||||
"forcing_refresh_library_files": "Kogu kõigi failide sundvärskendamine",
|
||||
"image_format": "Formaat",
|
||||
"image_format_description": "WebP failid on väiksemad kui JPEG, aga kodeerimine on aeglasem.",
|
||||
"image_fullsize_description": "Täismõõdus pilt ilma metaandmeteta, kasutatakse sisse suumimisel",
|
||||
"image_fullsize_enabled": "Luba täismõõdus piltide genereerimine",
|
||||
"image_fullsize_enabled_description": "Genereeri mitte-veebisõbralike formaatide jaoks täismõõdus pilt. Kui \"Eelista manustatud eelvaadet\" on lubatud, kasutatakse manustatud eelvaateid otse ilma teisendamiseta. Ei mõjuta veebisõbralikke formaate nagu JPEG.",
|
||||
"image_fullsize_quality_description": "Täismõõdus pildi kvaliteet vahemikus 1-100. Kõrgem väärtus on parem, aga tulemuseks on suuremad failid.",
|
||||
"image_fullsize_title": "Täismõõdus pildi seaded",
|
||||
"image_prefer_embedded_preview": "Eelista manustatud eelvaadet",
|
||||
"image_prefer_embedded_preview_setting_description": "Kasuta pilditöötluse sisendina võimalusel RAW fotodesse manustatud eelvaateid. See võib mõnede piltide puhul anda tulemuseks täpsemad värvid, aga eelvaate kvaliteet sõltub konkreetsest kaamerast ning pildis võib olla rohkem tihendusmüra.",
|
||||
"image_prefer_wide_gamut": "Eelista laia värvigammat",
|
||||
@@ -162,7 +171,6 @@
|
||||
"no_pattern_added": "Mustreid ei ole",
|
||||
"note_apply_storage_label_previous_assets": "Märkus: Et rakendada talletussilt varem üleslaaditud üksustele, käivita",
|
||||
"note_cannot_be_changed_later": "MÄRKUS: Seda ei saa hiljem muuta!",
|
||||
"note_unlimited_quota": "Märkus: Piiramatu kvoodi jaoks sisesta 0",
|
||||
"notification_email_from_address": "Saatja aadress",
|
||||
"notification_email_from_address_description": "Saatja e-posti aadress, näiteks: \"Immich Photo Server <noreply@example.com>\"",
|
||||
"notification_email_host_description": "E-posti serveri host (nt. smtp.immich.app)",
|
||||
@@ -363,6 +371,10 @@
|
||||
"admin_password": "Administraatori parool",
|
||||
"administration": "Administratsioon",
|
||||
"advanced": "Täpsemad valikud",
|
||||
"advanced_settings_log_level_title": "Logimistase: {}",
|
||||
"advanced_settings_proxy_headers_title": "Vaheserveri päised",
|
||||
"advanced_settings_self_signed_ssl_title": "Luba endasigneeritud SSL-sertifikaadid",
|
||||
"advanced_settings_troubleshooting_title": "Tõrkeotsing",
|
||||
"age_months": "Vanus {months, plural, one {# kuu} other {# kuud}}",
|
||||
"age_year_months": "Vanus 1 aasta, {months, plural, one {# kuu} other {# kuud}}",
|
||||
"age_years": "{years, plural, other {Vanus #}}",
|
||||
@@ -371,6 +383,8 @@
|
||||
"album_cover_updated": "Albumi kaanepilt muudetud",
|
||||
"album_delete_confirmation": "Kas oled kindel, et soovid albumi {album} kustutada?",
|
||||
"album_delete_confirmation_description": "Kui see album on jagatud, ei pääse teised kasutajad sellele enam ligi.",
|
||||
"album_info_card_backup_album_excluded": "VÄLJA JÄETUD",
|
||||
"album_info_card_backup_album_included": "LISATUD",
|
||||
"album_info_updated": "Albumi info muudetud",
|
||||
"album_leave": "Lahku albumist?",
|
||||
"album_leave_confirmation": "Kas oled kindel, et soovid albumist {album} lahkuda?",
|
||||
@@ -379,10 +393,21 @@
|
||||
"album_remove_user": "Eemalda kasutaja?",
|
||||
"album_remove_user_confirmation": "Kas oled kindel, et soovid kasutaja {user} eemaldada?",
|
||||
"album_share_no_users": "Paistab, et oled seda albumit kõikide kasutajatega jaganud, või pole ühtegi kasutajat, kellega jagada.",
|
||||
"album_thumbnail_card_item": "1 üksus",
|
||||
"album_thumbnail_card_items": "{} üksust",
|
||||
"album_thumbnail_card_shared": " · Jagatud",
|
||||
"album_thumbnail_shared_by": "Jagas {}",
|
||||
"album_updated": "Album muudetud",
|
||||
"album_updated_setting_description": "Saa teavitus e-posti teel, kui jagatud albumis on uusi üksuseid",
|
||||
"album_user_left": "Lahkutud albumist {album}",
|
||||
"album_user_removed": "Kasutaja {user} eemaldatud",
|
||||
"album_viewer_appbar_delete_confirm": "Kas oled kindel, et soovid selle albumi oma kontolt kustutada?",
|
||||
"album_viewer_appbar_share_err_delete": "Albumi kustutamine ebaõnnestus",
|
||||
"album_viewer_appbar_share_err_leave": "Albumist lahkumine ebaõnnestus",
|
||||
"album_viewer_appbar_share_err_remove": "Üksuste albumist eemaldamisel tekkis probleeme",
|
||||
"album_viewer_appbar_share_err_title": "Albumi pealkirja muutmine ebaõnnestus",
|
||||
"album_viewer_appbar_share_leave": "Lahku albumist",
|
||||
"album_viewer_page_share_add_users": "Lisa kasutajaid",
|
||||
"album_with_link_access": "Luba kõigil, kellel on link, näha selle albumi fotosid ja isikuid.",
|
||||
"albums": "Albumid",
|
||||
"albums_count": "{count, plural, one {{count, number} album} other {{count, number} albumit}}",
|
||||
@@ -400,23 +425,36 @@
|
||||
"api_key_description": "Seda väärtust kuvatakse ainult üks kord. Kopeeri see enne akna sulgemist.",
|
||||
"api_key_empty": "Su API võtme nimi ei tohiks olla tühi",
|
||||
"api_keys": "API võtmed",
|
||||
"app_bar_signout_dialog_content": "Kas oled kindel, et soovid välja logida?",
|
||||
"app_bar_signout_dialog_ok": "Jah",
|
||||
"app_bar_signout_dialog_title": "Logi välja",
|
||||
"app_settings": "Rakenduse seaded",
|
||||
"appears_in": "Albumid",
|
||||
"archive": "Arhiiv",
|
||||
"archive_or_unarchive_photo": "Arhiveeri või taasta foto",
|
||||
"archive_page_no_archived_assets": "Arhiveeritud üksuseid ei leitud",
|
||||
"archive_size": "Arhiivi suurus",
|
||||
"archive_size_description": "Seadista arhiivi suurus allalaadimiseks (GiB)",
|
||||
"archived": "Arhiveeritud",
|
||||
"archived_count": "{count, plural, other {# arhiveeritud}}",
|
||||
"are_these_the_same_person": "Kas need on sama isik?",
|
||||
"are_you_sure_to_do_this": "Kas oled kindel, et soovid seda teha?",
|
||||
"asset_action_delete_err_read_only": "Kirjutuskaitstud üksuseid ei saa kustutada, jätan vahele",
|
||||
"asset_added_to_album": "Lisatud albumisse",
|
||||
"asset_adding_to_album": "Albumisse lisamine…",
|
||||
"asset_description_updated": "Üksuse kirjeldus on muudetud",
|
||||
"asset_filename_is_offline": "Üksus {filename} ei ole kättesaadav",
|
||||
"asset_has_unassigned_faces": "Üksusel on seostamata nägusid",
|
||||
"asset_hashing": "Räsimine…",
|
||||
"asset_list_group_by_sub_title": "Grupeeri",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dünaamiline asetus",
|
||||
"asset_list_layout_settings_group_automatically": "Automaatne",
|
||||
"asset_list_layout_settings_group_by": "Grupeeri üksused",
|
||||
"asset_list_layout_settings_group_by_month_day": "Kuu + päev",
|
||||
"asset_list_layout_sub_title": "Asetus",
|
||||
"asset_offline": "Üksus pole kättesaadav",
|
||||
"asset_offline_description": "Seda välise kogu üksust ei leitud kettalt. Abi saamiseks palun võta ühendust oma Immich'i administraatoriga.",
|
||||
"asset_restored_successfully": "Üksus edukalt taastatud",
|
||||
"asset_skipped": "Vahele jäetud",
|
||||
"asset_skipped_in_trash": "Prügikastis",
|
||||
"asset_uploaded": "Üleslaaditud",
|
||||
@@ -434,8 +472,26 @@
|
||||
"assets_trashed_count": "{count, plural, one {# üksus} other {# üksust}} liigutatud prügikasti",
|
||||
"assets_were_part_of_album_count": "{count, plural, one {Üksus oli} other {Üksused olid}} juba osa albumist",
|
||||
"authorized_devices": "Autoriseeritud seadmed",
|
||||
"automatic_endpoint_switching_subtitle": "Ühendu lokaalselt üle valitud WiFi-võrgu, kui see on saadaval, ja kasuta mujal alternatiivseid ühendusi",
|
||||
"back": "Tagasi",
|
||||
"back_close_deselect": "Tagasi, sulge või tühista valik",
|
||||
"backup_album_selection_page_select_albums": "Vali albumid",
|
||||
"backup_album_selection_page_selection_info": "Valiku info",
|
||||
"backup_album_selection_page_total_assets": "Unikaalseid üksuseid kokku",
|
||||
"backup_all": "Kõik",
|
||||
"backup_background_service_default_notification": "Uute üksuste kontrollimine…",
|
||||
"backup_background_service_error_title": "Varundamise viga",
|
||||
"backup_controller_page_background_battery_info_ok": "OK",
|
||||
"backup_controller_page_background_wifi": "Ainult WiFi-võrgus",
|
||||
"backup_controller_page_backup_sub": "Varundatud fotod ja videod",
|
||||
"backup_controller_page_desc_backup": "Lülita sisse esiplaanil varundamine, et rakenduse avamisel uued üksused automaatselt serverisse üles laadida.",
|
||||
"backup_controller_page_to_backup": "Albumid, mida varundada",
|
||||
"backup_controller_page_total_sub": "Kõik unikaalsed fotod ja videod valitud albumitest",
|
||||
"backup_err_only_album": "Ei saa ainsat albumit eemaldada",
|
||||
"backup_info_card_assets": "üksused",
|
||||
"backup_manual_cancelled": "Tühistatud",
|
||||
"backup_manual_title": "Üleslaadimise staatus",
|
||||
"backup_setting_subtitle": "Halda taustal ja esiplaanil üleslaadimise seadeid",
|
||||
"backward": "Tagasi",
|
||||
"birthdate_saved": "Sünnikuupäev salvestatud",
|
||||
"birthdate_set_description": "Sünnikuupäeva kasutatakse isiku vanuse arvutamiseks foto tegemise hetkel.",
|
||||
@@ -447,11 +503,14 @@
|
||||
"bulk_keep_duplicates_confirmation": "Kas oled kindel, et soovid {count, plural, one {# dubleeritud üksuse} other {# dubleeritud üksust}} alles jätta? Sellega märgitakse kõik duplikaadigrupid lahendatuks ilma midagi kustutamata.",
|
||||
"bulk_trash_duplicates_confirmation": "Kas oled kindel, et soovid {count, plural, one {# dubleeritud üksuse} other {# dubleeritud üksust}} masskustutada? Sellega jäetakse alles iga grupi suurim üksus ning duplikaadid liigutatakse prügikasti.",
|
||||
"buy": "Osta Immich",
|
||||
"cache_settings_clear_cache_button": "Tühjenda puhver",
|
||||
"cache_settings_statistics_title": "Puhvri kasutus",
|
||||
"camera": "Kaamera",
|
||||
"camera_brand": "Kaamera mark",
|
||||
"camera_model": "Kaamera mudel",
|
||||
"cancel": "Katkesta",
|
||||
"cancel_search": "Katkesta otsing",
|
||||
"canceled": "Tühistatud",
|
||||
"cannot_merge_people": "Ei saa isikuid ühendada",
|
||||
"cannot_undo_this_action": "Sa ei saa seda tagasi võtta!",
|
||||
"cannot_update_the_description": "Kirjelduse muutmine ebaõnnestus",
|
||||
@@ -462,6 +521,10 @@
|
||||
"change_name_successfully": "Nimi edukalt muudetud",
|
||||
"change_password": "Parooli muutmine",
|
||||
"change_password_description": "See on su esimene kord süsteemi siseneda, või on tehtud taotlus parooli muutmiseks. Palun sisesta allpool uus parool.",
|
||||
"change_password_form_confirm_password": "Kinnita parool",
|
||||
"change_password_form_new_password": "Uus parool",
|
||||
"change_password_form_password_mismatch": "Paroolid ei klapi",
|
||||
"change_password_form_reenter_new_password": "Korda uut parooli",
|
||||
"change_your_password": "Muuda oma parooli",
|
||||
"changed_visibility_successfully": "Nähtavus muudetud",
|
||||
"check_all": "Märgi kõik",
|
||||
@@ -473,6 +536,14 @@
|
||||
"clear_all_recent_searches": "Tühjenda hiljutised otsingud",
|
||||
"clear_message": "Tühjenda sõnum",
|
||||
"clear_value": "Tühjenda väärtus",
|
||||
"client_cert_dialog_msg_confirm": "OK",
|
||||
"client_cert_enter_password": "Sisesta parool",
|
||||
"client_cert_import": "Impordi",
|
||||
"client_cert_import_success_msg": "Klientsertifikaat on imporditud",
|
||||
"client_cert_invalid_msg": "Vigane sertifikaadi fail või vale parool",
|
||||
"client_cert_remove_msg": "Klientsertifikaat on eemaldatud",
|
||||
"client_cert_subtitle": "Toetab ainult PKCS12 (.p12, .pfx) formaati. Sertifikaadi importimine/eemaldamine on saadaval ainult enne sisselogimist",
|
||||
"client_cert_title": "SSL klientsertifikaat",
|
||||
"clockwise": "Päripäeva",
|
||||
"close": "Sulge",
|
||||
"collapse": "Peida",
|
||||
@@ -483,6 +554,8 @@
|
||||
"comment_options": "Kommentaari valikud",
|
||||
"comments_and_likes": "Kommentaarid ja meeldimised",
|
||||
"comments_are_disabled": "Kommentaarid on keelatud",
|
||||
"common_create_new_album": "Lisa uus album",
|
||||
"completed": "Lõpetatud",
|
||||
"confirm": "Kinnita",
|
||||
"confirm_admin_password": "Kinnita administraatori parool",
|
||||
"confirm_delete_face": "Kas oled kindel, et soovid isiku {name} näo üksuselt kustutada?",
|
||||
@@ -492,6 +565,10 @@
|
||||
"contain": "Mahuta ära",
|
||||
"context": "Kontekst",
|
||||
"continue": "Jätka",
|
||||
"control_bottom_app_bar_create_new_album": "Lisa uus album",
|
||||
"control_bottom_app_bar_delete_from_local": "Kustuta seadmest",
|
||||
"control_bottom_app_bar_edit_location": "Muuda asukohta",
|
||||
"control_bottom_app_bar_edit_time": "Muuda kuupäeva ja aega",
|
||||
"copied_image_to_clipboard": "Pilt kopeeritud lõikelauale.",
|
||||
"copied_to_clipboard": "Kopeeritud lõikelauale!",
|
||||
"copy_error": "Kopeeri viga",
|
||||
@@ -513,6 +590,7 @@
|
||||
"create_new_person": "Lisa uus isik",
|
||||
"create_new_person_hint": "Seosta valitud üksused uue isikuga",
|
||||
"create_new_user": "Lisa uus kasutaja",
|
||||
"create_shared_album_page_share_select_photos": "Vali fotod",
|
||||
"create_tag": "Lisa silt",
|
||||
"create_tag_description": "Lisa uus silt. Pesastatud siltide jaoks sisesta täielik tee koos kaldkriipsudega.",
|
||||
"create_user": "Lisa kasutaja",
|
||||
@@ -537,19 +615,23 @@
|
||||
"delete": "Kustuta",
|
||||
"delete_album": "Kustuta album",
|
||||
"delete_api_key_prompt": "Kas oled kindel, et soovid selle API võtme kustutada?",
|
||||
"delete_dialog_title": "Kustuta jäädavalt",
|
||||
"delete_duplicates_confirmation": "Kas oled kindel, et soovid need duplikaadid jäädavalt kustutada?",
|
||||
"delete_face": "Kustuta nägu",
|
||||
"delete_key": "Kustuta võti",
|
||||
"delete_library": "Kustuta kogu",
|
||||
"delete_link": "Kustuta link",
|
||||
"delete_local_dialog_ok_backed_up_only": "Kustuta ainult varundatud",
|
||||
"delete_others": "Kustuta teised",
|
||||
"delete_shared_link": "Kustuta jagatud link",
|
||||
"delete_shared_link_dialog_title": "Kustuta jagatud link",
|
||||
"delete_tag": "Kustuta silt",
|
||||
"delete_tag_confirmation_prompt": "Kas oled kindel, et soovid sildi {tagName} kustutada?",
|
||||
"delete_user": "Kustuta kasutaja",
|
||||
"deleted_shared_link": "Jagatud link kustutatud",
|
||||
"deletes_missing_assets": "Kustutab üksused, mis on kettalt puudu",
|
||||
"description": "Kirjeldus",
|
||||
"description_input_hint_text": "Lisa kirjeldus...",
|
||||
"details": "Üksikasjad",
|
||||
"direction": "Suund",
|
||||
"disabled": "Välja lülitatud",
|
||||
@@ -566,10 +648,20 @@
|
||||
"documentation": "Dokumentatsioon",
|
||||
"done": "Tehtud",
|
||||
"download": "Laadi alla",
|
||||
"download_canceled": "Allalaadimine katkestatud",
|
||||
"download_complete": "Allalaadimine lõpetatud",
|
||||
"download_enqueue": "Allalaadimine ootel",
|
||||
"download_error": "Allalaadimise viga",
|
||||
"download_failed": "Allalaadimine ebaõnnestus",
|
||||
"download_finished": "Allalaadimine lõpetatud",
|
||||
"download_include_embedded_motion_videos": "Manustatud videod",
|
||||
"download_include_embedded_motion_videos_description": "Lisa liikuvatesse fotodesse manustatud videod eraldi failidena",
|
||||
"download_paused": "Allalaadimine peatatud",
|
||||
"download_settings": "Allalaadimine",
|
||||
"download_settings_description": "Halda üksuste allalaadimise seadeid",
|
||||
"download_started": "Allalaadimine alustatud",
|
||||
"download_sucess": "Allalaadimine õnnestus",
|
||||
"download_sucess_android": "Meediumid laaditi alla kataloogi DCIM/Immich",
|
||||
"downloading": "Allalaadimine",
|
||||
"downloading_asset_filename": "Üksuse {filename} allalaadimine",
|
||||
"drop_files_to_upload": "Failide üleslaadimiseks sikuta need ükskõik kuhu",
|
||||
@@ -588,6 +680,7 @@
|
||||
"edit_key": "Muuda võtit",
|
||||
"edit_link": "Muuda linki",
|
||||
"edit_location": "Muuda asukohta",
|
||||
"edit_location_dialog_title": "Asukoht",
|
||||
"edit_name": "Muuda nime",
|
||||
"edit_people": "Muuda isikuid",
|
||||
"edit_tag": "Muuda silti",
|
||||
@@ -600,12 +693,15 @@
|
||||
"editor_crop_tool_h2_aspect_ratios": "Kuvasuhted",
|
||||
"editor_crop_tool_h2_rotation": "Pööre",
|
||||
"email": "E-post",
|
||||
"empty_folder": "See kaust on tühi",
|
||||
"empty_trash": "Tühjenda prügikast",
|
||||
"empty_trash_confirmation": "Kas oled kindel, et soovid prügikasti tühjendada? See eemaldab kõik seal olevad üksused Immich'ist jäädavalt.\nSeda tegevust ei saa tagasi võtta!",
|
||||
"enable": "Luba",
|
||||
"enabled": "Lubatud",
|
||||
"end_date": "Lõppkuupäev",
|
||||
"enter_wifi_name": "Sisesta WiFi-võrgu nimi",
|
||||
"error": "Viga",
|
||||
"error_change_sort_album": "Albumi sorteerimisjärjestuse muutmine ebaõnnestus",
|
||||
"error_delete_face": "Viga näo kustutamisel",
|
||||
"error_loading_image": "Viga pildi laadimisel",
|
||||
"error_title": "Viga - midagi läks valesti",
|
||||
@@ -736,8 +832,14 @@
|
||||
"unable_to_upload_file": "Faili üleslaadimine ebaõnnestus"
|
||||
},
|
||||
"exif": "Exif",
|
||||
"exif_bottom_sheet_description": "Lisa kirjeldus...",
|
||||
"exif_bottom_sheet_details": "ÜKSIKASJAD",
|
||||
"exif_bottom_sheet_location": "ASUKOHT",
|
||||
"exif_bottom_sheet_people": "ISIKUD",
|
||||
"exif_bottom_sheet_person_add_person": "Lisa nimi",
|
||||
"exit_slideshow": "Sulge slaidiesitlus",
|
||||
"expand_all": "Näita kõik",
|
||||
"experimental_settings_title": "Eksperimentaalne",
|
||||
"expire_after": "Aegub",
|
||||
"expired": "Aegunud",
|
||||
"expires_date": "Aegub {date}",
|
||||
@@ -748,6 +850,7 @@
|
||||
"extension": "Laiend",
|
||||
"external": "Väline",
|
||||
"external_libraries": "Välised kogud",
|
||||
"external_network_sheet_info": "Kui seade ei ole eelistatud WiFi-võrgus, ühendub rakendus serveriga allolevatest URL-idest esimese kättesaadava kaudu, alustades ülevalt",
|
||||
"face_unassigned": "Seostamata",
|
||||
"failed_to_load_assets": "Üksuste laadimine ebaõnnestus",
|
||||
"favorite": "Lemmik",
|
||||
@@ -763,6 +866,8 @@
|
||||
"filter_people": "Filtreeri isikuid",
|
||||
"find_them_fast": "Leia teda kiiresti nime järgi otsides",
|
||||
"fix_incorrect_match": "Paranda ebaõige vaste",
|
||||
"folder": "Kaust",
|
||||
"folder_not_found": "Kausta ei leitud",
|
||||
"folders": "Kaustad",
|
||||
"folders_feature_description": "Kaustavaate abil failisüsteemis olevate fotode ja videote sirvimine",
|
||||
"forward": "Edasi",
|
||||
@@ -779,6 +884,10 @@
|
||||
"group_places_by": "Grupeeri kohad...",
|
||||
"group_year": "Grupeeri aasta kaupa",
|
||||
"has_quota": "On kvoot",
|
||||
"header_settings_add_header_tip": "Lisa päis",
|
||||
"header_settings_field_validator_msg": "Väärtus ei saa olla tühi",
|
||||
"header_settings_header_name_input": "Päise nimi",
|
||||
"header_settings_header_value_input": "Päise väärtus",
|
||||
"hi_user": "Tere {name} ({email})",
|
||||
"hide_all_people": "Peida kõik isikud",
|
||||
"hide_gallery": "Peida galerii",
|
||||
@@ -786,8 +895,20 @@
|
||||
"hide_password": "Peida parool",
|
||||
"hide_person": "Peida isik",
|
||||
"hide_unnamed_people": "Peida nimetud isikud",
|
||||
"home_page_add_to_album_conflicts": "{added} üksust lisati albumisse {album}. {failed} üksust oli juba albumis.",
|
||||
"home_page_add_to_album_err_local": "Lokaalseid üksuseid ei saa veel albumisse lisada, jätan vahele",
|
||||
"home_page_add_to_album_success": "{added} üksust lisati albumisse {album}.",
|
||||
"home_page_album_err_partner": "Partneri üksuseid ei saa veel albumisse lisada, jätan vahele",
|
||||
"home_page_archive_err_local": "Lokaalseid üksuseid ei saa veel arhiveerida, jätan vahele",
|
||||
"home_page_archive_err_partner": "Partneri üksuseid ei saa arhiveerida, jätan vahele",
|
||||
"home_page_building_timeline": "Ajajoone koostamine",
|
||||
"home_page_delete_err_partner": "Partneri üksuseid ei saa kustutada, jätan vahele",
|
||||
"home_page_favorite_err_local": "Lokaalseid üksuseid ei saa lemmikuks märkida, jätan vahele",
|
||||
"home_page_favorite_err_partner": "Partneri üksuseid ei saa lemmikuks märkida, jätan vahele",
|
||||
"home_page_share_err_local": "Lokaalseid üksuseid ei saa lingiga jagada, jätan vahele",
|
||||
"host": "Host",
|
||||
"hour": "Tund",
|
||||
"ignore_icloud_photos": "Ignoreeri iCloud fotosid",
|
||||
"image": "Pilt",
|
||||
"image_alt_text_date": "{isVideo, select, true {Video} other {Pilt}} tehtud {date}",
|
||||
"image_alt_text_date_1_person": "{isVideo, select, true {Video} other {Pilt}} tehtud {date} koos isikuga {person1}",
|
||||
@@ -799,6 +920,8 @@
|
||||
"image_alt_text_date_place_2_people": "{isVideo, select, true {Video} other {Pilt}} tehtud {date} kohas {city}, {country} koos isikutega {person1} ja {person2}",
|
||||
"image_alt_text_date_place_3_people": "{isVideo, select, true {Video} other {Pilt}} tehtud {date} kohas {city}, {country} koos isikutega {person1}, {person2} ja {person3}",
|
||||
"image_alt_text_date_place_4_or_more_people": "{isVideo, select, true {Video} other {Pilt}} tehtud {date} kohas {city}, {country} koos {person1}, {person2} ja veel {additionalCount, number} isikuga",
|
||||
"image_viewer_page_state_provider_download_started": "Allalaadimine alustatud",
|
||||
"image_viewer_page_state_provider_download_success": "Allalaadimine õnnestus",
|
||||
"immich_logo": "Immich'i logo",
|
||||
"immich_web_interface": "Immich'i veebiliides",
|
||||
"import_from_json": "Impordi JSON-formaadist",
|
||||
@@ -817,6 +940,8 @@
|
||||
"night_at_midnight": "Iga päev keskööl",
|
||||
"night_at_twoam": "Iga öö kell 2"
|
||||
},
|
||||
"invalid_date": "Vigane kuupäev",
|
||||
"invalid_date_format": "Vigane kuupäevaformaat",
|
||||
"invite_people": "Kutsu inimesi",
|
||||
"invite_to_album": "Kutsu albumisse",
|
||||
"items_count": "{count, plural, one {# üksus} other {# üksust}}",
|
||||
@@ -837,6 +962,9 @@
|
||||
"level": "Tase",
|
||||
"library": "Kogu",
|
||||
"library_options": "Kogu seaded",
|
||||
"library_page_new_album": "Uus album",
|
||||
"library_page_sort_asset_count": "Üksuste arv",
|
||||
"library_page_sort_title": "Albumi pealkiri",
|
||||
"light": "Hele",
|
||||
"like_deleted": "Meeldimine kustutatud",
|
||||
"link_motion_video": "Lingi liikuv video",
|
||||
@@ -846,12 +974,24 @@
|
||||
"list": "Loend",
|
||||
"loading": "Laadimine",
|
||||
"loading_search_results_failed": "Otsitulemuste laadimine ebaõnnestus",
|
||||
"local_network_sheet_info": "Rakendus ühendub valitud Wi-Fi võrgus olles serveriga selle URL-i kaudu",
|
||||
"location_permission_content": "Automaatseks ümberlülitumiseks vajab Immich täpse asukoha luba, et saaks lugeda aktiivse WiFi-võrgu nime",
|
||||
"location_picker_choose_on_map": "Vali kaardil",
|
||||
"log_out": "Logi välja",
|
||||
"log_out_all_devices": "Logi kõigist seadmetest välja",
|
||||
"logged_out_all_devices": "Kõigist seadmetest välja logitud",
|
||||
"logged_out_device": "Seadmest välja logitud",
|
||||
"login": "Logi sisse",
|
||||
"login_form_back_button_text": "Tagasi",
|
||||
"login_form_email_hint": "sinunimi@email.com",
|
||||
"login_form_endpoint_hint": "http://serveri-ip:port",
|
||||
"login_form_endpoint_url": "Serveri lõpp-punkti URL",
|
||||
"login_form_err_http": "Palun täpsusta http:// või https://",
|
||||
"login_form_err_invalid_email": "Vigane e-posti aadress",
|
||||
"login_form_err_invalid_url": "Vigane URL",
|
||||
"login_form_password_hint": "parool",
|
||||
"login_has_been_disabled": "Sisselogimine on keelatud.",
|
||||
"login_password_changed_success": "Parool edukalt uuendatud",
|
||||
"logout_all_device_confirmation": "Kas oled kindel, et soovid kõigist seadmetest välja logida?",
|
||||
"logout_this_device_confirmation": "Kas oled kindel, et soovid sellest seadmest välja logida?",
|
||||
"longitude": "Pikkuskraad",
|
||||
@@ -859,6 +999,7 @@
|
||||
"loop_videos": "Taasesita videod",
|
||||
"loop_videos_description": "Lülita sisse, et detailvaates videot automaatselt taasesitada.",
|
||||
"main_branch_warning": "Sa kasutad arendusversiooni; soovitame tungivalt kasutada väljalaskeversiooni!",
|
||||
"main_menu": "Peamenüü",
|
||||
"make": "Mark",
|
||||
"manage_shared_links": "Halda jagatud linke",
|
||||
"manage_sharing_with_partners": "Halda partneritega jagamist",
|
||||
@@ -871,10 +1012,14 @@
|
||||
"map_marker_for_images": "Kaardimarker kohas {city}, {country} tehtud piltide jaoks",
|
||||
"map_marker_with_image": "Kaardimarker pildiga",
|
||||
"map_settings": "Kaardi seaded",
|
||||
"map_settings_date_range_option_day": "Viimased 24 tundi",
|
||||
"map_settings_date_range_option_year": "Viimane aasta",
|
||||
"map_settings_dialog_title": "Kaardi seaded",
|
||||
"matches": "Ühtivad failid",
|
||||
"media_type": "Meedia tüüp",
|
||||
"media_type": "Meediumi tüüp",
|
||||
"memories": "Mälestused",
|
||||
"memories_setting_description": "Halda, mida sa oma mälestustes näed",
|
||||
"memories_year_ago": "Aasta tagasi",
|
||||
"memory": "Mälestus",
|
||||
"memory_lane_title": "Mälestus {title}",
|
||||
"menu": "Menüü",
|
||||
@@ -891,10 +1036,14 @@
|
||||
"month": "Kuu",
|
||||
"more": "Rohkem",
|
||||
"moved_to_trash": "Liigutatud prügikasti",
|
||||
"multiselect_grid_edit_date_time_err_read_only": "Kirjutuskaitsega üksus(t)e kuupäeva ei saa muuta, jätan vahele",
|
||||
"multiselect_grid_edit_gps_err_read_only": "Kirjutuskaitsega üksus(t)e asukohta ei saa muuta, jätan vahele",
|
||||
"mute_memories": "Vaigista mälestused",
|
||||
"my_albums": "Minu albumid",
|
||||
"name": "Nimi",
|
||||
"name_or_nickname": "Nimi või hüüdnimi",
|
||||
"networking_settings": "Võrguühendus",
|
||||
"networking_subtitle": "Halda serveri lõpp-punkti seadeid",
|
||||
"never": "Mitte kunagi",
|
||||
"new_album": "Uus album",
|
||||
"new_api_key": "Uus API võti",
|
||||
@@ -923,7 +1072,6 @@
|
||||
"no_shared_albums_message": "Lisa album, et fotosid ja videosid teistega jagada",
|
||||
"not_in_any_album": "Pole üheski albumis",
|
||||
"note_apply_storage_label_to_previously_uploaded assets": "Märkus: Et rakendada talletussilt varem üleslaaditud üksustele, käivita",
|
||||
"note_unlimited_quota": "Märkus: Piiramatu kvoodi jaoks sisesta 0",
|
||||
"notes": "Märkused",
|
||||
"notification_toggle_setting_description": "Luba e-posti teel teavitused",
|
||||
"notifications": "Teavitused",
|
||||
@@ -958,6 +1106,9 @@
|
||||
"partner_can_access": "{partner} pääseb ligi",
|
||||
"partner_can_access_assets": "Kõik su fotod ja videod, välja arvatud arhiveeritud ja kustutatud",
|
||||
"partner_can_access_location": "Asukohad, kus su fotod tehti",
|
||||
"partner_list_view_all": "Vaata kõiki",
|
||||
"partner_page_partner_add_failed": "Partneri lisamine ebaõnnestus",
|
||||
"partner_page_select_partner": "Vali partner",
|
||||
"partner_sharing": "Partneriga jagamine",
|
||||
"partners": "Partnerid",
|
||||
"password": "Parool",
|
||||
@@ -986,6 +1137,7 @@
|
||||
"permanently_delete_assets_prompt": "Kas oled kindel, et soovid {count, plural, one {selle üksuse} other {need <b>#</b> üksust}} jäädavalt kustutada? Sellega eemaldatakse {count, plural, one {see} other {need}} ka oma albumi(te)st.",
|
||||
"permanently_deleted_asset": "Üksus jäädavalt kustutatud",
|
||||
"permanently_deleted_assets_count": "{count, plural, one {# üksus} other {# üksust}} jäädavalt kustutatud",
|
||||
"permission_onboarding_back": "Tagasi",
|
||||
"person": "Isik",
|
||||
"person_birthdate": "Sündinud {date}",
|
||||
"person_hidden": "{name}{hidden, select, true { (peidetud)} other {}}",
|
||||
@@ -1003,6 +1155,7 @@
|
||||
"play_motion_photo": "Esita liikuv foto",
|
||||
"play_or_pause_video": "Esita või peata video",
|
||||
"port": "Port",
|
||||
"preferences_settings_title": "Eelistused",
|
||||
"preset": "Eelseadistus",
|
||||
"preview": "Eelvaade",
|
||||
"previous": "Eelmine",
|
||||
@@ -1010,6 +1163,8 @@
|
||||
"previous_or_next_photo": "Eelmine või järgmine foto",
|
||||
"primary": "Peamine",
|
||||
"privacy": "Privaatsus",
|
||||
"profile_drawer_app_logs": "Logid",
|
||||
"profile_drawer_github": "GitHub",
|
||||
"profile_image_of_user": "Kasutaja {user} profiilipilt",
|
||||
"profile_picture_set": "Profiilipilt määratud.",
|
||||
"public_album": "Avalik album",
|
||||
@@ -1059,6 +1214,8 @@
|
||||
"recent": "Hiljutine",
|
||||
"recent-albums": "Hiljutised albumid",
|
||||
"recent_searches": "Hiljutised otsingud",
|
||||
"recently_added": "Hiljuti lisatud",
|
||||
"recently_added_page_title": "Hiljuti lisatud",
|
||||
"refresh": "Värskenda",
|
||||
"refresh_encoded_videos": "Värskenda kodeeritud videod",
|
||||
"refresh_faces": "Värskenda näod",
|
||||
@@ -1115,6 +1272,7 @@
|
||||
"role_editor": "Muutja",
|
||||
"role_viewer": "Vaataja",
|
||||
"save": "Salvesta",
|
||||
"save_to_gallery": "Salvesta galeriisse",
|
||||
"saved_api_key": "API võti salvestatud",
|
||||
"saved_profile": "Profiil salvestatud",
|
||||
"saved_settings": "Seaded salvestatud",
|
||||
@@ -1134,14 +1292,32 @@
|
||||
"search_camera_model": "Otsi kaamera mudelit...",
|
||||
"search_city": "Otsi linna...",
|
||||
"search_country": "Otsi riiki...",
|
||||
"search_filter_camera_title": "Vali kaamera tüüp",
|
||||
"search_filter_date": "Kuupäev",
|
||||
"search_filter_date_interval": "{start} kuni {end}",
|
||||
"search_filter_date_title": "Vali kuupäevavahemik",
|
||||
"search_filter_display_options": "Kuva valikud",
|
||||
"search_filter_filename": "Otsi failinime alusel",
|
||||
"search_filter_location": "Asukoht",
|
||||
"search_filter_location_title": "Vali asukoht",
|
||||
"search_filter_media_type": "Meediumi tüüp",
|
||||
"search_filter_media_type_title": "Vali meediumi tüüp",
|
||||
"search_filter_people_title": "Vali isikud",
|
||||
"search_for": "Otsi",
|
||||
"search_for_existing_person": "Otsi olemasolevat isikut",
|
||||
"search_no_people": "Isikuid ei ole",
|
||||
"search_no_people_named": "Ei ole isikuid nimega \"{name}\"",
|
||||
"search_options": "Otsingu valikud",
|
||||
"search_page_categories": "Kategooriad",
|
||||
"search_page_screenshots": "Ekraanipildid",
|
||||
"search_page_search_photos_videos": "Otsi oma fotosid ja videosid",
|
||||
"search_page_selfies": "Selfid",
|
||||
"search_page_things": "Asjad",
|
||||
"search_page_view_all_button": "Vaata kõiki",
|
||||
"search_people": "Otsi inimesi",
|
||||
"search_places": "Otsi kohti",
|
||||
"search_rating": "Otsi hinnangu järgi...",
|
||||
"search_result_page_new_search_hint": "Uus otsing",
|
||||
"search_settings": "Otsi seadeid",
|
||||
"search_state": "Otsi osariiki...",
|
||||
"search_tags": "Otsi silte...",
|
||||
@@ -1164,10 +1340,14 @@
|
||||
"select_new_face": "Vali uus nägu",
|
||||
"select_photos": "Vali fotod",
|
||||
"select_trash_all": "Vali kõik prügikasti",
|
||||
"select_user_for_sharing_page_err_album": "Albumi lisamine ebaõnnestus",
|
||||
"selected": "Valitud",
|
||||
"selected_count": "{count, plural, other {# valitud}}",
|
||||
"send_message": "Saada sõnum",
|
||||
"send_welcome_email": "Saada tervituskiri",
|
||||
"server_endpoint": "Serveri lõpp-punkt",
|
||||
"server_info_box_app_version": "Rakenduse versioon",
|
||||
"server_info_box_server_url": "Serveri URL",
|
||||
"server_offline": "Serveriga ühendus puudub",
|
||||
"server_online": "Server ühendatud",
|
||||
"server_stats": "Serveri statistika",
|
||||
@@ -1179,22 +1359,42 @@
|
||||
"set_date_of_birth": "Määra sünnikuupäev",
|
||||
"set_profile_picture": "Sea profiilipilt",
|
||||
"set_slideshow_to_fullscreen": "Kuva slaidiesitlus täisekraanil",
|
||||
"setting_languages_apply": "Rakenda",
|
||||
"setting_languages_title": "Keeled",
|
||||
"setting_notifications_notify_immediately": "kohe",
|
||||
"setting_notifications_notify_never": "mitte kunagi",
|
||||
"settings": "Seaded",
|
||||
"settings_saved": "Seaded salvestatud",
|
||||
"share": "Jaga",
|
||||
"shared": "Jagatud",
|
||||
"shared_album_section_people_action_error": "Viga albumist eemaldamisel/lahkumisel",
|
||||
"shared_album_section_people_action_leave": "Eemalda kasutaja albumist",
|
||||
"shared_album_section_people_action_remove_user": "Eemalda kasutaja albumist",
|
||||
"shared_album_section_people_title": "ISIKUD",
|
||||
"shared_by": "Jagas",
|
||||
"shared_by_user": "Jagas {user}",
|
||||
"shared_by_you": "Jagasid sina",
|
||||
"shared_from_partner": "Fotod partnerilt {partner}",
|
||||
"shared_link_app_bar_title": "Jagatud lingid",
|
||||
"shared_link_clipboard_copied_massage": "Kopeeritud lõikelauale",
|
||||
"shared_link_create_error": "Viga jagatud lingi loomisel",
|
||||
"shared_link_edit_expire_after_option_day": "1 päev",
|
||||
"shared_link_edit_expire_after_option_hour": "1 tund",
|
||||
"shared_link_edit_expire_after_option_minute": "1 minut",
|
||||
"shared_link_info_chip_metadata": "EXIF",
|
||||
"shared_link_manage_links": "Halda jagatud linke",
|
||||
"shared_link_options": "Jagatud lingi valikud",
|
||||
"shared_links": "Jagatud lingid",
|
||||
"shared_links_description": "Jaga fotosid ja videosid lingiga",
|
||||
"shared_photos_and_videos_count": "{assetCount, plural, other {# jagatud fotot ja videot.}}",
|
||||
"shared_with_me": "Minuga jagatud",
|
||||
"shared_with_partner": "Jagatud partneriga {partner}",
|
||||
"sharing": "Jagamine",
|
||||
"sharing_enter_password": "Palun sisesta selle lehe vaatamiseks salasõna.",
|
||||
"sharing_page_album": "Jagatud albumid",
|
||||
"sharing_sidebar_description": "Kuva külgmenüüs Jagamise linki",
|
||||
"sharing_silver_appbar_create_shared_album": "Uus jagatud album",
|
||||
"sharing_silver_appbar_share_partner": "Jaga partneriga",
|
||||
"shift_to_permanent_delete": "vajuta ⇧, et üksus jäädavalt kustutada",
|
||||
"show_album_options": "Näita albumi valikuid",
|
||||
"show_albums": "Näita albumeid",
|
||||
@@ -1261,6 +1461,7 @@
|
||||
"support_third_party_description": "Sinu Immich'i install on kolmanda osapoole pakendatud. Probleemid, mida täheldad, võivad olla põhjustatud selle pakendamise poolt, seega võta esmajärjekorras nendega ühendust, kasutades allolevaid linke.",
|
||||
"swap_merge_direction": "Muuda ühendamise suunda",
|
||||
"sync": "Sünkrooni",
|
||||
"sync_albums": "Sünkrooni albumid",
|
||||
"tag": "Silt",
|
||||
"tag_assets": "Sildista üksuseid",
|
||||
"tag_created": "Lisatud silt: {tag}",
|
||||
@@ -1274,6 +1475,9 @@
|
||||
"theme": "Teema",
|
||||
"theme_selection": "Teema valik",
|
||||
"theme_selection_description": "Sea automaatselt hele või tume teema vastavalt veebilehitseja eelistustele",
|
||||
"theme_setting_primary_color_title": "Põhivärv",
|
||||
"theme_setting_system_primary_color_title": "Kasuta süsteemset värvi",
|
||||
"theme_setting_system_theme_switch": "Automaatne (järgi süsteemi seadet)",
|
||||
"they_will_be_merged_together": "Nad ühendatakse kokku",
|
||||
"third_party_resources": "Kolmanda osapoole ressursid",
|
||||
"time_based_memories": "Ajapõhised mälestused",
|
||||
@@ -1294,6 +1498,9 @@
|
||||
"trash_count": "Liiguta {count, number} prügikasti",
|
||||
"trash_delete_asset": "Kustuta üksus",
|
||||
"trash_no_results_message": "Siia ilmuvad prügikasti liigutatud fotod ja videod.",
|
||||
"trash_page_delete_all": "Kustuta kõik",
|
||||
"trash_page_restore_all": "Taasta kõik",
|
||||
"trash_page_select_assets_btn": "Vali üksused",
|
||||
"trashed_items_will_be_permanently_deleted_after": "Prügikasti tõstetud üksused kustutatakse jäädavalt {days, plural, one {# päeva} other {# päeva}} pärast.",
|
||||
"type": "Tüüp",
|
||||
"unarchive": "Taasta arhiivist",
|
||||
@@ -1329,6 +1536,7 @@
|
||||
"upload_status_errors": "Vead",
|
||||
"upload_status_uploaded": "Üleslaaditud",
|
||||
"upload_success": "Üleslaadimine õnnestus, uute üksuste nägemiseks värskenda lehte.",
|
||||
"uploading": "Üleslaadimine",
|
||||
"url": "URL",
|
||||
"usage": "Kasutus",
|
||||
"use_custom_date_range": "Kasuta kohandatud kuupäevavahemikku",
|
||||
@@ -1366,16 +1574,21 @@
|
||||
"view_name": "Vaade",
|
||||
"view_next_asset": "Vaata järgmist üksust",
|
||||
"view_previous_asset": "Vaata eelmist üksust",
|
||||
"view_qr_code": "Vaata QR-koodi",
|
||||
"view_stack": "Vaata virna",
|
||||
"viewer_remove_from_stack": "Eemalda virnast",
|
||||
"viewer_unstack": "Eralda",
|
||||
"visibility_changed": "{count, plural, one {# isiku} other {# isiku}} nähtavus muudetud",
|
||||
"waiting": "Ootel",
|
||||
"warning": "Hoiatus",
|
||||
"week": "Nädal",
|
||||
"welcome": "Tere tulemast",
|
||||
"welcome_to_immich": "Tere tulemast Immich'isse",
|
||||
"wifi_name": "WiFi-võrgu nimi",
|
||||
"year": "Aasta",
|
||||
"years_ago": "{years, plural, one {# aasta} other {# aastat}} tagasi",
|
||||
"yes": "Jah",
|
||||
"you_dont_have_any_shared_links": "Sul pole ühtegi jagatud linki",
|
||||
"your_wifi_name": "Sinu WiFi-võrgu nimi",
|
||||
"zoom_image": "Suumi pilti"
|
||||
}
|
||||
|
||||
1
i18n/eu.json
Normal file
1
i18n/eu.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -132,7 +132,6 @@
|
||||
"no_pattern_added": "هیچ الگوی اضافه نشده",
|
||||
"note_apply_storage_label_previous_assets": "توجه: برای اعمال برچسب ذخیره سازی به دارایی هایی که قبلاً بارگذاری شده اند، دستور زیر را اجرا کنید",
|
||||
"note_cannot_be_changed_later": "توجه: این را نمی توان بعداً تغییر داد!",
|
||||
"note_unlimited_quota": "توجه: برای سهمیه نامحدود، عدد 0 را وارد کنید",
|
||||
"notification_email_from_address": "آدرس فرستنده",
|
||||
"notification_email_from_address_description": "آدرس ایمیل فرستنده، به عنوان مثال:\"Immich سرور عکس <noreply@example.com>\"",
|
||||
"notification_email_host_description": "میزبان سرور ایمیل (مثلاً smtp.immich.app)",
|
||||
@@ -664,7 +663,6 @@
|
||||
"no_shared_albums_message": "",
|
||||
"not_in_any_album": "در هیچ آلبومی نیست",
|
||||
"note_apply_storage_label_to_previously_uploaded assets": "",
|
||||
"note_unlimited_quota": "",
|
||||
"notes": "یادداشتها",
|
||||
"notification_toggle_setting_description": "اعلانهای ایمیلی را فعال کنید",
|
||||
"notifications": "اعلانها",
|
||||
@@ -926,4 +924,4 @@
|
||||
"yes": "بله",
|
||||
"you_dont_have_any_shared_links": "",
|
||||
"zoom_image": "بزرگنمایی تصویر"
|
||||
}
|
||||
}
|
||||
|
||||
517
i18n/fi.json
517
i18n/fi.json
@@ -4,6 +4,7 @@
|
||||
"account_settings": "Tilin asetukset",
|
||||
"acknowledge": "Tiedostan",
|
||||
"action": "Toiminta",
|
||||
"action_common_update": "Päivitä",
|
||||
"actions": "Toimintoja",
|
||||
"active": "Aktiivinen",
|
||||
"activity": "Aktiviteetti",
|
||||
@@ -13,6 +14,7 @@
|
||||
"add_a_location": "Lisää sijainti",
|
||||
"add_a_name": "Lisää nimi",
|
||||
"add_a_title": "Lisää otsikko",
|
||||
"add_endpoint": "Add endpoint",
|
||||
"add_exclusion_pattern": "Lisää poissulkemismalli",
|
||||
"add_import_path": "Lisää tuontipolku",
|
||||
"add_location": "Lisää sijainti",
|
||||
@@ -22,6 +24,8 @@
|
||||
"add_photos": "Lisää kuvia",
|
||||
"add_to": "Lisää…",
|
||||
"add_to_album": "Lisää albumiin",
|
||||
"add_to_album_bottom_sheet_added": "Lisätty albumiin {album}",
|
||||
"add_to_album_bottom_sheet_already_exists": "Kohde on jo albumissa {album}",
|
||||
"add_to_shared_album": "Lisää jaettuun albumiin",
|
||||
"add_url": "Lisää URL",
|
||||
"added_to_archive": "Arkistoitu",
|
||||
@@ -159,7 +163,6 @@
|
||||
"no_pattern_added": "Kaavoja ei lisättynä",
|
||||
"note_apply_storage_label_previous_assets": "Huom: Asettaaksesi nimikkeen aiemmin ladatulle aineistolle, aja",
|
||||
"note_cannot_be_changed_later": "Huom: Tätä ei voi enää myöhemmin vaihtaa!",
|
||||
"note_unlimited_quota": "Huom: Määritä 0 rajoittamattomaksi kiintiöksi",
|
||||
"notification_email_from_address": "Lähettäjän osoite",
|
||||
"notification_email_from_address_description": "Lähettäjän sähköpostiosoite. Esimerkiksi \"Immich-kuvapalvelin <noreply@example.com>\"",
|
||||
"notification_email_host_description": "Sähköpostipalvelin (esim. smtp.immich.app)",
|
||||
@@ -219,7 +222,7 @@
|
||||
"reset_settings_to_default": "Nollaa asetukset oletuksille",
|
||||
"reset_settings_to_recent_saved": "Palauta aiemmin tallennetut asetukset",
|
||||
"scanning_library": "Kirjastoa skannataan",
|
||||
"search_jobs": "Etsi tehtäviä...",
|
||||
"search_jobs": "Etsi tehtäviä…",
|
||||
"send_welcome_email": "Lähetä tervetuloviesti",
|
||||
"server_external_domain_settings": "Ulkoinen osoite",
|
||||
"server_external_domain_settings_description": "Osoite julkisille linkeille, http(s):// mukaan lukien",
|
||||
@@ -360,6 +363,16 @@
|
||||
"admin_password": "Ylläpitäjän salasana",
|
||||
"administration": "Ylläpito",
|
||||
"advanced": "Edistyneet",
|
||||
"advanced_settings_log_level_title": "Lokitaso: {}",
|
||||
"advanced_settings_prefer_remote_subtitle": "Jotkut laitteet ovat erittäin hitaita lataamaan esikatselukuvia laitteen kohteista. Aktivoi tämä asetus käyttääksesi etäkuvia.",
|
||||
"advanced_settings_prefer_remote_title": "Suosi etäkuvia",
|
||||
"advanced_settings_proxy_headers_subtitle": "Define proxy headers Immich should send with each network request",
|
||||
"advanced_settings_proxy_headers_title": "Proxy Headers",
|
||||
"advanced_settings_self_signed_ssl_subtitle": "Ohita SSL sertifikaattivarmennus palvelimen päätepisteellä. Vaaditaan self-signed -sertifikaateissa.",
|
||||
"advanced_settings_self_signed_ssl_title": "Salli self-signed SSL -sertifikaatit",
|
||||
"advanced_settings_tile_subtitle": "Edistyneen käyttäjän asetukset",
|
||||
"advanced_settings_troubleshooting_subtitle": "Ota vianetsinnän lisäominaisuudet käyttöön",
|
||||
"advanced_settings_troubleshooting_title": "Vianetsintä",
|
||||
"age_months": "Ikä {months, plural, one {# kuukausi} other {# kuukautta}}",
|
||||
"age_year_months": "Ikä 1 vuosi, {months, plural, one {# kuukausi} other {# kuukautta}}",
|
||||
"age_years": "{years, plural, other {Ikä #v}}",
|
||||
@@ -368,6 +381,8 @@
|
||||
"album_cover_updated": "Albumin kansikuva päivitetty",
|
||||
"album_delete_confirmation": "Haluatko varmasti poistaa albumin {album}?",
|
||||
"album_delete_confirmation_description": "Jos albumi on jaettu, muut eivät pääse siihen enää.",
|
||||
"album_info_card_backup_album_excluded": "JÄTETTY POIS",
|
||||
"album_info_card_backup_album_included": "SISÄLLYTETTY",
|
||||
"album_info_updated": "Albumin tiedot päivitetty",
|
||||
"album_leave": "Poistu albumista?",
|
||||
"album_leave_confirmation": "Haluatko varmasti poistua albumista {album}?",
|
||||
@@ -376,10 +391,22 @@
|
||||
"album_remove_user": "Poista käyttäjä?",
|
||||
"album_remove_user_confirmation": "Oletko varma että haluat poistaa {user}?",
|
||||
"album_share_no_users": "Näyttää että olet jakanut tämän albumin kaikkien kanssa, tai sinulla ei ole käyttäjiä joille jakaa.",
|
||||
"album_thumbnail_card_item": "1 kohde",
|
||||
"album_thumbnail_card_items": "{} kohdetta",
|
||||
"album_thumbnail_card_shared": "Jaettu",
|
||||
"album_thumbnail_shared_by": "Jakanut {}",
|
||||
"album_updated": "Albumi päivitetty",
|
||||
"album_updated_setting_description": "Saa sähköpostia kun jaetussa albumissa on uutta sisältöä",
|
||||
"album_user_left": "Poistuttiin albumista {album}",
|
||||
"album_user_removed": "{user} poistettu",
|
||||
"album_viewer_appbar_delete_confirm": "Haluatko varmast poistaa tämän albumin tililtäsi?",
|
||||
"album_viewer_appbar_share_err_delete": "Albumin poistaminen epäonnistui",
|
||||
"album_viewer_appbar_share_err_leave": "Albumista poistuminen epäonnistui",
|
||||
"album_viewer_appbar_share_err_remove": "Ongelmia kohteiden poistamisessa albumista",
|
||||
"album_viewer_appbar_share_err_title": "Albumin nimen muuttaminen epäonnistui",
|
||||
"album_viewer_appbar_share_leave": "Poistu albumista",
|
||||
"album_viewer_appbar_share_to": "Jaa",
|
||||
"album_viewer_page_share_add_users": "Lisää käyttäjiä",
|
||||
"album_with_link_access": "Anna kenen tahansa nähdä linkin kautta tämän albumin valokuvat ja henkilöt.",
|
||||
"albums": "Albumit",
|
||||
"albums_count": "{count, plural, one {{count, number} albumi} other {{count, number} albumia}}",
|
||||
@@ -396,42 +423,133 @@
|
||||
"api_key_description": "Tämä arvo näytetään vain kerran. Varmista, että olet kopioinut sen ennen kuin suljet ikkunan.",
|
||||
"api_key_empty": "API-avaimesi ei pitäisi olla tyhjä",
|
||||
"api_keys": "API-avaimet",
|
||||
"app_bar_signout_dialog_content": "Haluatko varmasti kirjautua ulos?",
|
||||
"app_bar_signout_dialog_ok": "Kyllä",
|
||||
"app_bar_signout_dialog_title": "Kirjaudu ulos",
|
||||
"app_settings": "Sovellusasetukset",
|
||||
"appears_in": "Esiintyy albumeissa",
|
||||
"archive": "Arkisto",
|
||||
"archive_or_unarchive_photo": "Arkistoi kuva tai palauta arkistosta",
|
||||
"archive_page_no_archived_assets": "Arkistoituja kohteita ei löytynyt",
|
||||
"archive_page_title": "Arkisto ({})",
|
||||
"archive_size": "Arkiston koko",
|
||||
"archive_size_description": "Määritä arkiston koko latauksissa (Gt)",
|
||||
"archived": "Archived",
|
||||
"archived_count": "{count, plural, other {Arkistoitu #}}",
|
||||
"are_these_the_same_person": "Ovatko he sama henkilö?",
|
||||
"are_you_sure_to_do_this": "Haluatko varmasti tehdä tämän?",
|
||||
"asset_action_delete_err_read_only": "Vain luku-tilassa olevia kohteita ei voitu poistaa, ohitetaan",
|
||||
"asset_action_share_err_offline": "Verkottomassa tilassa olevia kohteita ei voitu noutaa, ohitetaan",
|
||||
"asset_added_to_album": "Lisätty albumiin",
|
||||
"asset_adding_to_album": "Lisätään albumiin...",
|
||||
"asset_adding_to_album": "Lisätään albumiin…",
|
||||
"asset_description_updated": "Kohteen kuvaus on päivitetty",
|
||||
"asset_filename_is_offline": "Kohde {filename} on offline-tilassa",
|
||||
"asset_has_unassigned_faces": "Kohteella on määrittämättömiä kasvoja",
|
||||
"asset_hashing": "Hajautetaan...",
|
||||
"asset_hashing": "Hajautetaan…",
|
||||
"asset_list_group_by_sub_title": "Ryhmittele",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dynaaminen asetelma",
|
||||
"asset_list_layout_settings_group_automatically": "Automaattisesti",
|
||||
"asset_list_layout_settings_group_by": "Ryhmittele",
|
||||
"asset_list_layout_settings_group_by_month_day": "Kuukauden ja päivän mukaan",
|
||||
"asset_list_layout_sub_title": "Asettelu",
|
||||
"asset_list_settings_subtitle": "Kuvaruudukon asettelu",
|
||||
"asset_list_settings_title": "Kuvaruudukko",
|
||||
"asset_offline": "Aineisto offline-tilassa",
|
||||
"asset_offline_description": "Tätä ulkoista resurssia ei enää löydy levyltä. Ole hyvä ja ota yhteyttä Immich-järjestelmänvalvojaan saadaksesi apua.",
|
||||
"asset_restored_successfully": "Asset restored successfully",
|
||||
"asset_skipped": "Ohitettu",
|
||||
"asset_skipped_in_trash": "Roskakorissa",
|
||||
"asset_uploaded": "Lähetetty",
|
||||
"asset_uploading": "Lähetetään…",
|
||||
"asset_viewer_settings_subtitle": "Manage your gallery viewer settings",
|
||||
"asset_viewer_settings_title": "Katselin",
|
||||
"assets": "kohdetta",
|
||||
"assets_added_count": "Lisätty {count, plural, one {# kohde} other {# kohdetta}}",
|
||||
"assets_added_to_album_count": "Albumiin lisätty {count, plural, one {# kohde} other {# kohdetta}}",
|
||||
"assets_added_to_name_count": "Lisätty {count, plural, one {# kohde} other {# kohdetta}} {hasName, select, true {<b>{name}</b>} other {uuteen albumiin}}",
|
||||
"assets_count": "{count, plural, one {# media} other {# mediaa}}",
|
||||
"assets_deleted_permanently": "{} asset(s) deleted permanently",
|
||||
"assets_deleted_permanently_from_server": "{} asset(s) deleted permanently from the Immich server",
|
||||
"assets_moved_to_trash_count": "Siirretty {count, plural, one {# media} other {# mediaa}} roskakoriin",
|
||||
"assets_permanently_deleted_count": "{count, plural, one {# media} other {# mediaa}} poistettu pysyvästi",
|
||||
"assets_removed_count": "{count, plural, one {# media} other {# mediaa}} poistettu",
|
||||
"assets_removed_permanently_from_device": "{} asset(s) removed permanently from your device",
|
||||
"assets_restore_confirmation": "Haluatko varmasti palauttaa kaikki roskakoriisi siirretyt resurssit? Tätä toimintoa ei voi peruuttaa! Huomaa, että offline-resursseja ei voida palauttaa tällä tavalla.",
|
||||
"assets_restored_count": "{count, plural, one {# media} other {# mediaa}} palautettu",
|
||||
"assets_restored_successfully": "{} asset(s) restored successfully",
|
||||
"assets_trashed": "{} asset(s) trashed",
|
||||
"assets_trashed_count": "{count, plural, one {# media} other {# mediaa}} siirretty roskakoriin",
|
||||
"assets_trashed_from_server": "{} asset(s) trashed from the Immich server",
|
||||
"assets_were_part_of_album_count": "{count, plural, one {Media oli} other {Mediat olivat}} jo albumissa",
|
||||
"authorized_devices": "Valtuutetut laitteet",
|
||||
"automatic_endpoint_switching_subtitle": "Connect locally over designated Wi-Fi when available and use alternative connections elsewhere",
|
||||
"automatic_endpoint_switching_title": "Automatic URL switching",
|
||||
"back": "Takaisin",
|
||||
"back_close_deselect": "Palaa, sulje tai poista valinnat",
|
||||
"background_location_permission": "Background location permission",
|
||||
"background_location_permission_content": "In order to switch networks when running in the background, Immich must *always* have precise location access so the app can read the Wi-Fi network's name",
|
||||
"backup_album_selection_page_albums_device": "Laitteen albumit ({})",
|
||||
"backup_album_selection_page_albums_tap": "Napauta sisällyttääksesi, kaksoisnapauta jättääksesi pois",
|
||||
"backup_album_selection_page_assets_scatter": "Kohteet voivat olla hajaantuneina useisiin albumeihin. Albumeita voidaan sisällyttää varmuuskopiointiin tai jättää siitä pois.",
|
||||
"backup_album_selection_page_select_albums": "Valitse albumit",
|
||||
"backup_album_selection_page_selection_info": "Valintatiedot",
|
||||
"backup_album_selection_page_total_assets": "Uniikkeja kohteita yhteensä",
|
||||
"backup_all": "Kaikki",
|
||||
"backup_background_service_backup_failed_message": "Kohteiden varmuuskopiointi epäonnistui. Yritetään uudelleen...",
|
||||
"backup_background_service_connection_failed_message": "Palvelimeen ei saatu yhteyttä. Yritetään uudelleen...",
|
||||
"backup_background_service_current_upload_notification": "Lähetetään {}",
|
||||
"backup_background_service_default_notification": "Tarkistetaan uusia kohteita...",
|
||||
"backup_background_service_error_title": "Virhe varmuuskopioinnissa",
|
||||
"backup_background_service_in_progress_notification": "Varmuuskopioidaan kohteita...",
|
||||
"backup_background_service_upload_failure_notification": "Lähetys palvelimelle epäonnistui {}",
|
||||
"backup_controller_page_albums": "Varmuuskopioi albumit",
|
||||
"backup_controller_page_background_app_refresh_disabled_content": "Salli sovelluksen päivittäminen taustalla suorittaaksesi varmuuskopiointia taustalla: Asetukset > Yleiset > Appien päivitys taustalla",
|
||||
"backup_controller_page_background_app_refresh_disabled_title": "Sovelluksen päivittäminen taustalla on pois päältä",
|
||||
"backup_controller_page_background_app_refresh_enable_button_text": "Siirry asetuksiin",
|
||||
"backup_controller_page_background_battery_info_link": "Näytä minulle miten",
|
||||
"backup_controller_page_background_battery_info_message": "Kytke pois päältä kaikki Immichin taustatyöskentelyyn liittyvät akun optimoinnit, jotta varmistat taustavarmuuskopioinnin parhaan mahdollisen toiminnan.\n\nKoska tämä on laitekohtaista, tarkista tarvittavat toimet laitevalmistajan ohjeista.",
|
||||
"backup_controller_page_background_battery_info_ok": "OK",
|
||||
"backup_controller_page_background_battery_info_title": "Akun optimointi",
|
||||
"backup_controller_page_background_charging": "Vain laitteen ollessa kytkettynä laturiin",
|
||||
"backup_controller_page_background_configure_error": "Taustapalvelun asettaminen epäonnistui",
|
||||
"backup_controller_page_background_delay": "Viivästytä uusien kohteiden varmuuskopiointia: {}",
|
||||
"backup_controller_page_background_description": "Kytke taustapalvelu päälle varmuuskopioidaksesi uudet kohteet automaattisesti, ilman sovelluksen avaamista",
|
||||
"backup_controller_page_background_is_off": "Automaattinen varmuuskopiointi taustalla on pois päältä",
|
||||
"backup_controller_page_background_is_on": "Automaattinen varmuuskopiointi taustalla on päällä",
|
||||
"backup_controller_page_background_turn_off": "Kytke taustapalvelu pois päältä",
|
||||
"backup_controller_page_background_turn_on": "Kytke taustapalvelu päälle",
|
||||
"backup_controller_page_background_wifi": "Vain WiFi-verkossa",
|
||||
"backup_controller_page_backup": "Varmuuskopiointi",
|
||||
"backup_controller_page_backup_selected": "Valittu: ",
|
||||
"backup_controller_page_backup_sub": "Varmuuskopioidut kuvat ja videot",
|
||||
"backup_controller_page_created": "Luotu: {}",
|
||||
"backup_controller_page_desc_backup": "Kytke varmuuskopiointi päälle lähettääksesi uudet kohteet palvelimelle automaattisesti.",
|
||||
"backup_controller_page_excluded": "Jätetty pois: ",
|
||||
"backup_controller_page_failed": "Epäonnistui ({})",
|
||||
"backup_controller_page_filename": "Tiedoston nimi: {} [{}]",
|
||||
"backup_controller_page_id": "ID: {}",
|
||||
"backup_controller_page_info": "Varmuuskopioinnin tiedot",
|
||||
"backup_controller_page_none_selected": "Ei mitään",
|
||||
"backup_controller_page_remainder": "Jäljellä",
|
||||
"backup_controller_page_remainder_sub": "Varmuuskopiointia odottavat kuvat ja videot",
|
||||
"backup_controller_page_server_storage": "Palvelimen tallennustila",
|
||||
"backup_controller_page_start_backup": "Aloita varmuuskopiointi",
|
||||
"backup_controller_page_status_off": "Varmuuskopiointi on pois päältä",
|
||||
"backup_controller_page_status_on": "Varmuuskopiointi on päällä",
|
||||
"backup_controller_page_storage_format": "{} / {} käytetty",
|
||||
"backup_controller_page_to_backup": "Varmuuskopioitavat albumit",
|
||||
"backup_controller_page_total_sub": "Kaikki uniikit kuvat ja videot valituista albumeista",
|
||||
"backup_controller_page_turn_off": "Varmuuskopiointi pois päältä",
|
||||
"backup_controller_page_turn_on": "Varmuuskopiointi päälle",
|
||||
"backup_controller_page_uploading_file_info": "Tiedostojen lähetystiedot",
|
||||
"backup_err_only_album": "Vähintään yhden albumin tulee olla valittuna",
|
||||
"backup_info_card_assets": "kohdetta",
|
||||
"backup_manual_cancelled": "Peruutettu",
|
||||
"backup_manual_in_progress": "Lähetys palvelimelle on jo käynnissä. Kokeile uudelleen hetken kuluttua.",
|
||||
"backup_manual_success": "Onnistui",
|
||||
"backup_manual_title": "Lähetyksen tila",
|
||||
"backup_options_page_title": "Varmuuskopioinnin asetukset",
|
||||
"backup_setting_subtitle": "Manage background and foreground upload settings",
|
||||
"backward": "Taaksepäin",
|
||||
"birthdate_saved": "Syntymäaika tallennettu",
|
||||
"birthdate_set_description": "Syntymäaikaa käytetään laskemaan henkilön ikä kuvanottohetkellä.",
|
||||
@@ -443,24 +561,52 @@
|
||||
"bulk_keep_duplicates_confirmation": "Haluatko varmasti säilyttää {count, plural, one {# kaksoiskappaleen} other {# kaksoiskappaleet}}? Tämä merkitsee kaikki kaksoiskappaleet ratkaistuiksi, eikä poista mitään.",
|
||||
"bulk_trash_duplicates_confirmation": "Haluatko varmasti siirtää {count, plural, one {# kaksoiskappaleen} other {# kaksoiskappaleet}} roskakoriin? Tämä säilyttää kustakin mediasta kookkaimman ja siirtää loput roskakoriin.",
|
||||
"buy": "Osta lisenssi Immich:iin",
|
||||
"cache_settings_album_thumbnails": "Kirjastosivun esikatselukuvat ({} kohdetta)",
|
||||
"cache_settings_clear_cache_button": "Tyhjennä välimuisti",
|
||||
"cache_settings_clear_cache_button_title": "Tyhjennä sovelluksen välimuisti. Tämä vaikuttaa merkittävästi sovelluksen suorituskykyyn, kunnes välimuisti on rakennettu uudelleen.",
|
||||
"cache_settings_duplicated_assets_clear_button": "Tyhjennä",
|
||||
"cache_settings_duplicated_assets_subtitle": "Sovelluksen mustalle listalle merkitsemät valokuvat ja videot",
|
||||
"cache_settings_duplicated_assets_title": "Kaksoiskappaleet ({})",
|
||||
"cache_settings_image_cache_size": "Kuvien välimuistin koko ({} kohdetta)",
|
||||
"cache_settings_statistics_album": "Kirjaston esikatselukuvat",
|
||||
"cache_settings_statistics_assets": "{} kohdetta ({})",
|
||||
"cache_settings_statistics_full": "Täysikokoiset kuvat",
|
||||
"cache_settings_statistics_shared": "Jaettujen albumien esikatselukuvat",
|
||||
"cache_settings_statistics_thumbnail": "Esikatselukuvat",
|
||||
"cache_settings_statistics_title": "Välimuistin käyttö",
|
||||
"cache_settings_subtitle": "Hallitse Immich-mobiilisovelluksen välimuistin käyttöä",
|
||||
"cache_settings_thumbnail_size": "Esikatselukuvien välimuistin koko ({} kohdetta)",
|
||||
"cache_settings_tile_subtitle": "Hallitse paikallista tallenustilaa",
|
||||
"cache_settings_tile_title": "Paikallinen tallennustila",
|
||||
"cache_settings_title": "Välimuistin asetukset",
|
||||
"camera": "Kamera",
|
||||
"camera_brand": "Kameran merkki",
|
||||
"camera_model": "Kameran malli",
|
||||
"cancel": "Peruuta",
|
||||
"cancel_search": "Peru haku",
|
||||
"canceled": "Canceled",
|
||||
"cannot_merge_people": "Ihmisiä ei voitu yhdistää",
|
||||
"cannot_undo_this_action": "Et voi perua tätä toimintoa!",
|
||||
"cannot_update_the_description": "Kuvausta ei voi päivittää",
|
||||
"change_date": "Vaihda päiväys",
|
||||
"change_display_order": "Change display order",
|
||||
"change_expiration_time": "Muuta erääntymisaikaa",
|
||||
"change_location": "Vaihda sijainti",
|
||||
"change_name": "Vaihda nimi",
|
||||
"change_name_successfully": "Nimi vaihdettu",
|
||||
"change_password": "Vaihda Salasana",
|
||||
"change_password_description": "Tämä on joko ensimmäinen kertasi kun kirjaudut järjestelmään, tai salasanasi on pyydetty vaihtamaan. Määritä uusi salasana alle.",
|
||||
"change_password_form_confirm_password": "Vahvista salasana",
|
||||
"change_password_form_description": "Hei {name},\n\nTämä on joko ensimmäinen kirjautumisesi järjestelmään tai salasanan vaihtaminen vaihtaminen on pakotettu. Ole hyvä ja syötä uusi salasana alle.",
|
||||
"change_password_form_new_password": "Uusi salasana",
|
||||
"change_password_form_password_mismatch": "Salasanat eivät täsmää",
|
||||
"change_password_form_reenter_new_password": "Uusi salasana uudelleen",
|
||||
"change_your_password": "Vaihda salasanasi",
|
||||
"changed_visibility_successfully": "Näkyvyys vaihdettu",
|
||||
"check_all": "Valitse kaikki",
|
||||
"check_corrupt_asset_backup": "Check for corrupt asset backups",
|
||||
"check_corrupt_asset_backup_button": "Perform check",
|
||||
"check_corrupt_asset_backup_description": "Run this check only over Wi-Fi and once all assets have been backed-up. The procedure might take a few minutes.",
|
||||
"check_logs": "Katso lokeja",
|
||||
"choose_matching_people_to_merge": "Valitse henkilöt joka yhdistetään",
|
||||
"city": "Kaupunki",
|
||||
@@ -469,6 +615,14 @@
|
||||
"clear_all_recent_searches": "Tyhjennä viimeisimmät haut",
|
||||
"clear_message": "Tyhjennä viesti",
|
||||
"clear_value": "Tyhjää arvo",
|
||||
"client_cert_dialog_msg_confirm": "OK",
|
||||
"client_cert_enter_password": "Enter Password",
|
||||
"client_cert_import": "Import",
|
||||
"client_cert_import_success_msg": "Client certificate is imported",
|
||||
"client_cert_invalid_msg": "Invalid certificate file or wrong password",
|
||||
"client_cert_remove_msg": "Client certificate is removed",
|
||||
"client_cert_subtitle": "Supports PKCS12 (.p12, .pfx) format only. Certificate Import/Remove is available only before login",
|
||||
"client_cert_title": "SSL Client Certificate",
|
||||
"clockwise": "Myötäpäivään",
|
||||
"close": "Sulje",
|
||||
"collapse": "Supista",
|
||||
@@ -479,6 +633,9 @@
|
||||
"comment_options": "Kommentin valinnat",
|
||||
"comments_and_likes": "Kommentit ja tykkäykset",
|
||||
"comments_are_disabled": "Kommentointi ei käytössä",
|
||||
"common_create_new_album": "Luo uusi albumi",
|
||||
"common_server_error": "Tarkista internet-yhteytesi. Varmista että palvelin on saavutettavissa ja sovellus-/palvelinversiot ovat yhteensopivia.",
|
||||
"completed": "Completed",
|
||||
"confirm": "Vahvista",
|
||||
"confirm_admin_password": "Vahvista ylläpitäjän salasana",
|
||||
"confirm_delete_shared_link": "Haluatko varmasti poistaa tämän jaetun linkin?",
|
||||
@@ -487,6 +644,15 @@
|
||||
"contain": "Mahduta",
|
||||
"context": "Konteksti",
|
||||
"continue": "Jatka",
|
||||
"control_bottom_app_bar_album_info_shared": "{} kohdetta · Jaettu",
|
||||
"control_bottom_app_bar_create_new_album": "Luo uusi albumi",
|
||||
"control_bottom_app_bar_delete_from_immich": "Poista Immichistä",
|
||||
"control_bottom_app_bar_delete_from_local": "Poista laitteelta",
|
||||
"control_bottom_app_bar_edit_location": "Muokkaa sijaintia",
|
||||
"control_bottom_app_bar_edit_time": "Muokkaa aikaa",
|
||||
"control_bottom_app_bar_share_link": "Share Link",
|
||||
"control_bottom_app_bar_share_to": "Jaa",
|
||||
"control_bottom_app_bar_trash_from_immich": "Siirrä roskakoriin",
|
||||
"copied_image_to_clipboard": "Kuva kopioitu leikepöydälle.",
|
||||
"copied_to_clipboard": "Kopioitu leikepöydälle!",
|
||||
"copy_error": "Kopiointivirhe",
|
||||
@@ -501,24 +667,34 @@
|
||||
"covers": "Kannet",
|
||||
"create": "Luo",
|
||||
"create_album": "Luo albumi",
|
||||
"create_album_page_untitled": "Nimetön",
|
||||
"create_library": "Luo uusi kirjasto",
|
||||
"create_link": "Luo linkki",
|
||||
"create_link_to_share": "Luo linkki jaettavaksi",
|
||||
"create_link_to_share_description": "Salli kaikkien linkin saaneiden nähdä valitut kuvat",
|
||||
"create_new": "CREATE NEW",
|
||||
"create_new_person": "Luo uusi henkilö",
|
||||
"create_new_person_hint": "Määritä valitut mediat uudelle henkilölle",
|
||||
"create_new_user": "Luo uusi käyttäjä",
|
||||
"create_shared_album_page_share_add_assets": "LISÄÄ KOHTEITA",
|
||||
"create_shared_album_page_share_select_photos": "Valitse kuvat",
|
||||
"create_tag": "Luo tunniste",
|
||||
"create_tag_description": "Luo uusi tunniste. Sisäkkäisiä tunnisteita varten syötä tunnisteen täydellinen polku kauttaviivat mukaan luettuna.",
|
||||
"create_user": "Luo käyttäjä",
|
||||
"created": "Luotu",
|
||||
"crop": "Crop",
|
||||
"curated_object_page_title": "Asiat",
|
||||
"current_device": "Nykyinen laite",
|
||||
"current_server_address": "Current server address",
|
||||
"custom_locale": "Muokatut maa-asetukset",
|
||||
"custom_locale_description": "Muotoile päivämäärät ja numerot perustuen alueen kieleen",
|
||||
"daily_title_text_date": "E, MMM dd",
|
||||
"daily_title_text_date_year": "E, MMM dd, yyyy",
|
||||
"dark": "Tumma",
|
||||
"date_after": "Päivämäärän jälkeen",
|
||||
"date_and_time": "Päivämäärä ja aika",
|
||||
"date_before": "Päivä ennen",
|
||||
"date_format": "E, LLL d, y • h:mm a",
|
||||
"date_of_birth_saved": "Syntymäaika tallennettu",
|
||||
"date_range": "Päivämäärän rajaus",
|
||||
"day": "Päivä",
|
||||
@@ -532,18 +708,29 @@
|
||||
"delete": "Poista",
|
||||
"delete_album": "Poista albumi",
|
||||
"delete_api_key_prompt": "Haluatko varmasti poistaa tämän API-avaimen?",
|
||||
"delete_dialog_alert": "Nämä kohteet poistetaan pysyvästi Immich:stä ja laitteeltasi",
|
||||
"delete_dialog_alert_local": "Kohteet poistetaan pysyvästi laitteelta, mutta ovat saatavilla Immich-palvelimella",
|
||||
"delete_dialog_alert_local_non_backed_up": "Joitain kohteista ei ole varmuuskopioitu Immichiin ja ne poistetaan laitteelta pysyvästi",
|
||||
"delete_dialog_alert_remote": "Kohteet poistetaan pysyvästi Immich-palvelimelta",
|
||||
"delete_dialog_ok_force": "Poista kuitenkin",
|
||||
"delete_dialog_title": "Poista pysyvästi",
|
||||
"delete_duplicates_confirmation": "Haluatko varmasti poistaa nämä kaksoiskappaleet pysyvästi?",
|
||||
"delete_key": "Poista avain",
|
||||
"delete_library": "Poista kirjasto",
|
||||
"delete_link": "Poista linkki",
|
||||
"delete_local_dialog_ok_backed_up_only": "Poista vain varmuuskopioidut",
|
||||
"delete_local_dialog_ok_force": "Poista kuitenkin",
|
||||
"delete_others": "Poista muut",
|
||||
"delete_shared_link": "Poista jaettu linkki",
|
||||
"delete_shared_link_dialog_title": "Poista jaettu linkki",
|
||||
"delete_tag": "Poista tunniste",
|
||||
"delete_tag_confirmation_prompt": "Haluatko varmasti poistaa tunnisteen {tagName}?",
|
||||
"delete_user": "Poista käyttäjä",
|
||||
"deleted_shared_link": "Jaettu linkki poistettu",
|
||||
"deletes_missing_assets": "Poistaa levyltä puuttuvat resurssit",
|
||||
"description": "Kuvaus",
|
||||
"description_input_hint_text": "Lisää kuvaus...",
|
||||
"description_input_submit_error": "Virhe kuvauksen päivittämisessä, tarkista lisätiedot lokista",
|
||||
"details": "TIEDOT",
|
||||
"direction": "Suunta",
|
||||
"disabled": "Poistettu käytöstä",
|
||||
@@ -560,12 +747,26 @@
|
||||
"documentation": "Dokumentaatio",
|
||||
"done": "Valmis",
|
||||
"download": "Lataa",
|
||||
"download_canceled": "Download canceled",
|
||||
"download_complete": "Download complete",
|
||||
"download_enqueue": "Download enqueued",
|
||||
"download_error": "Download Error",
|
||||
"download_failed": "Download failed",
|
||||
"download_filename": "file: {}",
|
||||
"download_finished": "Download finished",
|
||||
"download_include_embedded_motion_videos": "Upotetut videot",
|
||||
"download_include_embedded_motion_videos_description": "Sisällytä liikekuviin upotetut videot erillisinä tiedostoina",
|
||||
"download_notfound": "Download not found",
|
||||
"download_paused": "Download paused",
|
||||
"download_settings": "Lataukset",
|
||||
"download_settings_description": "Hallitse aineiston lataukseen liittyviä asetuksia",
|
||||
"download_started": "Download started",
|
||||
"download_sucess": "Download success",
|
||||
"download_sucess_android": "The media has been downloaded to DCIM/Immich",
|
||||
"download_waiting_to_retry": "Waiting to retry",
|
||||
"downloading": "Ladataan",
|
||||
"downloading_asset_filename": "Ladataan mediaa {filename}",
|
||||
"downloading_media": "Downloading media",
|
||||
"drop_files_to_upload": "Pudota tiedostot mihin tahansa ladataksesi ne",
|
||||
"duplicates": "Kaksoiskappaleet",
|
||||
"duplicates_description": "Selvitä jokaisen kohdalla mitkä (jos yksikään) ovat kaksoiskappaleita",
|
||||
@@ -582,6 +783,7 @@
|
||||
"edit_key": "Muokkaa avainta",
|
||||
"edit_link": "Muokkaa linkkiä",
|
||||
"edit_location": "Muokkaa sijaintia",
|
||||
"edit_location_dialog_title": "Sijainti",
|
||||
"edit_name": "Muokkaa nimeä",
|
||||
"edit_people": "Muokkaa henkilöitä",
|
||||
"edit_tag": "Muokkaa tunnistetta",
|
||||
@@ -594,13 +796,18 @@
|
||||
"editor_crop_tool_h2_aspect_ratios": "Kuvasuhteet",
|
||||
"editor_crop_tool_h2_rotation": "Rotaatio",
|
||||
"email": "Sähköposti",
|
||||
"empty_folder": "This folder is empty",
|
||||
"empty_trash": "Tyhjennä roskakori",
|
||||
"empty_trash_confirmation": "Haluatko varmasti tyhjentää roskakorin? Tämä poistaa pysyvästi kaikki tiedostot Immich:stä.\nToimintoa ei voi perua!",
|
||||
"enable": "Ota käyttöön",
|
||||
"enabled": "Käytössä",
|
||||
"end_date": "Päättymispäivä",
|
||||
"enqueued": "Enqueued",
|
||||
"enter_wifi_name": "Enter WiFi name",
|
||||
"error": "Virhe",
|
||||
"error_change_sort_album": "Failed to change album sort order",
|
||||
"error_loading_image": "Kuvan lataus ei onnistunut",
|
||||
"error_saving_image": "Error: {}",
|
||||
"error_title": "Virhe - Jotain meni pieleen",
|
||||
"errors": {
|
||||
"cannot_navigate_next_asset": "Seuraavaan mediaan ei voi siirtyä",
|
||||
@@ -729,8 +936,21 @@
|
||||
"unable_to_upload_file": "Tiedostoa ei voitu ladata"
|
||||
},
|
||||
"exif": "Exif",
|
||||
"exif_bottom_sheet_description": "Lisää kuvaus…",
|
||||
"exif_bottom_sheet_details": "TIEDOT",
|
||||
"exif_bottom_sheet_location": "SIJAINTI",
|
||||
"exif_bottom_sheet_people": "IHMISET",
|
||||
"exif_bottom_sheet_person_add_person": "Lisää nimi",
|
||||
"exif_bottom_sheet_person_age": "Age {}",
|
||||
"exif_bottom_sheet_person_age_months": "Age {} months",
|
||||
"exif_bottom_sheet_person_age_year_months": "Age 1 year, {} months",
|
||||
"exif_bottom_sheet_person_age_years": "Age {}",
|
||||
"exit_slideshow": "Poistu diaesityksestä",
|
||||
"expand_all": "Laajenna kaikki",
|
||||
"experimental_settings_new_asset_list_subtitle": "Työn alla",
|
||||
"experimental_settings_new_asset_list_title": "Ota käyttöön kokeellinen kuvaruudukko",
|
||||
"experimental_settings_subtitle": "Käyttö omalla vastuulla!",
|
||||
"experimental_settings_title": "Kokeellinen",
|
||||
"expire_after": "Umpeutuu",
|
||||
"expired": "Voimassaolo päättynyt",
|
||||
"expires_date": "Vanhenee {date}",
|
||||
@@ -741,11 +961,16 @@
|
||||
"extension": "Tiedostopääte",
|
||||
"external": "Ulkoisesta",
|
||||
"external_libraries": "Ulkoiset kirjastot",
|
||||
"external_network": "External network",
|
||||
"external_network_sheet_info": "When not on the preferred WiFi network, the app will connect to the server through the first of the below URLs it can reach, starting from top to bottom",
|
||||
"face_unassigned": "Ei määritelty",
|
||||
"failed": "Failed",
|
||||
"failed_to_load_assets": "Kohteiden lataus epäonnistui",
|
||||
"failed_to_load_folder": "Failed to load folder",
|
||||
"favorite": "Suosikki",
|
||||
"favorite_or_unfavorite_photo": "Suosikki- tai ei-suosikkikuva",
|
||||
"favorites": "Suosikit",
|
||||
"favorites_page_no_favorites": "Suosikkikohteita ei löytynyt",
|
||||
"feature_photo_updated": "Kansikuva ladattu",
|
||||
"features": "Ominaisuudet",
|
||||
"features_setting_description": "Hallitse sovelluksen ominaisuuksia",
|
||||
@@ -753,25 +978,38 @@
|
||||
"file_name_or_extension": "Tiedostonimi tai tiedostopääte",
|
||||
"filename": "Tiedostonimi",
|
||||
"filetype": "Tiedostotyyppi",
|
||||
"filter": "Filter",
|
||||
"filter_people": "Suodata henkilöt",
|
||||
"find_them_fast": "Löydä nopeasti hakemalla nimellä",
|
||||
"fix_incorrect_match": "Korjaa virheellinen osuma",
|
||||
"folder": "Folder",
|
||||
"folder_not_found": "Folder not found",
|
||||
"folders": "Kansiot",
|
||||
"folders_feature_description": "Käytetään kansionäkymää valokuvien ja videoiden selaamiseen järjestelmässä",
|
||||
"forward": "Eteenpäin",
|
||||
"general": "Yleinen",
|
||||
"get_help": "Hae apua",
|
||||
"get_wifiname_error": "Could not get Wi-Fi name. Make sure you have granted the necessary permissions and are connected to a Wi-Fi network",
|
||||
"getting_started": "Aloittaminen",
|
||||
"go_back": "Palaa",
|
||||
"go_to_folder": "Mene kansioon",
|
||||
"go_to_search": "Siirry hakuun",
|
||||
"grant_permission": "Grant permission",
|
||||
"group_albums_by": "Ryhmitä albumi...",
|
||||
"group_country": "Ryhmitä maan mukaan",
|
||||
"group_no": "Ei ryhmitystä",
|
||||
"group_owner": "Ryhmitä omistajan mukaan",
|
||||
"group_places_by": "Ryhmitä paikat...",
|
||||
"group_year": "Ryhmitä vuoden mukaan",
|
||||
"haptic_feedback_switch": "Ota haptinen palaute käyttöön",
|
||||
"haptic_feedback_title": "Haptinen palaute",
|
||||
"has_quota": "On kiintiö",
|
||||
"header_settings_add_header_tip": "Add Header",
|
||||
"header_settings_field_validator_msg": "Value cannot be empty",
|
||||
"header_settings_header_name_input": "Header name",
|
||||
"header_settings_header_value_input": "Header value",
|
||||
"headers_settings_tile_subtitle": "Define proxy headers the app should send with each network request",
|
||||
"headers_settings_tile_title": "Custom proxy headers",
|
||||
"hi_user": "Hei {name} ({email})",
|
||||
"hide_all_people": "Piilota kaikki henkilöt",
|
||||
"hide_gallery": "Piilota galleria",
|
||||
@@ -779,8 +1017,24 @@
|
||||
"hide_password": "Piilota salasana",
|
||||
"hide_person": "Piilota henkilö",
|
||||
"hide_unnamed_people": "Piilota nimeämättömät henkilöt",
|
||||
"home_page_add_to_album_conflicts": "Lisätty {added} kohdetta albumiin {album}. {failed} kohdetta on jo albumissa.",
|
||||
"home_page_add_to_album_err_local": "Paikallisten kohteiden lisääminen albumeihin ei ole mahdollista, ohitetaan",
|
||||
"home_page_add_to_album_success": "Lisätty {added} kohdetta albumiin {album}.",
|
||||
"home_page_album_err_partner": "Kumppanin kohteita ei voi vielä lisätä albumiin. Hypätään yli",
|
||||
"home_page_archive_err_local": "Paikallisten kohteiden arkistointi ei ole mahdollista, ohitetaan",
|
||||
"home_page_archive_err_partner": "Kumppanin kohteita ei voi arkistoida. Hypätään yli",
|
||||
"home_page_building_timeline": "Rakennetaan aikajanaa",
|
||||
"home_page_delete_err_partner": "Kumppanin kohteita ei voi poistaa.Hypätään yli",
|
||||
"home_page_delete_remote_err_local": "Paikallisia kohteita etäkohdevalintojen joukossa, ohitetaan",
|
||||
"home_page_favorite_err_local": "Paikallisten kohteiden lisääminen suosikkeihin ei ole mahdollista, ohitetaan",
|
||||
"home_page_favorite_err_partner": "Kumppanin kohteita ei voi vielä merkitä suosikiksi. Hypätään yli",
|
||||
"home_page_first_time_notice": "Jos käytät sovellusta ensimmäistä kertaa, muista valita varmuuskopioitavat albumi(t), jotta aikajanalla voi olla kuvia ja videoita.",
|
||||
"home_page_share_err_local": "Paikallisia kohteita ei voitu jakaa linkkien avulla. Hypätään yli",
|
||||
"home_page_upload_err_limit": "Voit lähettää palvelimelle enintään 30 kohdetta kerrallaan, ohitetaan",
|
||||
"host": "Isäntä",
|
||||
"hour": "Tunti",
|
||||
"ignore_icloud_photos": "Ignore iCloud photos",
|
||||
"ignore_icloud_photos_description": "Photos that are stored on iCloud will not be uploaded to the Immich server",
|
||||
"image": "Kuva",
|
||||
"image_alt_text_date": "{isVideo, select, true {Video} other {Kuva}} otettu {date}",
|
||||
"image_alt_text_date_1_person": "{isVideo, select, true {Video} other {Kuva}} otettu {person1} kanssa {date}",
|
||||
@@ -792,6 +1046,10 @@
|
||||
"image_alt_text_date_place_2_people": "{isVideo, select, true {Video} other {Kuva}} otettu {city}ssä, {country}ssä {person1}n ja {person2}n kanssa {date}",
|
||||
"image_alt_text_date_place_3_people": "{isVideo, select, true {Video} other {Kuva}} otettu {city}ssä, {country}ssä {person1}n, {person2}n ja {person3}n kanssa {date}",
|
||||
"image_alt_text_date_place_4_or_more_people": "{isVideo, select, true {Video} other {Kuva}} otettu {city}ssä, {country}ssä {person1}n, {person2}n ja {additionalCount, number} muun kanssa {date}",
|
||||
"image_saved_successfully": "Image saved",
|
||||
"image_viewer_page_state_provider_download_started": "Lataaminen aloitettu",
|
||||
"image_viewer_page_state_provider_download_success": "Lataus onnistui",
|
||||
"image_viewer_page_state_provider_share_error": "Jakovirhe",
|
||||
"immich_logo": "Immich-logo",
|
||||
"immich_web_interface": "Immich-verkkokäyttöliittymä",
|
||||
"import_from_json": "Tuo JSON-tiedostosta",
|
||||
@@ -810,6 +1068,8 @@
|
||||
"night_at_midnight": "Joka yö keskiyöllä",
|
||||
"night_at_twoam": "Joka yö klo 02:00"
|
||||
},
|
||||
"invalid_date": "Invalid date",
|
||||
"invalid_date_format": "Invalid date format",
|
||||
"invite_people": "Kutsu ihmisiä",
|
||||
"invite_to_album": "Kutsu albumiin",
|
||||
"items_count": "{count, plural, one {# kpl} other {# kpl}}",
|
||||
@@ -829,6 +1089,12 @@
|
||||
"level": "Taso",
|
||||
"library": "Kirjasto",
|
||||
"library_options": "Kirjastovaihtoehdot",
|
||||
"library_page_device_albums": "Laitteen albumit",
|
||||
"library_page_new_album": "Uusi albumi",
|
||||
"library_page_sort_asset_count": "Kohteiden lukumäärä",
|
||||
"library_page_sort_created": "Viimeisin luotu",
|
||||
"library_page_sort_last_modified": "Viimeksi muokattu",
|
||||
"library_page_sort_title": "Albumin otsikko",
|
||||
"light": "Vaalea",
|
||||
"like_deleted": "Tykkäys poistettu",
|
||||
"link_motion_video": "Linkitä liikevideo",
|
||||
@@ -838,12 +1104,42 @@
|
||||
"list": "Lista",
|
||||
"loading": "Ladataan",
|
||||
"loading_search_results_failed": "Hakutulosten lataaminen epäonnistui",
|
||||
"local_network": "Local network",
|
||||
"local_network_sheet_info": "The app will connect to the server through this URL when using the specified Wi-Fi network",
|
||||
"location_permission": "Location permission",
|
||||
"location_permission_content": "In order to use the auto-switching feature, Immich needs precise location permission so it can read the current WiFi network's name",
|
||||
"location_picker_choose_on_map": "Valitse kartalta",
|
||||
"location_picker_latitude_error": "Lisää kelvollinen leveysaste",
|
||||
"location_picker_latitude_hint": "Syötä leveysaste",
|
||||
"location_picker_longitude_error": "Lisää kelvollinen pituusaste",
|
||||
"location_picker_longitude_hint": "Syötä pituusaste",
|
||||
"log_out": "Kirjaudu ulos",
|
||||
"log_out_all_devices": "Kirjaudu ulos kaikilta laitteilta",
|
||||
"logged_out_all_devices": "Kaikki laitteet kirjattu ulos",
|
||||
"logged_out_device": "Laite kirjattu ulos",
|
||||
"login": "Kirjaudu",
|
||||
"login_disabled": "Kirjautuminen on poistettu käytöstä",
|
||||
"login_form_api_exception": "API-virhe. Tarkista palvelimen URL-osoite ja yritä uudelleen.",
|
||||
"login_form_back_button_text": "Takaisin",
|
||||
"login_form_email_hint": "sahkopostisi@esimerkki.fi",
|
||||
"login_form_endpoint_hint": "http://palvelimesi-osoite:portti",
|
||||
"login_form_endpoint_url": "Palvelimen URL",
|
||||
"login_form_err_http": "Lisää http:// tai https://",
|
||||
"login_form_err_invalid_email": "Virheellinen sähköpostiosoite",
|
||||
"login_form_err_invalid_url": "Virheellinen URL",
|
||||
"login_form_err_leading_whitespace": "Alussa välilyönti",
|
||||
"login_form_err_trailing_whitespace": "Lopussa välilyönti",
|
||||
"login_form_failed_get_oauth_server_config": "Virhe kirjauduttaessa OAuth:lla, tarkista palvelimen URL",
|
||||
"login_form_failed_get_oauth_server_disable": "OAuth-ominaisuus ei ole käytössä tällä palvelimella",
|
||||
"login_form_failed_login": "Virhe kirjautumisessa. Tarkista palvelimen URL, sähköpostiosoite ja salasana.",
|
||||
"login_form_handshake_exception": "Tapahtui poikkeus kättelyssä palvelimen kanssa. Kytke päälle self-signed -sertifikaattituki asetuksista, mikäli käytät self-signed -sertifikaatteja.",
|
||||
"login_form_password_hint": "salasana",
|
||||
"login_form_save_login": "Pysy kirjautuneena",
|
||||
"login_form_server_empty": "Syötä palvelimen URL-osoite.",
|
||||
"login_form_server_error": "Palvelimeen ei saatu yhteyttä.",
|
||||
"login_has_been_disabled": "Kirjautuminen on otettu pois käytöstä.",
|
||||
"login_password_changed_error": "Salasanan päivityksessä tapahtui virhe",
|
||||
"login_password_changed_success": "Salasan päivitetty onnistuneesti",
|
||||
"logout_all_device_confirmation": "Haluatko varmasti kirjautua ulos kaikilta laitteilta?",
|
||||
"logout_this_device_confirmation": "Haluatko varmasti kirjautua ulos näiltä laitteilta?",
|
||||
"longitude": "Pituusaste",
|
||||
@@ -860,13 +1156,40 @@
|
||||
"manage_your_devices": "Hallitse sisäänkirjautuneita laitteitasi",
|
||||
"manage_your_oauth_connection": "Hallitse OAuth-yhteyttäsi",
|
||||
"map": "Kartta",
|
||||
"map_assets_in_bound": "{} kuva",
|
||||
"map_assets_in_bounds": "{} kuvaa",
|
||||
"map_cannot_get_user_location": "Käyttäjän sijaintia ei voitu määrittää",
|
||||
"map_location_dialog_yes": "Kyllä",
|
||||
"map_location_picker_page_use_location": "Käytä tätä sijaintia",
|
||||
"map_location_service_disabled_content": "Paikannuspalvelun pitää olla kytkettynä päälle, jotta nykyisen sijaintisi kohteita voidaan näyttää. Haluatko kytkeä sen päälle nyt?",
|
||||
"map_location_service_disabled_title": "Paikannuspalvelu pois päältä",
|
||||
"map_marker_for_images": "Karttamarkerointi kuville, jotka on otettu kaupungissa {city}, maassa {country}",
|
||||
"map_marker_with_image": "Karttamarkerointi kuvalla",
|
||||
"map_no_assets_in_bounds": "Ei kuvia tällä alueella",
|
||||
"map_no_location_permission_content": "Paikannuslupa tarvitaan, jotta nykyisen sijainnin kohteita voidaan näyttää. Haluatko sallia pääsyn sijaintiin?",
|
||||
"map_no_location_permission_title": "Paikannuslupa estetty",
|
||||
"map_settings": "Kartta-asetukset",
|
||||
"map_settings_dark_mode": "Tumma tila",
|
||||
"map_settings_date_range_option_day": "Viimeiset 24 tuntia",
|
||||
"map_settings_date_range_option_days": "Viimeiset {} päivää",
|
||||
"map_settings_date_range_option_year": "Viimeisin vuosi",
|
||||
"map_settings_date_range_option_years": "Viimeiset {} vuotta",
|
||||
"map_settings_dialog_title": "Kartta-asetukset",
|
||||
"map_settings_include_show_archived": "Sisällytä arkistoidut",
|
||||
"map_settings_include_show_partners": "Sisällytä kumppanit",
|
||||
"map_settings_only_show_favorites": "Näytä vain suosikit",
|
||||
"map_settings_theme_settings": "Kartan teema",
|
||||
"map_zoom_to_see_photos": "Tarkenna nähdäksesi kuvat",
|
||||
"matches": "Osumia",
|
||||
"media_type": "Median tyyppi",
|
||||
"memories": "Muistoja",
|
||||
"memories_all_caught_up": "Kaikki ajan tasalla",
|
||||
"memories_check_back_tomorrow": "Palaa huomenna nähdäskesi lisää muistoja",
|
||||
"memories_setting_description": "Hallitse mitä näet muistoissasi",
|
||||
"memories_start_over": "Aloita alusta",
|
||||
"memories_swipe_to_close": "Pyyhkäise ylös sulkeaksesi",
|
||||
"memories_year_ago": "A year ago",
|
||||
"memories_years_ago": "{} years ago",
|
||||
"memory": "Muisto",
|
||||
"memory_lane_title": "Muistojen polku {title}",
|
||||
"menu": "Valikko",
|
||||
@@ -881,11 +1204,16 @@
|
||||
"missing": "Puuttuu",
|
||||
"model": "Malli",
|
||||
"month": "Kuukauden mukaan",
|
||||
"monthly_title_text_date_format": "MMMM y",
|
||||
"more": "Enemmän",
|
||||
"moved_to_trash": "Siirretty roskakoriin",
|
||||
"multiselect_grid_edit_date_time_err_read_only": "Vain luku -tilassa olevien kohteiden päivämäärää ei voitu muokata, ohitetaan",
|
||||
"multiselect_grid_edit_gps_err_read_only": "Vain luku-tilassa olevien kohteiden sijantitietoja ei voitu muokata, ohitetaan",
|
||||
"my_albums": "Albumini",
|
||||
"name": "Nimi",
|
||||
"name_or_nickname": "Nimi tai lempinimi",
|
||||
"networking_settings": "Networking",
|
||||
"networking_subtitle": "Manage the server endpoint settings",
|
||||
"never": "ei koskaan",
|
||||
"new_album": "Uusi Albumi",
|
||||
"new_api_key": "Uusi API-avain",
|
||||
@@ -902,6 +1230,7 @@
|
||||
"no_albums_yet": "Näyttää siltä, ettei sinulla ole vielä yhtään albumia.",
|
||||
"no_archived_assets_message": "Arkistoi kuvia ja videoita piilottaaksesi ne kuvat näkymästä",
|
||||
"no_assets_message": "NAPAUTA LATAAKSESI ENSIMMÄISEN KUVASI",
|
||||
"no_assets_to_show": "Ei näytettäviä kohteita",
|
||||
"no_duplicates_found": "Kaksoiskappaleita ei löytynyt.",
|
||||
"no_exif_info_available": "EXIF-tietoa ei saatavilla",
|
||||
"no_explore_results_message": "Lataa lisää kuvia tutkiaksesi kokoelmaasi.",
|
||||
@@ -913,9 +1242,13 @@
|
||||
"no_results_description": "Kokeile synonyymiä tai yleisempää avainsanaa",
|
||||
"no_shared_albums_message": "Luo albumi, jotta voit jakaa kuvia ja videoita toisille",
|
||||
"not_in_any_album": "Ei yhdessäkään albumissa",
|
||||
"not_selected": "Not selected",
|
||||
"note_apply_storage_label_to_previously_uploaded assets": "Huom: Jotta voit soveltaa tallennustunnistetta aiemmin ladattuihin kohteisiin, suorita",
|
||||
"note_unlimited_quota": "Huomio: Syötä 0 rajoittamatonta kiintiötä varten",
|
||||
"notes": "Muistiinpanot",
|
||||
"notification_permission_dialog_content": "Ottaaksesi ilmoitukset käyttöön, siirry asetuksiin ja valitse 'salli'.",
|
||||
"notification_permission_list_tile_content": "Myönnä käyttöoikeus ottaaksesi ilmoitukset käyttöön.",
|
||||
"notification_permission_list_tile_enable_button": "Ota ilmoitukset käyttöön",
|
||||
"notification_permission_list_tile_title": "Ilmoitusten käyttöoikeus",
|
||||
"notification_toggle_setting_description": "Ota sähköposti-ilmoitukset käyttöön",
|
||||
"notifications": "Ilmoitukset",
|
||||
"notifications_setting_description": "Hallitse ilmoituksia",
|
||||
@@ -926,6 +1259,7 @@
|
||||
"offline_paths_description": "Nämä tulokset voivat johtua tiedostojen manuaalisesta poistamisesta, jotka eivät ole osa ulkoista kirjastoa.",
|
||||
"ok": "Ok",
|
||||
"oldest_first": "Vanhin ensin",
|
||||
"on_this_device": "On this device",
|
||||
"onboarding": "Käyttöönotto",
|
||||
"onboarding_privacy_description": "Seuraavat (valinnaiset) ominaisuudet perustuvat ulkoisiin palveluihin, ja ne voidaan poistaa käytöstä milloin tahansa hallinta asetuksista.",
|
||||
"onboarding_theme_description": "Valitse väriteema istunnollesi. Voit muuttaa tämän myöhemmin asetuksistasi.",
|
||||
@@ -949,6 +1283,14 @@
|
||||
"partner_can_access": "{partner} voi päästä",
|
||||
"partner_can_access_assets": "Kaikki valokuvasi ja videosi, lukuun ottamatta arkistoituja ja poistettuja",
|
||||
"partner_can_access_location": "Sijainti, jossa kuvasi on otettu",
|
||||
"partner_list_user_photos": "Käyttäjän {user} kuvat",
|
||||
"partner_list_view_all": "Näytä kaikki",
|
||||
"partner_page_empty_message": "Kuviasi ei ole vielä jaettu kenenkään kumppanin kanssa.",
|
||||
"partner_page_no_more_users": "Ei enempää käyttäjiä lisättäväksi",
|
||||
"partner_page_partner_add_failed": "Kumppanin lisääminen epäonnistui",
|
||||
"partner_page_select_partner": "Valitse kumppani",
|
||||
"partner_page_shared_to_title": "Jaettu henkilöille",
|
||||
"partner_page_stop_sharing_content": "{} ei voi enää käyttää kuviasi.",
|
||||
"partner_sharing": "Kumppanijako",
|
||||
"partners": "Kumppanit",
|
||||
"password": "Salasana",
|
||||
@@ -977,6 +1319,14 @@
|
||||
"permanently_delete_assets_prompt": "Oletko varma, että haluat poistaa pysyvästi {count, plural, one {tämän kohteen?} other {nämä <b>#</b> kohteet?}} Tämä poistaa myös {count, plural, one {sen sen} other {ne niiden}} albumista.",
|
||||
"permanently_deleted_asset": "Media poistettu pysyvästi",
|
||||
"permanently_deleted_assets_count": "{count, plural, one {# media} other {# mediaa}} poistettu pysyvästi",
|
||||
"permission_onboarding_back": "Takaisin",
|
||||
"permission_onboarding_continue_anyway": "Jatka silti",
|
||||
"permission_onboarding_get_started": "Aloittaminen",
|
||||
"permission_onboarding_go_to_settings": "Siirry asetuksiin",
|
||||
"permission_onboarding_permission_denied": "Kielletty käyttöoikeus. Käyttääksesi Immichiä, myönnä oikeus kuviin ja videoihin asetuksista.",
|
||||
"permission_onboarding_permission_granted": "Käyttöoikeus myönnetty! Kaikki valmista.",
|
||||
"permission_onboarding_permission_limited": "Rajoitettu käyttöoikeus. Salliaksesi Immichin varmuuskopioida ja hallita koko kuvakirjastoasi, myönnä oikeus kuviin ja videoihin asetuksista.",
|
||||
"permission_onboarding_request": "Immich vaatii käyttöoikeuden kuvien ja videoiden käyttämiseen.",
|
||||
"person": "Henkilö",
|
||||
"person_hidden": "{name}{hidden, select, true { (piilotettu)} other {}}",
|
||||
"photo_shared_all_users": "Näyttää että olet jakanut kuvasi kaikkien käyttäjien kanssa, tai sinulla ei ole käyttäjää kenelle jakaa.",
|
||||
@@ -992,6 +1342,8 @@
|
||||
"play_motion_photo": "Toista Liikekuva",
|
||||
"play_or_pause_video": "Toista tai keskeytä video",
|
||||
"port": "Portti",
|
||||
"preferences_settings_subtitle": "Manage the app's preferences",
|
||||
"preferences_settings_title": "Asetukset",
|
||||
"preset": "Asetus",
|
||||
"preview": "Esikatselu",
|
||||
"previous": "Edellinen",
|
||||
@@ -999,6 +1351,13 @@
|
||||
"previous_or_next_photo": "Edellinen tai seuraava kuva",
|
||||
"primary": "Ensisijainen",
|
||||
"privacy": "Yksityisyys",
|
||||
"profile_drawer_app_logs": "Lokit",
|
||||
"profile_drawer_client_out_of_date_major": "Sovelluksen mobiiliversio on vanhentunut. Päivitä viimeisimpään merkittävään versioon.",
|
||||
"profile_drawer_client_out_of_date_minor": "Sovelluksen mobiiliversio on vanhentunut. Päivitä viimeisimpään versioon.",
|
||||
"profile_drawer_client_server_up_to_date": "Asiakassovellus ja palvelin ovat ajan tasalla",
|
||||
"profile_drawer_github": "GitHub",
|
||||
"profile_drawer_server_out_of_date_major": "Palvelimen ohjelmistoversio on vanhentunut. Päivitä viimeisimpään merkittävään versioon.",
|
||||
"profile_drawer_server_out_of_date_minor": "Palvelimen ohjelmistoversio on vanhentunut. Päivitä viimeisimpään versioon.",
|
||||
"profile_image_of_user": "Käyttäjän {user} profiilikuva",
|
||||
"profile_picture_set": "Profiilikuva asetettu.",
|
||||
"public_album": "Julkinen albumi",
|
||||
@@ -1048,6 +1407,8 @@
|
||||
"recent": "Viimeisin",
|
||||
"recent-albums": "Viimeisimmät albumit",
|
||||
"recent_searches": "Edelliset haut",
|
||||
"recently_added": "Recently added",
|
||||
"recently_added_page_title": "Viimeksi lisätyt",
|
||||
"refresh": "Päivitä",
|
||||
"refresh_encoded_videos": "Päivitä enkoodatut videot",
|
||||
"refresh_faces": "Päivitä kasvot",
|
||||
@@ -1099,10 +1460,12 @@
|
||||
"role_editor": "Editori",
|
||||
"role_viewer": "Toistin",
|
||||
"save": "Tallenna",
|
||||
"save_to_gallery": "Save to gallery",
|
||||
"saved_api_key": "API-avain tallennettu",
|
||||
"saved_profile": "Profiili tallennettu",
|
||||
"saved_settings": "Asetukset tallennettu",
|
||||
"say_something": "Sano jotain",
|
||||
"scaffold_body_error_occurred": "Tapahtui virhe",
|
||||
"scan_all_libraries": "Skannaa kaikki kirjastot",
|
||||
"scan_library": "Skannaa",
|
||||
"scan_settings": "Skannausasetukset",
|
||||
@@ -1117,14 +1480,43 @@
|
||||
"search_camera_model": "Etsi kameramallia...",
|
||||
"search_city": "Etsi kaupunkia...",
|
||||
"search_country": "Etsi maata...",
|
||||
"search_filter_apply": "Käytä",
|
||||
"search_filter_camera_title": "Select camera type",
|
||||
"search_filter_date": "Date",
|
||||
"search_filter_date_interval": "{start} to {end}",
|
||||
"search_filter_date_title": "Select a date range",
|
||||
"search_filter_display_option_not_in_album": "Ei kuulu albumiin",
|
||||
"search_filter_display_options": "Display Options",
|
||||
"search_filter_filename": "Search by file name",
|
||||
"search_filter_location": "Location",
|
||||
"search_filter_location_title": "Select location",
|
||||
"search_filter_media_type": "Media Type",
|
||||
"search_filter_media_type_title": "Select media type",
|
||||
"search_filter_people_title": "Select people",
|
||||
"search_for_existing_person": "Etsi olemassa olevaa henkilöä",
|
||||
"search_no_more_result": "No more results",
|
||||
"search_no_people": "Ei henkilöitä",
|
||||
"search_no_people_named": "Ei \"{name}\" nimisiä henkilöitä",
|
||||
"search_no_result": "No results found, try a different search term or combination",
|
||||
"search_options": "Hakuvaihtoehdot",
|
||||
"search_page_categories": "Kategoriat",
|
||||
"search_page_motion_photos": "Liikekuvat",
|
||||
"search_page_no_objects": "Objektitietoja ei ole saatavilla",
|
||||
"search_page_no_places": "Paikkatietoja ei ole saatavilla",
|
||||
"search_page_screenshots": "Näyttökuvat",
|
||||
"search_page_search_photos_videos": "Search for your photos and videos",
|
||||
"search_page_selfies": "Selfiet",
|
||||
"search_page_things": "Asiat",
|
||||
"search_page_view_all_button": "Näytä kaikki",
|
||||
"search_page_your_activity": "Toimintasi",
|
||||
"search_page_your_map": "Sinun karttasi",
|
||||
"search_people": "Etsi ihmisiä",
|
||||
"search_places": "Etsi paikkoja",
|
||||
"search_result_page_new_search_hint": "Uusi haku",
|
||||
"search_settings": "Hakuasetukset",
|
||||
"search_state": "Etsi tilaa...",
|
||||
"search_suggestion_list_smart_search_hint_1": "Älykäs haku on oletuksena käytössä. Käytä metatietojen etsimiseen syntaksia",
|
||||
"search_suggestion_list_smart_search_hint_2": "m:hakusana",
|
||||
"search_tags": "Etsi tunnisteita...",
|
||||
"search_timezone": "Etsi aikavyöhyke...",
|
||||
"search_type": "Etsinnän tyyppi",
|
||||
@@ -1144,10 +1536,14 @@
|
||||
"select_new_face": "Valitse uudet kasvot",
|
||||
"select_photos": "Valitse kuvat",
|
||||
"select_trash_all": "Valitse kaikki roskakoriin",
|
||||
"select_user_for_sharing_page_err_album": "Albumin luonti epäonnistui",
|
||||
"selected": "Valittu",
|
||||
"selected_count": "{count, plural, other {# valittu}}",
|
||||
"send_message": "Lähetä viesti",
|
||||
"send_welcome_email": "Lähetä tervetuloviesti",
|
||||
"server_endpoint": "Server Endpoint",
|
||||
"server_info_box_app_version": "Sovelluksen versio",
|
||||
"server_info_box_server_url": "Palvelimen URL-osoite",
|
||||
"server_offline": "Palvelin Offline-tilassa",
|
||||
"server_online": "Palvelin Online-tilassa",
|
||||
"server_stats": "Palvelimen tilastot",
|
||||
@@ -1159,21 +1555,90 @@
|
||||
"set_date_of_birth": "Aseta syntymäaika",
|
||||
"set_profile_picture": "Aseta profiilikuva",
|
||||
"set_slideshow_to_fullscreen": "Näytä diaesitys koko ruudulla",
|
||||
"setting_image_viewer_help": "Sovellus lataa ensin pienen esikatselukuvan, toisena keskitarkkuuksisen kuvan (jos käytössä) ja kolmantena alkuperäisen täysitarkkuuksisen kuvan (jos käytössä)",
|
||||
"setting_image_viewer_original_subtitle": "Ota käyttöön ladataksesi alkuperäinen täysitarkkuuksinen kuva (suuri!). Poista käytöstä vähentääksesi datan käyttöä (sekä verkossa että laitteen välimuistissa).",
|
||||
"setting_image_viewer_original_title": "Lataa alkuperäinen kuva",
|
||||
"setting_image_viewer_preview_subtitle": "Ota käyttöön ladataksesi keskitarkkuuksinen kuva. Poista käytöstä ladataksesi alkuperäinen kuva tai käyttääksesi vain esikatselukuvaa.",
|
||||
"setting_image_viewer_preview_title": "Lataa esikatselukuva",
|
||||
"setting_image_viewer_title": "Kuvat",
|
||||
"setting_languages_apply": "Käytä",
|
||||
"setting_languages_subtitle": "Change the app's language",
|
||||
"setting_languages_title": "Kieli",
|
||||
"setting_notifications_notify_failures_grace_period": "Ilmoita taustavarmuuskopioinnin epäonnistumisista: {}",
|
||||
"setting_notifications_notify_hours": "{} tunnin välein",
|
||||
"setting_notifications_notify_immediately": "heti",
|
||||
"setting_notifications_notify_minutes": "{} minuutin välein",
|
||||
"setting_notifications_notify_never": "ei koskaan",
|
||||
"setting_notifications_notify_seconds": "{} sekuntia",
|
||||
"setting_notifications_single_progress_subtitle": "Yksityiskohtainen tieto palvelimelle lähettämisen edistymisestä kohteittain",
|
||||
"setting_notifications_single_progress_title": "Näytä taustavarmuuskopioinnin eidstminen",
|
||||
"setting_notifications_subtitle": "Ilmoitusasetusten määrittely",
|
||||
"setting_notifications_total_progress_subtitle": "Lähetyksen yleinen edistyminen (kohteita lähetetty/yhteensä)",
|
||||
"setting_notifications_total_progress_title": "Näytä taustavarmuuskopioinnin kokonaisedistyminen",
|
||||
"setting_video_viewer_looping_title": "Looping",
|
||||
"setting_video_viewer_original_video_subtitle": "When streaming a video from the server, play the original even when a transcode is available. May lead to buffering. Videos available locally are played in original quality regardless of this setting.",
|
||||
"setting_video_viewer_original_video_title": "Force original video",
|
||||
"settings": "Asetukset",
|
||||
"settings_require_restart": "Käynnistä Immich uudelleen ottaaksesti tämän asetuksen käyttöön",
|
||||
"settings_saved": "Asetukset tallennettu",
|
||||
"share": "Jaa",
|
||||
"share_add_photos": "Lisää kuvia",
|
||||
"share_assets_selected": "{} valittu",
|
||||
"share_dialog_preparing": "Valmistellaan...",
|
||||
"shared": "Jaettu",
|
||||
"shared_album_activities_input_disable": "Kommentointi on kytketty pois päältä",
|
||||
"shared_album_activity_remove_content": "Haluatko poistaa tämän aktiviteetin?",
|
||||
"shared_album_activity_remove_title": "Poista aktiviteetti",
|
||||
"shared_album_section_people_action_error": "Virhe poistuttaessa/poistaessa kohdetta albumista",
|
||||
"shared_album_section_people_action_leave": "Poista käyttäjä albumista",
|
||||
"shared_album_section_people_action_remove_user": "Poista käyttäjä albumista",
|
||||
"shared_album_section_people_title": "HENKILÖT",
|
||||
"shared_by": "Jakanut",
|
||||
"shared_by_user": "Käyttäjän {user} jakama",
|
||||
"shared_by_you": "Sinun jakamasi",
|
||||
"shared_from_partner": "Kumppanin {partner} kuvia",
|
||||
"shared_intent_upload_button_progress_text": "{} / {} Uploaded",
|
||||
"shared_link_app_bar_title": "Jaetut linkit",
|
||||
"shared_link_clipboard_copied_massage": "Kopioitu leikepöydältä",
|
||||
"shared_link_clipboard_text": "Linkki: {}\nSalasana: {}",
|
||||
"shared_link_create_error": "Jaetun linkin luomisessa tapahtui virhe",
|
||||
"shared_link_edit_description_hint": "Lisää jaon kuvaus",
|
||||
"shared_link_edit_expire_after_option_day": "1 päivä",
|
||||
"shared_link_edit_expire_after_option_days": "{} päivää",
|
||||
"shared_link_edit_expire_after_option_hour": "1 tunti",
|
||||
"shared_link_edit_expire_after_option_hours": "{} tuntia",
|
||||
"shared_link_edit_expire_after_option_minute": "1 minuutti",
|
||||
"shared_link_edit_expire_after_option_minutes": "{} minuuttia",
|
||||
"shared_link_edit_expire_after_option_months": "{} kuukautta",
|
||||
"shared_link_edit_expire_after_option_year": "{} vuosi",
|
||||
"shared_link_edit_password_hint": "Syötä jaon salasana",
|
||||
"shared_link_edit_submit_button": "Päivitä linkki",
|
||||
"shared_link_error_server_url_fetch": "Palvelimen URL-osoitetta ei voitu hakea",
|
||||
"shared_link_expires_day": "Voimassaolo päättyy {} päivän kuluttua",
|
||||
"shared_link_expires_days": "Voimassaolo päättyy {} päivän kuluttua",
|
||||
"shared_link_expires_hour": "Voimassaolo päättyy {} tunnin kuluttua",
|
||||
"shared_link_expires_hours": "Voimassaolo päättyy {} tunnin kuluttua",
|
||||
"shared_link_expires_minute": "Voimassaolo päättyy {} minuutin kuluttua",
|
||||
"shared_link_expires_minutes": "Voimassaolo päättyy {} minuutin kuluttua",
|
||||
"shared_link_expires_never": "Voimassaolo päättyy ∞",
|
||||
"shared_link_expires_second": "Voimassaolo päättyy {} sekunnin kuluttua",
|
||||
"shared_link_expires_seconds": "Voimassaolo päättyy {} sekunnin kuluttua",
|
||||
"shared_link_individual_shared": "Individual shared",
|
||||
"shared_link_info_chip_metadata": "EXIF",
|
||||
"shared_link_manage_links": "Hallitse jaettuja linkkejä",
|
||||
"shared_link_options": "Jaetun linkin vaihtoehdot",
|
||||
"shared_links": "Jaetut linkit",
|
||||
"shared_photos_and_videos_count": "{assetCount, plural, other {# jaettua kuvaa ja videota.}}",
|
||||
"shared_with_me": "Shared with me",
|
||||
"shared_with_partner": "Jaa kumppanin {partner} kanssa",
|
||||
"sharing": "Jakaminen",
|
||||
"sharing_enter_password": "Nähdäksesi sivun sinun tulee antaa salasana.",
|
||||
"sharing_page_album": "Jaetut albumit",
|
||||
"sharing_page_description": "Luo jaettuja albumeja jakaaksesi kuvia ja videoita läheisillesi.",
|
||||
"sharing_page_empty_list": "TYHJÄ LISTA",
|
||||
"sharing_sidebar_description": "Näytä jakamislinkki sivupalkissa",
|
||||
"sharing_silver_appbar_create_shared_album": "Luo jaettu albumi",
|
||||
"sharing_silver_appbar_share_partner": "Jaa kumppanille",
|
||||
"shift_to_permanent_delete": "Paina ⇧ poistaaksesi median pysyvästi",
|
||||
"show_album_options": "Näytä albumin asetukset",
|
||||
"show_albums": "Näytä albumit",
|
||||
@@ -1239,6 +1704,9 @@
|
||||
"support_third_party_description": "Immich-asennuksesi on pakattu kolmannen osapuolen toimesta. Kohtaamasi ongelmat saattavat johtua tästä paketista, joten ilmoita niistä ensisijaisesti heille alla olevien linkkien kautta.",
|
||||
"swap_merge_direction": "Käännä yhdistämissuunta",
|
||||
"sync": "Synkronoi",
|
||||
"sync_albums": "Sync albums",
|
||||
"sync_albums_manual_subtitle": "Sync all uploaded videos and photos to the selected backup albums",
|
||||
"sync_upload_album_setting_subtitle": "Create and upload your photos and videos to the selected albums on Immich",
|
||||
"tag": "Lisää tunniste",
|
||||
"tag_assets": "Lisää tunnisteita",
|
||||
"tag_created": "Luotu tunniste: {tag}",
|
||||
@@ -1251,6 +1719,19 @@
|
||||
"theme": "Teema",
|
||||
"theme_selection": "Teeman valinta",
|
||||
"theme_selection_description": "Aseta vaalea tai tumma tila automaattisesti perustuen selaimesi asetuksiin",
|
||||
"theme_setting_asset_list_storage_indicator_title": "Näytä tallennustilan ilmaisin kohteiden kuvakkeissa",
|
||||
"theme_setting_asset_list_tiles_per_row_title": "Kohteiden määrä rivillä ({})",
|
||||
"theme_setting_colorful_interface_subtitle": "Apply primary color to background surfaces.",
|
||||
"theme_setting_colorful_interface_title": "Colorful interface",
|
||||
"theme_setting_image_viewer_quality_subtitle": "Säädä kuvien katselun laatua",
|
||||
"theme_setting_image_viewer_quality_title": "Kuvien katseluohjelman laatu",
|
||||
"theme_setting_primary_color_subtitle": "Pick a color for primary actions and accents.",
|
||||
"theme_setting_primary_color_title": "Primary color",
|
||||
"theme_setting_system_primary_color_title": "Use system color",
|
||||
"theme_setting_system_theme_switch": "Automaattinen (seuraa järjestelmän asetusta)",
|
||||
"theme_setting_theme_subtitle": "Valitse sovelluksen teema-asetukset",
|
||||
"theme_setting_three_stage_loading_subtitle": "Kolmivaiheinen lataaminen saattaa parantaa latauksen suorituskykyä, mutta lisää kaistankäyttöä huomattavasti.",
|
||||
"theme_setting_three_stage_loading_title": "Ota kolmivaiheinen lataus käyttöön",
|
||||
"they_will_be_merged_together": "Nämä tullaan yhdistämään",
|
||||
"third_party_resources": "Kolmannen osapuolen resurssit",
|
||||
"time_based_memories": "Aikaan perustuvat muistot",
|
||||
@@ -1270,7 +1751,15 @@
|
||||
"trash_all": "Vie kaikki roskakoriin",
|
||||
"trash_count": "Roskakori {count, number}",
|
||||
"trash_delete_asset": "Poista / vie roskakoriin",
|
||||
"trash_emptied": "Emptied trash",
|
||||
"trash_no_results_message": "Roskakorissa olevat kuvat ja videot näytetään täällä.",
|
||||
"trash_page_delete_all": "Poista kaikki",
|
||||
"trash_page_empty_trash_dialog_content": "Haluatko poistaa roskakoriin siirretyt kohteet? Kohteet poistetaan lopullisesti Immich:sta.",
|
||||
"trash_page_info": "Roskakoriin siirretyt kohteet poistetaan lopullisesti {} päivän kuluttua",
|
||||
"trash_page_no_assets": "Ei poistettuja kohteita",
|
||||
"trash_page_restore_all": "Palauta kaikki",
|
||||
"trash_page_select_assets_btn": "Valitse kohteet",
|
||||
"trash_page_title": "Roskakori",
|
||||
"trashed_items_will_be_permanently_deleted_after": "Roskakorin kohteet poistetaan pysyvästi {days, plural, one {# päivän} other {# päivän}} päästä.",
|
||||
"type": "Tyyppi",
|
||||
"unarchive": "Palauta arkistosta",
|
||||
@@ -1297,6 +1786,8 @@
|
||||
"updated_password": "Salasana päivitetty",
|
||||
"upload": "Siirrä palvelimelle",
|
||||
"upload_concurrency": "Latausten samanaikaisuus",
|
||||
"upload_dialog_info": "Haluatko varmuuskopioida valitut kohteet palvelimelle?",
|
||||
"upload_dialog_title": "Lähetä kohde",
|
||||
"upload_errors": "Lataus valmistui {count, plural, one {# virheen} other {# virheen}} kanssa. Päivitä sivu nähdäksesi ladatut tiedot.",
|
||||
"upload_progress": "Jäljellä {remaining, number} - Käsitelty {processed, number}/{total, number}",
|
||||
"upload_skipped_duplicates": "Ohitettiin {count, plural, one {# kaksoiskappale} other {# kaksoiskappaletta}}",
|
||||
@@ -1304,8 +1795,11 @@
|
||||
"upload_status_errors": "Virheet",
|
||||
"upload_status_uploaded": "Ladattu",
|
||||
"upload_success": "Lataus onnistui. Päivitä sivu jotta näet latauksesi.",
|
||||
"upload_to_immich": "Upload to Immich ({})",
|
||||
"uploading": "Uploading",
|
||||
"url": "URL",
|
||||
"usage": "Käyttö",
|
||||
"use_current_connection": "use current connection",
|
||||
"use_custom_date_range": "Käytä omaa aikaväliä",
|
||||
"user": "Käyttäjä",
|
||||
"user_id": "Käyttäjän ID",
|
||||
@@ -1320,10 +1814,16 @@
|
||||
"users": "Käyttäjät",
|
||||
"utilities": "Apuohjelmat",
|
||||
"validate": "Validoi",
|
||||
"validate_endpoint_error": "Please enter a valid URL",
|
||||
"variables": "Muuttujat",
|
||||
"version": "Versio",
|
||||
"version_announcement_closing": "Ystäväsi Alex",
|
||||
"version_announcement_message": "Hei! Sovelluksen uusi versio on saatavilla. Käythän vilkaisemassa <link>julkaisun tiedot</link> ja varmistathan, että ohjelman määritykset ovat ajan tasalla. Erityisesti, jos käytössä on Watchtower tai jokin muu mekanismi Immich-sovelluksen automaattista päivitystä varten.",
|
||||
"version_announcement_overlay_release_notes": "julkaisutiedoissa",
|
||||
"version_announcement_overlay_text_1": "Hei, kaveri! Uusi palvelinversio on saatavilla sovelluksesta",
|
||||
"version_announcement_overlay_text_2": "Ota hetki aikaa vieraillaksesi",
|
||||
"version_announcement_overlay_text_3": "ja varmista, että käyttämäsi docker-compose ja .env-asetukset ovat ajantasalla välttyäksesi asetusongelmilta. Varsinkin jos käytät WatchToweria tai jotain muuta mekanismia päivittääksesi palvelinsovellusta automaattisesti.",
|
||||
"version_announcement_overlay_title": "Uusi palvelinversio saatavilla 🎉",
|
||||
"version_history": "Versiohistoria",
|
||||
"version_history_item": "Asennettu {version} päivänä {date}",
|
||||
"video": "Video",
|
||||
@@ -1341,15 +1841,20 @@
|
||||
"view_next_asset": "Näytä seuraava",
|
||||
"view_previous_asset": "Näytä edellinen",
|
||||
"view_stack": "Näytä pinona",
|
||||
"viewer_remove_from_stack": "Poista pinosta",
|
||||
"viewer_stack_use_as_main_asset": "Käytä pääkohteena",
|
||||
"viewer_unstack": "Pura pino",
|
||||
"visibility_changed": "{count, plural, one {# henkilön} other {# henkilöiden}} näkyvyys vaihdettu",
|
||||
"waiting": "Odottaa",
|
||||
"warning": "Varoitus",
|
||||
"week": "Viikko",
|
||||
"welcome": "Tervetuloa",
|
||||
"welcome_to_immich": "Tervetuloa Immichiin",
|
||||
"wifi_name": "WiFi Name",
|
||||
"year": "Vuosi",
|
||||
"years_ago": "{years, plural, one {# vuosi} other {# vuotta}} sitten",
|
||||
"yes": "Kyllä",
|
||||
"you_dont_have_any_shared_links": "Sinulla ei ole jaettuja linkkejä",
|
||||
"your_wifi_name": "Your WiFi name",
|
||||
"zoom_image": "Zoomaa kuvaa"
|
||||
}
|
||||
}
|
||||
|
||||
543
i18n/fr.json
543
i18n/fr.json
File diff suppressed because it is too large
Load Diff
1899
i18n/gl.json
Normal file
1899
i18n/gl.json
Normal file
File diff suppressed because it is too large
Load Diff
808
i18n/he.json
808
i18n/he.json
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user