Compare commits

..

10 Commits

Author SHA1 Message Date
Armin Schrenk
e2ba37bbc7 Revert "do not extract wixhelper.dll if jmods do not exist"
This reverts commit 624b623f8f.
2025-06-23 15:42:45 +02:00
Armin Schrenk
60459c739e explicitlly state arch for exe installer 2025-06-23 14:52:05 +02:00
Armin Schrenk
2f43c6688d install wix 6.x on msi runner 2025-06-23 12:39:12 +02:00
Armin Schrenk
ac0b422701 add x86 installer with arm64 payload 2025-06-23 12:29:25 +02:00
Armin Schrenk
03fa62be01 include hidden files for upload 2025-06-23 12:27:13 +02:00
Armin Schrenk
fb86702cae fix wrong license placement path 2025-06-23 12:10:21 +02:00
Armin Schrenk
7cdd950290 fix wrong paths and keys 2025-06-23 11:58:12 +02:00
Armin Schrenk
624b623f8f do not extract wixhelper.dll if jmods do not exist 2025-06-23 11:57:22 +02:00
Armin Schrenk
f681618f30 fix errors 2025-06-23 11:44:30 +02:00
Armin Schrenk
39fc1fb7c9 First draft for workarounding #3899 2025-06-23 11:36:25 +02:00
55 changed files with 499 additions and 948 deletions

View File

@@ -44,14 +44,15 @@ jobs:
openjfx-url: 'https://download2.gluonhq.com/openjfx/24.0.1/openjfx-24.0.1_linux-aarch64_bin-jmods.zip'
openjfx-sha: '7e02edd0f4ee5527a27c94b0bbba66fcaaff41009119e45d0eca0f96ddfb6e7b'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v5
uses: actions/setup-java@v4
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}
check-latest: true
cache: 'maven'
- name: Download OpenJFX jmods
id: download-jmods
run: |
@@ -133,7 +134,6 @@ jobs:
--java-options "-Dcryptomator.integrationsLinux.trayIconsDir=\"@{appdir}/usr/share/icons/hicolor/symbolic/apps\""
--java-options "-Dcryptomator.buildNumber=\"appimage-${{ needs.get-version.outputs.revNum }}\""
--java-options "-Dcryptomator.networking.truststore.p12Path=\"/etc/cryptomator/certs.p12\""
--java-options "-XX:ErrorFile=/cryptomator/cryptomator_crash.log"
--resource-dir dist/linux/resources
- name: Patch Cryptomator.AppDir
run: |
@@ -194,68 +194,3 @@ jobs:
cryptomator-*.AppImage
cryptomator-*.zsync
cryptomator-*.asc
create-aur-bin-pr:
name: Create PR for aur-bin repo
needs: [build, get-version]
runs-on: ubuntu-latest
if: github.event_name == 'release'
steps:
- name: Download AppImages
uses: actions/download-artifact@v5
with:
path: downloads/
merge-multiple: true
- name: Compute sha256 hash of AppImages
id: checksums
run: |
X64_SHA256=$(sha256sum downloads/cryptomator-*-x86_64.AppImage | cut -d ' ' -f1)
echo "x64-sha256sum=${X64_SHA256}" >> "$GITHUB_OUTPUT"
AARCH64_SHA256=$(sha256sum downloads/cryptomator-*-aarch64.AppImage | cut -d ' ' -f1)
echo "aarch64-sha256sum=${AARCH64_SHA256}" >> "$GITHUB_OUTPUT"
- uses: actions/checkout@v5
with:
repository: 'cryptomator/aur-bin'
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get -y install makepkg pacman-package-manager
- name: Checkout release branch
run: |
git checkout -b release/${{ needs.get-version.outputs.semVerStr }}
- name: Update build file
run: |
sed -i -e 's|^pkgver=.*$|pkgver=${{ needs.get-version.outputs.semVerStr }}|' PKGBUILD
sed -i -e 's|^pkgrel=.*$|pkgrel=1|' PKGBUILD
sed -i -e "s|^sha256sums_x86_64=.*$|sha256sums_x86_64=('${{ steps.checksums.outputs.x64-sha256sum }}'|" PKGBUILD
sed -i -e "s|^sha256sums_aarch64=.*$|sha256sums_aarch64=('${{ steps.checksums.outputs.aarch64-sha256sum}}'|" PKGBUILD
makepkg --printsrcinfo > .SRCINFO
- name: Commit and push
run: |
git config user.name "${{ github.actor }}"
git config user.email "${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com"
git config push.autoSetupRemote true
git stage .
git commit -m "Prepare release ${{needs.get-version.outputs.semVerStr}}"
git push
- name: Create pull request
id: create-pr
run: |
printf "> [!IMPORTANT]\n> Todos:\n> - [ ] Update build instructions\n> - [ ] Check for JDK update\n> - [ ] Check for JFX update" > pr_body.md
URL=$(gh pr create --title "Release ${{ needs.get-version.outputs.semVerStr }}" --body-file pr_body.md)
echo "PR_URL=$URL" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
- name: Slack Notification
uses: rtCamp/action-slack-notify@v2
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_USERNAME: 'Cryptobot'
SLACK_ICON: false
SLACK_ICON_EMOJI: ':bot:'
SLACK_CHANNEL: 'cryptomator-desktop'
SLACK_TITLE: "AUR-bin release PR for ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} created."
SLACK_MESSAGE: "See <${{ steps.create-pr.outputs.PR_URL }}|PR> on how to proceed."
SLACK_FOOTER: false
MSG_MINIMAL: true

View File

@@ -1,93 +0,0 @@
name: Create PR for AUR
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: 'Release tag'
required: true
jobs:
get-version:
uses: ./.github/workflows/get-version.yml
with:
version: ${{ inputs.tag }}
tarball:
name: Determines tarball url and compute checksum
runs-on: ubuntu-latest
needs: [get-version]
if: github.event_name == 'workflow_dispatch' || needs.get-version.outputs.versionType == 'stable'
outputs:
url: ${{ steps.url.outputs.url}}
sha256: ${{ steps.sha256.outputs.sha256}}
steps:
- name: Determine tarball url
id: url
run: |
URL="";
if [[ -n "${{ inputs.tag }}" ]]; then
URL="https://github.com/cryptomator/cryptomator/archive/refs/tags/${{ inputs.tag }}.tar.gz"
else
URL="https://github.com/cryptomator/cryptomator/archive/refs/tags/${{ github.event.release.tag_name }}.tar.gz"
fi
echo "url=${URL}" >> "$GITHUB_OUTPUT"
- name: Download source tarball and compute checksum
id: sha256
run: |
curl --silent --fail-with-body -L -H "Accept: application/vnd.github+json" ${{ steps.url.outputs.url }} --output cryptomator.tar.gz
TARBALL_SHA256=$(sha256sum cryptomator.tar.gz | cut -d ' ' -f1)
echo "sha256=${TARBALL_SHA256}" >> "$GITHUB_OUTPUT"
aur:
name: Create PR for AUR
runs-on: ubuntu-latest
needs: [tarball, get-version]
env:
AUR_PR_URL: tbd
steps:
- uses: actions/checkout@v5
with:
repository: 'cryptomator/aur'
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install makepkg pacman-package-manager
- name: Checkout release branch
run: |
git checkout -b release/${{ needs.get-version.outputs.semVerStr }}
- name: Update build file
run: |
sed -i -e 's|^pkgver=.*$|pkgver=${{ needs.get-version.outputs.semVerStr }}|' PKGBUILD
sed -i -e 's|^pkgrel=.*$|pkgrel=1|' PKGBUILD
sed -i -e "s|^sha256sums=.*$|sha256sums=('${{ needs.tarball.outputs.sha256 }}'|" PKGBUILD
makepkg --printsrcinfo > .SRCINFO
- name: Commit and push
run: |
git config user.name "${{ github.actor }}"
git config user.email "${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com"
git config push.autoSetupRemote true
git stage .
git commit -m "Prepare release ${{needs.get-version.outputs.semVerStr}}"
git push
- name: Create pull request
run: |
printf "> [!IMPORTANT]\n> Todos:\n> - [ ] Update build instructions\n> - [ ] Check for JDK update\n> - [ ] Check for JFX update" > pr_body.md
PR_URL=$(gh pr create --title "Release ${{ needs.get-version.outputs.semVerStr }}" --body-file pr_body.md)
echo "AUR_PR_URL=$PR_URL" >> "$GITHUB_ENV"
env:
GH_TOKEN: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
- name: Slack Notification
uses: rtCamp/action-slack-notify@v2
if: github.event_name == 'release'
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_USERNAME: 'Cryptobot'
SLACK_ICON: false
SLACK_ICON_EMOJI: ':bot:'
SLACK_CHANNEL: 'cryptomator-desktop'
SLACK_TITLE: "AUR release PR created for ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} created."
SLACK_MESSAGE: "See <${{ env.AUR_PR_URL }}|PR> on how to proceed."
SLACK_FOOTER: false
MSG_MINIMAL: true

View File

@@ -51,12 +51,12 @@ jobs:
if: github.event_name == 'workflow_call' || inputs.kaspersky
steps:
- name: Download artifact
uses: actions/download-artifact@v5
uses: actions/download-artifact@v4
with:
name: ${{ needs.download-file.outputs.fileName }}
path: upload
- name: Upload to Kaspersky
uses: SamKirkland/FTP-Deploy-Action@v4.3.6
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
with:
protocol: ftps
server: allowlist.kaspersky-labs.com
@@ -71,7 +71,7 @@ jobs:
if: github.event_name == 'workflow_call' || inputs.avast
steps:
- name: Download artifact
uses: actions/download-artifact@v5
uses: actions/download-artifact@v4
with:
name: ${{ needs.download-file.outputs.fileName }}
path: upload

View File

@@ -22,8 +22,8 @@ jobs:
name: Compile and Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}

View File

@@ -26,7 +26,7 @@ jobs:
run: echo 'JDK_MAJOR_VERSION=${{ env.JDK_VERSION }}'.substring(0,20) >> "$env:GITHUB_ENV"
shell: pwsh
- name: Checkout latest JDK ${{ env.JDK_MAJOR_VERSION }}
uses: actions/setup-java@v5
uses: actions/setup-java@v4
with:
java-version: ${{ env.JDK_MAJOR_VERSION}}
distribution: ${{ env.JDK_VENDOR }}

View File

@@ -42,7 +42,7 @@ jobs:
runs-on: ubuntu-22.04
needs: [get-version]
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- id: deb-version
name: Determine deb-version
run: |
@@ -57,7 +57,7 @@ jobs:
sudo apt-get update
sudo apt-get install debhelper devscripts dput coffeelibs-jdk-${{ env.COFFEELIBS_JDK }}=${{ env.COFFEELIBS_JDK_VERSION }}
- name: Setup Java
uses: actions/setup-java@v5
uses: actions/setup-java@v4
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}

View File

@@ -10,7 +10,7 @@ jobs:
steps:
- name: Get download count of latest releases
id: get-stats
uses: actions/github-script@v8
uses: actions/github-script@v7
with:
script: |
const query = `query($owner:String!, $name:String!) {

View File

@@ -14,7 +14,7 @@ jobs:
- name: Query Discussion Data
if: github.event_name == 'discussion_comment' || github.event_name == 'discussion' && github.event.action != 'deleted'
id: query-data
uses: actions/github-script@v8
uses: actions/github-script@v7
with:
script: |
const query = `query ($owner: String!, $name: String!, $discussionNumber: Int!) {

View File

@@ -46,10 +46,10 @@ jobs:
env:
FLATHUB_PR_URL: tbd
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
with:
repository: 'flathub/org.cryptomator.Cryptomator'
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
token: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
- name: Checkout release branch
run: |
git checkout -b release/${{ needs.get-version.outputs.semVerStr }}
@@ -72,7 +72,7 @@ jobs:
PR_URL=$(gh pr create --title "Release ${{ needs.get-version.outputs.semVerStr }}" --body-file pr_body.md)
echo "FLATHUB_PR_URL=$PR_URL" >> "$GITHUB_ENV"
env:
GH_TOKEN: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
GH_TOKEN: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
- name: Slack Notification
uses: rtCamp/action-slack-notify@v2
if: github.event_name == 'release'

View File

@@ -35,11 +35,11 @@ jobs:
revNum: ${{ steps.versions.outputs.revNum }}
type: ${{ steps.versions.outputs.type}}
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Java
uses: actions/setup-java@v5
uses: actions/setup-java@v4
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}

View File

@@ -47,9 +47,9 @@ jobs:
openjfx-url: 'https://download2.gluonhq.com/openjfx/24.0.1/openjfx-24.0.1_osx-x64_bin-jmods.zip'
openjfx-sha: '6e62a426d43c168a488521f904a523f3dd6ee2cf103e08136f2fd465c828a105'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v5
uses: actions/setup-java@v4
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}

View File

@@ -45,9 +45,9 @@ jobs:
openjfx-url: 'https://download2.gluonhq.com/openjfx/24.0.1/openjfx-24.0.1_osx-aarch64_bin-jmods.zip'
openjfx-sha: 'b5a94a13077507003fa852512bfa33f4fb680bc8076d8002e4227a84c85171d4'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v5
uses: actions/setup-java@v4
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}
@@ -136,7 +136,6 @@ jobs:
--java-options "-Dcryptomator.mountPointsDir=\"@{userhome}/Library/Application Support/Cryptomator/mnt\""
--java-options "-Dcryptomator.showTrayIcon=true"
--java-options "-Dcryptomator.buildNumber=\"dmg-${{ needs.get-version.outputs.revNum }}\""
--java-options "-XX:ErrorFile=/cryptomator/cryptomator_crash.log"
--mac-package-identifier org.cryptomator
--resource-dir dist/mac/resources
- name: Patch Cryptomator.app

View File

@@ -12,7 +12,7 @@ jobs:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v10
- uses: actions/stale@v9
with:
days-before-stale: 14
days-before-close: 0

View File

@@ -16,8 +16,8 @@ jobs:
name: Compile and Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}

View File

@@ -19,9 +19,9 @@ jobs:
name: Validate commits pushed to release/hotfix branch to fulfill release requirements
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v5
uses: actions/setup-java@v4
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}

View File

@@ -12,7 +12,7 @@ jobs:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v10
- uses: actions/stale@v9
with:
days-before-stale: 365
days-before-close: 90

View File

@@ -12,11 +12,6 @@ on:
description: 'Build debug version with console output'
type: boolean
default: false
sign:
description: 'Sign binaries'
required: false
type: boolean
default: false
push:
branches-ignore:
- 'dependabot/**'
@@ -42,8 +37,8 @@ jobs:
with:
version: ${{ inputs.version }}
build-msi:
name: Build .msi Installer
build-appimage:
name: Build appimage
runs-on: ${{ matrix.os }}
needs: [ get-version ]
strategy:
@@ -59,10 +54,13 @@ jobs:
java-dist: 'liberica'
java-version: '24.0.1+11'
java-package: 'jdk+fx' #This is needed, as liberica contains JFX 24 Jmods for Windows ARM64
env:
LOOPBACK_ALIAS: 'cryptomator-vault'
WIN_CONSOLE_FLAG: ''
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v5
uses: actions/setup-java@v4
with:
distribution: ${{ matrix.java-dist }}
java-version: ${{ matrix.java-version }}
@@ -128,6 +126,9 @@ jobs:
--no-man-pages
--strip-debug
--compress zip-0
- name: Change win-console flag if debug is active
if: ${{ inputs.isDebug }}
run: echo "WIN_CONSOLE_FLAG=--win-console" >> $GITHUB_ENV
- name: Run jpackage
run: >
${JAVA_HOME}/bin/jpackage
@@ -156,24 +157,31 @@ jobs:
--java-options "-Dcryptomator.p12Path=\"@{appdata}/Cryptomator/key.p12;@{userhome}/AppData/Roaming/Cryptomator/key.p12\""
--java-options "-Dcryptomator.ipcSocketPath=\"@{localappdata}/Cryptomator/ipc.socket\""
--java-options "-Dcryptomator.mountPointsDir=\"@{userhome}/Cryptomator\""
--java-options "-Dcryptomator.loopbackAlias=\"cryptomator-vault\""
--java-options "-Dcryptomator.loopbackAlias=\"${{ env.LOOPBACK_ALIAS }}\""
--java-options "-Dcryptomator.showTrayIcon=true"
--java-options "-Dcryptomator.buildNumber=\"msi-${{ needs.get-version.outputs.revNum }}\""
--java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=\"Cryptomator\""
--java-options "-Dcryptomator.integrationsWin.keychainPaths=\"@{appdata}/Cryptomator/keychain.json;@{userhome}/AppData/Roaming/Cryptomator/keychain.json\""
--java-options "-Dcryptomator.integrationsWin.windowsHelloKeychainPaths=\"@{appdata}/Cryptomator/windowsHelloKeychain.json\""
--java-options "-Dcryptomator.disableUpdateCheck=false"
--java-options "-XX:ErrorFile=C:/cryptomator/cryptomator_crash.log"
--java-options "-Djavafx.verbose=${{ inputs.isDebug }}"
--resource-dir dist/win/resources
--icon dist/win/resources/Cryptomator.ico
--add-launcher "Cryptomator (Debug)=dist/win/debug-launcher.properties"
${WIN_CONSOLE_FLAG}
- name: Patch Application Directory
run: |
cp dist/win/contrib/* appdir/Cryptomator
- name: Fix permissions
- name: Set LOOPBACK_ALIAS in patchWebDAV.bat
shell: pwsh
run: |
attrib -r appdir/Cryptomator/Cryptomator.exe
attrib -r "appdir/Cryptomator/Cryptomator (Debug).exe"
$patchScript = "appdir\Cryptomator\patchWebDAV.bat"
try {
(Get-Content $patchScript ) -replace '::REPLACE ME', "SET LOOPBACK_ALIAS=`"${{ env.LOOPBACK_ALIAS}}`"" | Set-Content $patchScript
} catch {
Write-Host "Failed to set LOOPBACK_ALIAS for patchWebDAV.bat"
exit 1
}
- name: Fix permissions
run: attrib -r appdir/Cryptomator/Cryptomator.exe
shell: pwsh
- name: Extract jars with DLLs for Codesigning
shell: pwsh
@@ -198,17 +206,16 @@ jobs:
New-Item -Path appdir/jpackage-jmod -ItemType Directory
& $env:JAVA_HOME\bin\jmod.exe extract --dir jpackage-jmod "${env:JAVA_HOME}\jmods\jdk.jpackage.jmod"
Get-ChildItem -Recurse -Path "jpackage-jmod" -File wixhelper.dll | Select-Object -Last 1 | Copy-Item -Destination "appdir"
- name: Sign DLLs with Actalis CodeSigner
if: inputs.sign || github.event_name == 'release'
uses: skymatic/workflows/.github/actions/win-sign-action@450e322ff2214d0be0b079b63343c894f3ef735f
- name: Codesign
uses: skymatic/code-sign-action@v3
with:
base-dir: 'appdir'
file-extensions: 'dll,exe,ps1'
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
password: ${{ secrets.WIN_CODESIGN_P12_PW }}
certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A
description: Cryptomator
timestampUrl: 'http://timestamp.digicert.com'
folder: appdir
recursive: true
sign-description: 'Cryptomator'
sign-url: 'https://cryptomator.org'
username: ${{ secrets.WIN_CODESIGN_USERNAME }}
password: ${{ secrets.WIN_CODESIGN_PW }}
- name: Replace DLLs inside jars with signed ones
shell: pwsh
run: |
@@ -223,24 +230,64 @@ jobs:
jar --file="$jarFile" --update $(Resolve-Path -Relative -Path $_)
}
}
- name: Generate license for MSI
- name: Generate license file
run: >
mvn -B license:add-third-party "-Djavafx.platform=win"
"-Dlicense.thirdPartyFilename=license.rtf"
"-Dlicense.outputDirectory=dist/win/resources"
"-Dlicense.outputDirectory=appdir"
"-Dlicense.fileTemplate=dist/win/resources/licenseTemplate.ftl"
"-Dlicense.includedScopes=compile"
"-Dlicense.excludedGroups=^org\.cryptomator"
"-Dlicense.failOnMissing=true"
"-Dlicense.licenseMergesUrl=file:///${{ github.workspace }}/license/merges"
shell: pwsh
- name: Create MSI
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: appimage-${{ matrix.arch }}
include-hidden-files: true
if-no-files-found: error
path: |
appdir
build-msi:
name: Build .msi installer
runs-on: windows-latest
needs: [ get-version, build-appimage ]
steps:
- uses: actions/checkout@v4
- name: Download appimage
uses: actions/download-artifact@v4
with:
name: appimage-x64
path: appdir-x64
- name: Download appimage
uses: actions/download-artifact@v4
with:
name: appimage-arm64
path: appdir-arm64
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '24.0.1+9'
java-package: 'jdk'
cache: 'maven'
- name: Install wix and extensions
run: |
dotnet tool install --global wix --version 6.0.0
wix.exe extension add WixToolset.UI.wixext/6.0.0 --global
wix.exe extension add WixToolset.Util.wixext/6.0.0 --global
- name: Copy license file
run: cp appdir-x64/license.rtf dist/win/resources/license.rtf
- name: Create x64 MSI with x64 appimage
run: >
${JAVA_HOME}/bin/jpackage
--verbose
--type msi
--win-upgrade-uuid bda45523-42b1-4cae-9354-a45475ed4775
--app-image appdir/Cryptomator
--app-image appdir-x64/Cryptomator
--dest installer
--name Cryptomator
--vendor "Skymatic GmbH"
@@ -256,19 +303,45 @@ jobs:
--file-associations dist/win/resources/FAvaultFile.properties
env:
JP_WIXWIZARD_RESOURCES: ${{ github.workspace }}/dist/win/resources # requires abs path, used in resources/main.wxs
JP_WIXHELPER_DIR: ${{ github.workspace }}\appdir
- name: Sign msi with Actalis CodeSigner
if: inputs.sign || github.event_name == 'release'
uses: skymatic/workflows/.github/actions/win-sign-action@450e322ff2214d0be0b079b63343c894f3ef735f
with:
base-dir: 'installer'
file-extensions: 'msi'
sign-description: 'Cryptomator Installer'
sign-url: 'https://cryptomator.org'
username: ${{ secrets.WIN_CODESIGN_USERNAME }}
password: ${{ secrets.WIN_CODESIGN_PW }}
JP_WIXHELPER_DIR: ${{ github.workspace }}\appdir-x64
- name: Add possible alpha/beta tags and architecture to installer name
run: mv installer/Cryptomator-*.msi Cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.arch }}.msi
run: mv installer/Cryptomator-*.msi Cryptomator-${{ needs.get-version.outputs.semVerStr }}-x64.msi
- name: Copy license file for arm64
run: cp appdir-arm64/license.rtf dist/win/resources/license.rtf
- name: Create x64 MSI with arm64 appimage
run: >
${JAVA_HOME}/bin/jpackage
--verbose
--type msi
--win-upgrade-uuid bda45523-42b1-4cae-9354-a45475ed4775
--app-image appdir-arm64/Cryptomator
--dest installer
--name Cryptomator
--vendor "Skymatic GmbH"
--copyright "(C) 2016 - 2025 Skymatic GmbH"
--app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum}}"
--win-menu
--win-dir-chooser
--win-shortcut-prompt
--win-update-url "https:\\cryptomator.org\downloads"
--win-menu-group Cryptomator
--resource-dir dist/win/resources
--license-file dist/win/resources/license.rtf
--file-associations dist/win/resources/FAvaultFile.properties
env:
JP_WIXWIZARD_RESOURCES: ${{ github.workspace }}/dist/win/resources # requires abs path, used in resources/main.wxs
JP_WIXHELPER_DIR: ${{ github.workspace }}\appdir-arm64
- name: Add possible alpha/beta tags and architecture to installer name
run: mv installer/Cryptomator-*.msi Cryptomator-${{ needs.get-version.outputs.semVerStr }}-arm64.msi
- name: Codesign MSIs
uses: skymatic/code-sign-action@v3
with:
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
password: ${{ secrets.WIN_CODESIGN_P12_PW }}
certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A
description: Cryptomator Installer
timestampUrl: 'http://timestamp.digicert.com'
folder: installer
- name: Create detached GPG signature with key 615D449FE6E6A235
run: |
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
@@ -279,7 +352,7 @@ jobs:
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: msi-${{ matrix.arch }}
name: msi-x64
path: |
Cryptomator-*.msi
Cryptomator-*.asc
@@ -305,21 +378,21 @@ jobs:
java-version: '24.0.1+11'
java-package: 'jdk+fx' #This is needed, as liberica contains JFX 24 Jmods for Windows ARM64
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Install wix and extensions
run: |
dotnet tool install --global wix --version 6.0.0
wix.exe extension add WixToolset.BootstrapperApplications.wixext/6.0.0 --global
wix.exe extension add WixToolset.Util.wixext/6.0.0 --global
- name: Download .msi
uses: actions/download-artifact@v5
uses: actions/download-artifact@v4
with:
name: msi-${{ matrix.arch }}
path: dist/win/bundle/resources
- name: Strip version info from msi file name
run: mv dist/win/bundle/resources/Cryptomator*.msi dist/win/bundle/resources/Cryptomator.msi
- name: Setup Java
uses: actions/setup-java@v5
uses: actions/setup-java@v4
with:
distribution: ${{ matrix.java-dist }}
java-version: ${{ matrix.java-version }}
@@ -355,6 +428,7 @@ jobs:
working-directory: dist/win
run: >
wix build
-arch ${{ matrix.arch }}
-define BundleName="Cryptomator"
-define BundleVersion="${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum}}"
-define BundleVendor="Skymatic GmbH"
@@ -369,29 +443,27 @@ jobs:
- name: Detach burn engine in preparation to sign
run: >
wix burn detach installer/unsigned/Cryptomator-Installer.exe -engine tmp/engine.exe
- name: Sign burn engine with Actalis CodeSigner
if: inputs.sign || github.event_name == 'release'
uses: skymatic/workflows/.github/actions/win-sign-action@450e322ff2214d0be0b079b63343c894f3ef735f
- name: Codesign burn engine
uses: skymatic/code-sign-action@v3
with:
base-dir: 'tmp'
file-extensions: 'exe'
sign-description: 'Cryptomator Bundle Installer'
sign-url: 'https://cryptomator.org'
username: ${{ secrets.WIN_CODESIGN_USERNAME }}
password: ${{ secrets.WIN_CODESIGN_PW }}
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
password: ${{ secrets.WIN_CODESIGN_P12_PW }}
certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A
description: Cryptomator Installer
timestampUrl: 'http://timestamp.digicert.com'
folder: tmp
- name: Reattach signed burn engine to installer
run: >
wix burn reattach installer/unsigned/Cryptomator-Installer.exe -engine tmp/engine.exe -o installer/Cryptomator-Installer.exe
- name: Sign installer with Actalis CodeSigner
if: inputs.sign || github.event_name == 'release'
uses: skymatic/workflows/.github/actions/win-sign-action@450e322ff2214d0be0b079b63343c894f3ef735f
- name: Codesign EXE
uses: skymatic/code-sign-action@v3
with:
base-dir: 'installer'
file-extensions: 'exe'
sign-description: 'Cryptomator Bundle Installer'
sign-url: 'https://cryptomator.org'
username: ${{ secrets.WIN_CODESIGN_USERNAME }}
password: ${{ secrets.WIN_CODESIGN_PW }}
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
password: ${{ secrets.WIN_CODESIGN_P12_PW }}
certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A
description: Cryptomator Installer
timestampUrl: 'http://timestamp.digicert.com'
folder: installer
- name: Add possible alpha/beta tags to installer name
run: mv installer/Cryptomator-Installer.exe Cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.executable-suffix }}.exe
- name: Create detached GPG signature with key 615D449FE6E6A235
@@ -422,7 +494,7 @@ jobs:
download-url-exe-arm64: ${{ fromJSON(steps.publish.outputs.assets)[3].browser_download_url }}
steps:
- name: Download installers
uses: actions/download-artifact@v5
uses: actions/download-artifact@v4
with:
merge-multiple: true
- name: Publish installers on GitHub Releases

View File

@@ -16,7 +16,7 @@ jobs:
run: |
gh repo sync cryptomator/winget-pkgs -b master --force
env:
GH_TOKEN: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
GH_TOKEN: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
- name: Submit package
uses: vedantmgoyal2009/winget-releaser@main
with:
@@ -24,4 +24,4 @@ jobs:
version: ${{ inputs.tag }}
release-tag: ${{ inputs.tag }}
installers-regex: '-x64\.msi$'
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
token: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}

View File

@@ -98,7 +98,6 @@ ${JAVA_HOME}/bin/jpackage \
--java-options "-Dcryptomator.integrationsLinux.trayIconsDir=\"@{appdir}/usr/share/icons/hicolor/symbolic/apps\"" \
--java-options "-Dcryptomator.buildNumber=\"appimage-${REVISION_NO}\"" \
--java-options "-Dcryptomator.networking.truststore.p12Path=\"/etc/cryptomator/certs.p12\"" \
--java-options "-XX:ErrorFile=/cryptomator/cryptomator_crash.log" \
--resource-dir ../resources
# transform AppDir

View File

@@ -83,12 +83,6 @@
</content_rating>
<releases>
<release date="2025-07-08" version="1.17.1">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.17.1</url>
</release>
<release date="2025-06-24" version="1.17.0">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.17.0</url>
</release>
<release date="2025-05-15" version="1.16.2">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.16.2</url>
</release>

View File

@@ -115,7 +115,6 @@ ${JAVA_HOME}/bin/jpackage \
--java-options "-Dsun.java2d.metal=true" \
--java-options "-Dcryptomator.appVersion=\"${VERSION_NO}\"" \
--java-options "-Dcryptomator.logDir=\"@{userhome}/Library/Logs/${APP_NAME}\"" \
--java-options "-XX:ErrorFile=/cryptomator/cryptomator_crash.log" \
--java-options "-Dcryptomator.pluginDir=\"@{userhome}/Library/Application Support/${APP_NAME}/Plugins\"" \
--java-options "-Dcryptomator.settingsPath=\"@{userhome}/Library/Application Support/${APP_NAME}/settings.json\"" \
--java-options "-Dcryptomator.ipcSocketPath=\"@{userhome}/Library/Application Support/${APP_NAME}/ipc.socket\"" \

3
dist/win/.gitignore vendored
View File

@@ -4,8 +4,7 @@ installer
*.wixobj
*.pdb
*.msi
*Debug.properties
*.exe
*.jmod
resources/jfxJmods.zip
license.rtf
license.rtf

6
dist/win/build.bat vendored
View File

@@ -11,10 +11,6 @@ SET HELP_URL="https://cryptomator.org/contact/"
SET MODULE_AND_MAIN_CLASS="org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator"
SET LOOPBACK_ALIAS="cryptomator-vault"
:: read clean parameter from command line
SET CLEAN=0
IF "%~1"=="clean" SET CLEAN=1
pwsh -NoLogo -NoProfile -ExecutionPolicy Unrestricted -Command .\build.ps1^
-AppName %APPNAME%^
-MainJarGlob "%MAIN_JAR_GLOB%"^
@@ -26,4 +22,4 @@ pwsh -NoLogo -NoProfile -ExecutionPolicy Unrestricted -Command .\build.ps1^
-HelpUrl "%HELP_URL%"^
-UpdateUrl "%UPDATE_URL%"^
-LoopbackAlias "%LOOPBACK_ALIAS%"^
-Clean %CLEAN%
-Clean 1

106
dist/win/build.ps1 vendored
View File

@@ -9,15 +9,9 @@ Param(
[Parameter(Mandatory, HelpMessage="Please provide an update url")][string] $UpdateUrl,
[Parameter(Mandatory, HelpMessage="Please provide an about url")][string] $AboutUrl,
[Parameter(Mandatory, HelpMessage="Please provide an alias for localhost")][string] $LoopbackAlias,
[bool] $clean = $false # if true, cleans up previous build artifacts
[bool] $clean
)
# ============================
# Function Definitions Section
# ============================
function Main {
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$ProgressPreference = 'SilentlyContinue' # disables Invoke-WebRequest's progress bar, which slows down downloads to a few bytes/s
@@ -56,11 +50,11 @@ $version = $(mvn -f $buildDir/../../pom.xml help:evaluate -Dexpression="project.
$semVerNo = $version -replace '(\d+\.\d+\.\d+).*','$1'
$revisionNo = $(git rev-list --count HEAD)
Write-Host "`$version=$version"
Write-Host "`$semVerNo=$semVerNo"
Write-Host "`$revisionNo=$revisionNo"
Write-Host "`$buildDir=$buildDir"
Write-Host "`$Env:JAVA_HOME=$Env:JAVA_HOME"
Write-Output "`$version=$version"
Write-Output "`$semVerNo=$semVerNo"
Write-Output "`$revisionNo=$revisionNo"
Write-Output "`$buildDir=$buildDir"
Write-Output "`$Env:JAVA_HOME=$Env:JAVA_HOME"
$copyright = "(C) $CopyrightStartYear - $((Get-Date).Year) $Vendor"
@@ -77,7 +71,7 @@ if ($clean -and (Test-Path -Path $runtimeImagePath)) {
## download jfx jmods for X64, while they are part of the Arm64 JDK
$archCode = (Get-CimInstance Win32_Processor).Architecture
$archName = switch ($archCode) {
9 { "x64" }
9 { "x64 (AMD64)" }
12 { "ARM64" }
default { "WMI Win32_Processor.Architecture code ($archCode)" }
}
@@ -92,14 +86,14 @@ switch ($archName) {
$jmodPaths = "$Env:JAVA_HOME/jmods"
}
'x64' {
'x64 (AMD64)' {
$javaFxVersion='24.0.1'
$javaFxJmodsUrl = "https://download2.gluonhq.com/openjfx/${javaFxVersion}/openjfx-${javaFxVersion}_windows-x64_bin-jmods.zip"
$javaFxJmodsSHA256 = 'f13d17c7caf88654fc835f1b4e75a9b0f34a888eb8abef381796c0002e63b03f'
$javaFxJmods = '.\resources\jfxJmods.zip'
if( !(Test-Path -Path $javaFxJmods) ) {
Write-Host "Downloading ${javaFxJmodsUrl}..."
Write-Output "Downloading ${javaFxJmodsUrl}..."
Invoke-WebRequest $javaFxJmodsUrl -OutFile $javaFxJmods # redirects are followed by default
}
@@ -145,31 +139,6 @@ if ($clean -and (Test-Path -Path $appPath)) {
Remove-Item -Path $appPath -Force -Recurse
}
$javaOptions = @(
"--java-options", "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.win,org.cryptomator.integrations.win"
"--java-options", "-Xss5m"
"--java-options", "-Xmx256m"
"--java-options", "-Dcryptomator.appVersion=`"$semVerNo`""
"--java-options", "-Dfile.encoding=`"utf-8`""
"--java-options", "-Djava.net.useSystemProxies=true"
"--java-options", "-Dcryptomator.logDir=`"@{localappdata}/$AppName`""
"--java-options", "-XX:ErrorFile=`"C:/cryptomator/cryptomator_crash.log`""
"--java-options", "-Dcryptomator.pluginDir=`"@{appdata}/$AppName/Plugins`""
"--java-options", "-Dcryptomator.settingsPath=`"@{appdata}/$AppName/settings.json;@{userhome}/AppData/Roaming/$AppName/settings.json`""
"--java-options", "-Dcryptomator.ipcSocketPath=`"@{localappdata}/$AppName/ipc.socket`""
"--java-options", "-Dcryptomator.p12Path=`"@{appdata}/$AppName/key.p12;@{userhome}/AppData/Roaming/$AppName/key.p12`""
"--java-options", "-Dcryptomator.mountPointsDir=`"@{userhome}/$AppName`""
"--java-options", "-Dcryptomator.loopbackAlias=`"$LoopbackAlias`""
"--java-options", "-Dcryptomator.integrationsWin.autoStartShellLinkName=`"$AppName`""
"--java-options", "-Dcryptomator.integrationsWin.keychainPaths=`"@{appdata}/$AppName/keychain.json;@{userhome}/AppData/Roaming/$AppName/keychain.json`""
"--java-options", "-Dcryptomator.integrationsWin.windowsHelloKeychainPaths=`"@{appdata}/$AppName/windowsHelloKeychain.json`""
"--java-options", "-Dcryptomator.showTrayIcon=true"
"--java-options", "-Dcryptomator.buildNumber=`"msi-$revisionNo`""
"--java-options", "-Dcryptomator.disableUpdateCheck=false"
)
# create app dir
& "$Env:JAVA_HOME\bin\jpackage" `
--verbose `
@@ -182,16 +151,28 @@ $javaOptions = @(
--name $AppName `
--vendor $Vendor `
--copyright $copyright `
--java-options "--enable-preview" `
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.win,org.cryptomator.integrations.win" `
--java-options "-Xss5m" `
--java-options "-Xmx256m" `
--java-options "-Dcryptomator.appVersion=`"$semVerNo`"" `
--app-version "$semVerNo.$revisionNo" `
--java-options "-Dfile.encoding=`"utf-8`"" `
--java-options "-Djava.net.useSystemProxies=true" `
--java-options "-Dcryptomator.logDir=`"@{localappdata}/$AppName`"" `
--java-options "-Dcryptomator.pluginDir=`"@{appdata}/$AppName/Plugins`"" `
--java-options "-Dcryptomator.settingsPath=`"@{appdata}/$AppName/settings.json;@{userhome}/AppData/Roaming/$AppName/settings.json`"" `
--java-options "-Dcryptomator.ipcSocketPath=`"@{localappdata}/$AppName/ipc.socket`"" `
--java-options "-Dcryptomator.p12Path=`"@{appdata}/$AppName/key.p12;@{userhome}/AppData/Roaming/$AppName/key.p12`"" `
--java-options "-Dcryptomator.mountPointsDir=`"@{userhome}/$AppName`"" `
--java-options "-Dcryptomator.loopbackAlias=`"$LoopbackAlias`"" `
--java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=`"$AppName`"" `
--java-options "-Dcryptomator.integrationsWin.keychainPaths=`"@{appdata}/$AppName/keychain.json;@{userhome}/AppData/Roaming/$AppName/keychain.json`"" `
--java-options "-Dcryptomator.integrationsWin.windowsHelloKeychainPaths=`"@{appdata}/$AppName/windowsHelloKeychain.json`"" `
--java-options "-Dcryptomator.showTrayIcon=true" `
--java-options "-Dcryptomator.buildNumber=`"msi-$revisionNo`"" `
--resource-dir resources `
--icon resources/$AppName.ico `
--add-launcher "${AppName} (Debug)=$buildDir\debug-launcher.properties" `
@javaOptions
if ($LASTEXITCODE -ne 0) {
Write-Error "jpackage Appimage failed with exit code $LASTEXITCODE"
return 1;
}
--icon resources/$AppName.ico
#Create RTF license for msi
&mvn -B -f $buildDir/../../pom.xml license:add-third-party "-Djavafx.platform=win" `
@@ -206,7 +187,14 @@ if ($LASTEXITCODE -ne 0) {
# patch app dir
Copy-Item "contrib\*" -Destination "$AppName"
attrib -r "$AppName\$AppName.exe"
attrib -r "$AppName\${AppName} (Debug).exe"
# patch batch script to set hostfile
$webDAVPatcher = "$AppName\patchWebDAV.bat"
try {
(Get-Content $webDAVPatcher ) -replace '::REPLACE ME', "SET LOOPBACK_ALIAS=`"$LoopbackAlias`"" | Set-Content $webDAVPatcher
} catch {
Write-Host "Failed to set LOOPBACK_ALIAS for patchWebDAV.bat"
exit 1
}
# create .msi
$Env:JP_WIXWIZARD_RESOURCES = "$buildDir\resources"
@@ -249,7 +237,7 @@ if ($LASTEXITCODE -ne 0) {
# download Winfsp
$winfspMsiUrl= 'https://github.com/winfsp/winfsp/releases/download/v2.1/winfsp-2.1.25156.msi'
$winfspMsiHash = '073A70E00F77423E34BED98B86E600DEF93393BA5822204FAC57A29324DB9F7A'
Write-Host "Downloading ${winfspMsiUrl}..."
Write-Output "Downloading ${winfspMsiUrl}..."
Invoke-WebRequest $winfspMsiUrl -OutFile ".\bundle\resources\winfsp.msi" # redirects are followed by default
$computedHash = $(Get-FileHash -Path '.\bundle\resources\winfsp.msi' -Algorithm SHA256).Hash
if (! $computedHash.Equals($winfspMsiHash)) {
@@ -263,7 +251,7 @@ if (! $computedHash.Equals($winfspMsiHash)) {
# download legacy-winfsp uninstaller
$winfspUninstaller= 'https://github.com/cryptomator/winfsp-uninstaller/releases/latest/download/winfsp-uninstaller.exe'
Write-Host "Downloading ${winfspUninstaller}..."
Write-Output "Downloading ${winfspUninstaller}..."
Invoke-WebRequest $winfspUninstaller -OutFile ".\bundle\resources\winfsp-uninstaller.exe" # redirects are followed by default
# copy MSI to bundle resources
@@ -283,18 +271,4 @@ Copy-Item ".\installer\$AppName-*.msi" -Destination ".\bundle\resources\$AppName
.\bundle\bundleWithWinfsp.wxs `
-out "installer\$AppName-Installer.exe"
Write-Host "Created EXE installer .\installer\$AppName-Installer.exe"
return 0;
}
# ============================
# Script Execution Starts Here
# ============================
if ($clean) {
Write-Host "Cleaning up previous build artifacts..."
Remove-Item -Path ".\runtime" -Force -Recurse -ErrorAction Ignore -ProgressAction SilentlyContinue
Remove-Item -Path ".\$AppName" -Force -Recurse -ErrorAction Ignore -ProgressAction SilentlyContinue
Remove-Item -Path ".\installer" -Force -Recurse -ErrorAction Ignore -ProgressAction SilentlyContinue
}
return Main
Write-Output "Created EXE installer .\installer\$AppName-Installer.exe"

View File

@@ -27,8 +27,6 @@
<ns0:Payload Name="Cryptobot.ico" SourceFile="bundle\resources\Cryptomator.ico"/>
</ns0:BootstrapperApplication>
<ns0:Variable Name="DISABLEUPDATECHECK" bal:Overridable="yes" Type="string" Value="false"/>
<ns0:Chain>
<ns0:ExePackage Cache="keep" PerMachine="yes" Permanent="no" SourceFile="bundle\resources\winfsp-uninstaller.exe" DisplayName="Removing outdated WinFsp Driver" Description="Executable to remove old winfsp" DetectCondition="false" InstallCondition="(InstalledLegacyWinFspVersion &lt;&gt; v0.0.0.0) AND ((WixBundleAction = 7) OR (WixBundleAction = 5))" UninstallArguments="">
<ns0:CommandLine Condition="WixBundleUILevel &lt;= 3" InstallArgument="-q -l &quot;[WixBundleLog].winfsp-uninstaller.log&quot;" RepairArgument="-q" UninstallArgument="-s" />
@@ -43,9 +41,7 @@ Do you want to continue?&quot;" RepairArgument="-q" UninstallArgument="-s" />
<ns0:ExitCode Behavior="forceReboot" Value="4" />
<ns0:ExitCode Behavior="success" Value="5" />
</ns0:ExePackage>
<ns0:MsiPackage SourceFile="bundle\resources\Cryptomator.msi" CacheId="cryptomator-bundle-cryptomator" Visible="no">
<ns0:MsiProperty Name="DISABLEUPDATECHECK" Value="[DISABLEUPDATECHECK]"/>
</ns0:MsiPackage>
<ns0:MsiPackage SourceFile="bundle\resources\Cryptomator.msi" CacheId="cryptomator-bundle-cryptomator" Visible="no" />
<ns0:MsiPackage SourceFile="bundle\resources\winfsp.msi" CacheId="cryptomator-bundle-winfsp" Visible="yes" Permanent="yes" />
</ns0:Chain>
</ns0:Bundle>

View File

@@ -1,18 +0,0 @@
@echo off
:: Batch wrapper for PowerShell script to modify Cryptomator update check settings
:: This is executed as a Custom Action during MSI installation
:: This file must be located in the INSTALLDIR
set "DISABLEUPDATECHECK=%~1"
:: Log for debugging
echo DISABLEUPDATECHECK=%DISABLEUPDATECHECK%
:: Change to INSTALLDIR
cd %~dp0
:: Execute the PowerShell script
powershell.exe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy RemoteSigned -File ".\patchUpdateCheck.ps1"^
-DisableUpdateCheck "%DISABLEUPDATECHECK%"
:: Return the exit code from PowerShell
exit /b %ERRORLEVEL%

View File

@@ -1,58 +0,0 @@
# PowerShell script to modify Cryptomator.cfg to set disableUpdateCheck property
# This script is executed as a Custom Action during MSI installation
# If the DisableUpdateCheck parameter is set to true, it disables the update check in Cryptomator by modifying the Cryptomator.cfg file.
# NOTE: This file must be located in the same directory as set in the MSI property INSTALLDIR
param(
[Parameter(Mandatory)][string]$DisableUpdateCheck
)
try {
# Log parameters for debugging (visible in MSI verbose logs)
Write-Host "DisableUpdateCheck: $DisableUpdateCheck"
# Parse DisableUpdateCheck value (handle various input formats)
$shouldDisable = $false
if ($DisableUpdateCheck) {
$DisableUpdateCheck = $DisableUpdateCheck.Trim().ToLower()
$shouldDisable = ($DisableUpdateCheck -eq 'true') -or ($DisableUpdateCheck -eq '1') -or ($DisableUpdateCheck -eq 'yes')
}
Write-Host "Setting cryptomator.disableUpdateCheck to: $shouldDisable"
if (-not $shouldDisable) {
Write-Host 'Disable-Update-Check property is by default "false". Skipping config modification.'
exit 0
}
# Determine the .cfg file path
$cfgDir = Join-Path $PSScriptRoot 'app'
$cfgFiles = Get-ChildItem -Path $cfgDir -Filter '*.cfg' -File
if ($cfgFiles.Count -eq 0) {
Write-Error "No .cfg file found in directory: $cfgDir"
exit 1
}
foreach ($file in $cfgFiles) {
$cfgFile = $file.FullName
Write-Host "Modifying configuration file: $cfgFile"
# Read the current configuration
$content = Get-Content $cfgFile -Raw -ErrorAction Stop
# Add the new option based on the property value
# Use regular expressions substitutions to replace the property
$searchExpression = '(?<Prefix>java-options=-Dcryptomator\.disableUpdateCheck)=false'
$replacementExpression = '${Prefix}=true'
$content = $content -replace $searchExpression,$replacementExpression
# Write the modified content back
Set-Content -Path $cfgFile -Value $content -NoNewline
Write-Host "Successfully updated $cfgFile"
}
exit 0
}
catch {
Write-Error "Error modifying configuration file: $_"
exit 1
}

View File

@@ -1,18 +1,7 @@
@echo off
:: Batch wrapper for PowerShell script to adjust Windows network settings for the Cryptomator WebDAVAdapter
:: This is executed as a Custom Action during MSI installation
:: This file must be located in the INSTALLDIR
:: Default values for Cryptomator builds
::REPLACE ME
set "LOOPBACK_ALIAS=%1"
:: Log for debugging
echo LOOPBACK_ALIAS=%LOOPBACK_ALIAS%
:: Change to INSTALLDIR
cd %~dp0
:: Execute the PowerShell script
powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy RemoteSigned -File .\patchWebDAV.ps1^
-LoopbackAlias %LOOPBACK_ALIAS%
:: Return the exit code from PowerShell
exit /b %ERRORLEVEL%
powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy RemoteSigned -Command .\patchWebDAV.ps1^
-LoopbackAlias %LOOPBACK_ALIAS%

View File

@@ -1,4 +0,0 @@
win-console=true
win-shortcut=false
win-menu=false
description=Debug Launcher with Console for Cryptomator

15
dist/win/launcher.bat vendored Normal file
View File

@@ -0,0 +1,15 @@
@echo off
java ^
-p "mods" ^
-cp "libs/*" ^
-Dcryptomator.settingsPath="~/AppData/Roaming/Cryptomator/settings.json" ^
-Dcryptomator.ipcSocketPath="~/AppData/Roaming/Cryptomator/ipc.socket" ^
-Dcryptomator.logDir="~/AppData/Roaming/Cryptomator" ^
-Dcryptomator.mountPointsDir="~/Cryptomator" ^
-Dcryptomator.integrationsWin.keychainPaths="~/AppData/Roaming/Cryptomator/keychain.json" ^
-Dcryptomator.integrationsWin.windowsHelloKeychainPaths="~/AppData/Roaming/Cryptomator/windowsHelloKeychain.json" ^
-Xss20m ^
-Xmx512m ^
--enable-preview `
--enable-native-access=org.cryptomator.jfuse.win `
-m org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator

View File

@@ -26,7 +26,6 @@
<?define IconFileEncryptedData= "Cryptomator-Vault.ico" ?>
<?define ProgIdContentType= "application/vnd.cryptomator.encrypted" ?>
<?define CloseApplicationTarget= "cryptomator.exe" ?>
<?define LoopbackAlias= "cryptomator-vault" ?>
<?include $(var.JpConfigDir)/overrides.wxi ?>
@@ -127,18 +126,10 @@
<ns0:Property Id="WixQuietExec64CmdTimeout" Value="20" />
<!-- Note for custom actions: Immediate CAs run BEFORE the files are installed, hence if you depend on installed files, the CAs must be deferred.-->
<!-- Property for controlling update check behavior (can be set via command line) -->
<ns0:Property Id="DISABLEUPDATECHECK" Secure="yes" />
<!-- WebDAV patches -->
<ns0:SetProperty Id="PatchWebDAV" Value="&quot;[INSTALLDIR]patchWebDAV.bat&quot; &quot;$(var.LoopbackAlias)&quot;" Sequence="execute" Before="PatchWebDAV" />
<ns0:SetProperty Id="PatchWebDAV" Value="&quot;[INSTALLDIR]patchWebDAV.bat&quot;" Sequence="execute" Before="PatchWebDAV" />
<ns0:CustomAction Id="PatchWebDAV" BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)" DllEntry="WixQuietExec" Execute="deferred" Return="ignore" Impersonate="no"/>
<!-- Update check configuration -->
<ns0:SetProperty Id="PatchUpdateCheck" Value="&quot;[INSTALLDIR]patchUpdateCheck.bat&quot; &quot;[DISABLEUPDATECHECK]&quot;" Sequence="execute" Before="PatchUpdateCheck" />
<ns0:CustomAction Id="PatchUpdateCheck" BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)" DllEntry="WixQuietExec64" Execute="deferred" Return="ignore" Impersonate="no"/>
<!-- Running App detection and exit -->
<ns0:Property Id="FOUNDRUNNINGAPP" Admin="yes"/>
<util:CloseApplication
@@ -190,8 +181,6 @@
<!-- Skip action on uninstall -->
<!-- TODO: don't skip action, but remove cryptomator alias from hosts file -->
<ns0:Custom Action="PatchWebDAV" After="InstallFiles" Condition="NOT (Installed AND (NOT REINSTALL) AND (NOT UPGRADINGPRODUCTCODE) AND REMOVE)"/>
<!-- Configure update check setting if property is provided -->
<ns0:Custom Action="PatchUpdateCheck" After="PatchWebDAV" Condition="DISABLEUPDATECHECK AND NOT (Installed AND (NOT REINSTALL) AND (NOT UPGRADINGPRODUCTCODE) AND REMOVE)"/>
</ns0:InstallExecuteSequence>
<ns0:InstallUISequence>

View File

@@ -41,7 +41,7 @@ Media Type of the encrypted data files. Default is "application/vnd.cryptomator.
Close Application settings:
- CloseApplicationTarget
Full name of executable to be checked in the close application util. Default is "cryptomator.exe"
Full name of executable to be checkd in the close application util. Default is "cryptomator.exe"
Legacy Installation settings:
- SkipCryptomatorLegacyCheck

49
pom.xml
View File

@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.cryptomator</groupId>
<artifactId>cryptomator</artifactId>
<version>1.18.0</version>
<version>1.17.0-SNAPSHOT</version>
<name>Cryptomator Desktop App</name>
<organization>
@@ -34,18 +34,18 @@
<!-- cryptomator dependencies -->
<cryptomator.cryptofs.version>2.9.0</cryptomator.cryptofs.version>
<cryptomator.integrations.version>1.7.0</cryptomator.integrations.version>
<cryptomator.integrations.win.version>1.5.1</cryptomator.integrations.win.version>
<cryptomator.integrations.mac.version>1.4.1</cryptomator.integrations.mac.version>
<cryptomator.integrations.linux.version>1.6.1</cryptomator.integrations.linux.version>
<cryptomator.fuse.version>5.1.0</cryptomator.fuse.version>
<cryptomator.webdav.version>3.0.0</cryptomator.webdav.version>
<cryptomator.integrations.version>1.6.0</cryptomator.integrations.version>
<cryptomator.integrations.win.version>1.5.0</cryptomator.integrations.win.version>
<cryptomator.integrations.mac.version>1.4.0</cryptomator.integrations.mac.version>
<cryptomator.integrations.linux.version>1.6.0</cryptomator.integrations.linux.version>
<cryptomator.fuse.version>5.0.5</cryptomator.fuse.version>
<cryptomator.webdav.version>2.0.10</cryptomator.webdav.version>
<!-- 3rd party dependencies -->
<commons-lang3.version>3.18.0</commons-lang3.version>
<dagger.version>2.57.1</dagger.version>
<commons-lang3.version>3.17.0</commons-lang3.version>
<dagger.version>2.56.2</dagger.version>
<easybind.version>2.2</easybind.version>
<jackson.version>2.20.0</jackson.version>
<jackson.version>2.19.1</jackson.version>
<javafx.version>24.0.1</javafx.version>
<jwt.version>4.5.0</jwt.version>
<nimbus-jose.version>9.37.3</nimbus-jose.version>
@@ -55,26 +55,37 @@
<zxcvbn.version>1.9.0</zxcvbn.version>
<!-- test dependencies -->
<junit.jupiter.version>5.13.4</junit.jupiter.version>
<mockito.version>5.20.0</mockito.version>
<junit.jupiter.version>5.13.1</junit.jupiter.version>
<mockito.version>5.18.0</mockito.version>
<hamcrest.version>3.0</hamcrest.version>
<!-- build-time dependencies -->
<jetbrains.annotations.version>26.0.2-1</jetbrains.annotations.version>
<dependency-check.version>12.1.5</dependency-check.version>
<jetbrains.annotations.version>26.0.2</jetbrains.annotations.version>
<dependency-check.version>12.1.3</dependency-check.version>
<jacoco.version>0.8.13</jacoco.version>
<license-generator.version>2.7.0</license-generator.version>
<license-generator.version>2.5.0</license-generator.version>
<junit-tree-reporter.version>1.4.0</junit-tree-reporter.version>
<mvn-compiler.version>3.14.1</mvn-compiler.version>
<mvn-compiler.version>3.14.0</mvn-compiler.version>
<mvn-resources.version>3.3.1</mvn-resources.version>
<mvn-dependency.version>3.8.1</mvn-dependency.version>
<mvn-surefire.version>3.5.4</mvn-surefire.version>
<mvn-surefire.version>3.5.3</mvn-surefire.version>
<mvn-jar.version>3.4.2</mvn-jar.version>
<!-- Property used by surefire to determine jacoco engine -->
<surefire.jacoco.args></surefire.jacoco.args>
</properties>
<!-- TODO: Remove once webdav version 2.0.11 is released -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>webdav-nio-adapter-servlet</artifactId>
<version>1.2.9</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Cryptomator Libs -->
<dependency>
@@ -214,7 +225,7 @@
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.2.2</version>
<version>3.2.1</version>
</dependency>
<!-- JUnit / Mockito / Hamcrest -->
<dependency>
@@ -244,7 +255,7 @@
<dependency>
<groupId>com.google.jimfs</groupId>
<artifactId>jimfs</artifactId>
<version>1.3.1</version>
<version>1.3.0</version>
<scope>test</scope>
</dependency>

View File

@@ -25,8 +25,6 @@ import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.NodeOrientation;
import java.nio.file.Path;
import java.time.Instant;
import java.util.function.Consumer;
@@ -77,7 +75,6 @@ public class Settings {
public final BooleanProperty checkForUpdates;
public final ObjectProperty<Instant> lastUpdateCheckReminder;
public final ObjectProperty<Instant> lastSuccessfulUpdateCheck;
public final ObjectProperty<Path> previouslyUsedVaultDirectory;
private Consumer<Settings> saveCmd;
@@ -117,7 +114,6 @@ public class Settings {
this.checkForUpdates = new SimpleBooleanProperty(this, "checkForUpdates", json.checkForUpdatesEnabled);
this.lastUpdateCheckReminder = new SimpleObjectProperty<>(this, "lastUpdateCheckReminder", json.lastReminderForUpdateCheck);
this.lastSuccessfulUpdateCheck = new SimpleObjectProperty<>(this, "lastSuccessfulUpdateCheck", json.lastSuccessfulUpdateCheck);
this.previouslyUsedVaultDirectory = new SimpleObjectProperty<>(this, "previouslyUsedVaultDirectory", json.previouslyUsedVaultDirectory);
this.directories.addAll(json.directories.stream().map(VaultSettings::new).toList());
@@ -147,7 +143,6 @@ public class Settings {
checkForUpdates.addListener(this::somethingChanged);
lastUpdateCheckReminder.addListener(this::somethingChanged);
lastSuccessfulUpdateCheck.addListener(this::somethingChanged);
previouslyUsedVaultDirectory.addListener(this::somethingChanged);
}
@SuppressWarnings("deprecation")
@@ -209,7 +204,6 @@ public class Settings {
json.checkForUpdatesEnabled = checkForUpdates.get();
json.lastReminderForUpdateCheck = lastUpdateCheckReminder.get();
json.lastSuccessfulUpdateCheck = lastSuccessfulUpdateCheck.get();
json.previouslyUsedVaultDirectory = previouslyUsedVaultDirectory.get();
return json;
}

View File

@@ -5,7 +5,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.nio.file.Path;
import java.time.Instant;
import java.util.List;
@@ -93,7 +92,4 @@ class SettingsJson {
@JsonProperty("quickAccessService")
String quickAccessService = Settings.DEFAULT_QUICKACCESS_SERVICE;
@JsonProperty("previouslyUsedVaultDirectory")
Path previouslyUsedVaultDirectory;
}

View File

@@ -9,13 +9,13 @@
package org.cryptomator.common.vaults;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.Constants;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
import org.cryptomator.cryptofs.DirStructure;
import org.cryptomator.cryptofs.migration.Migrators;
import org.cryptomator.integrations.mount.MountService;
import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -125,7 +125,7 @@ public class VaultListManager {
vaultSettings.lastKnownKeyLoader.set(keyIdScheme);
}
} else if (vaultState == NEEDS_MIGRATION) {
vaultSettings.lastKnownKeyLoader.set(MasterkeyFileLoadingStrategy.SCHEME);
vaultSettings.lastKnownKeyLoader.set(Constants.DEFAULT_KEY_ID.toString());
}
return vaultComponentFactory.create(vaultSettings, wrapper, vaultState, null).vault();
} catch (IOException e) {

View File

@@ -53,26 +53,18 @@ class Server implements IpcCommunicator {
@Override
public void listen(IpcMessageListener listener, Executor executor) {
executor.execute(() -> {
int errorCount = 0;
while (serverSocketChannel.isOpen()) {
try (var ch = serverSocketChannel.accept()) {
while (ch.isConnected()) {
var msg = IpcMessage.receive(ch);
listener.handleMessage(msg);
}
errorCount = 0;
} catch (AsynchronousCloseException e) {
LOG.info("Closing server socket due to closed channel.");
return; // serverSocketChannel closed or listener interrupted
} catch (EOFException | ClosedChannelException e) {
// continue with next connected client
} catch (IOException e) {
errorCount++;
LOG.error("Failed to read IPC message", e);
if(errorCount > 100) { //apparently something is broken, prevent log spam
LOG.info("Closing server socket due to too many failed requests.");
return;
}
}
}
});

View File

@@ -90,9 +90,6 @@ public class LogbackConfigurator extends ContextAwareBase implements Configurato
// configure fuse file locking logger:
Logger fuseLocking = context.getLogger("org.cryptomator.frontend.fuse.locks");
fuseLocking.setLevel(Level.OFF);
//deactivate kwallet unsettling message
Logger kdeWallet = context.getLogger("org.purejava.kwallet.freedesktop.dbus.handlers");
kdeWallet.setLevel(Level.OFF);
}
return ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY;
}

View File

@@ -26,7 +26,7 @@ public class CreateNewVaultExpertSettingsController implements FxController {
public static final int MAX_SHORTENING_THRESHOLD = 220;
public static final int MIN_SHORTENING_THRESHOLD = 36;
private static final String DOCS_NAME_SHORTENING_URL = "https://docs.cryptomator.org/security/vault/#name-shortening";
private static final String DOCS_NAME_SHORTENING_URL = "https://docs.cryptomator.org/security/architecture/#name-shortening";
private final Stage window;
private final Lazy<Application> application;

View File

@@ -4,7 +4,6 @@ import dagger.Lazy;
import org.cryptomator.common.ObservableUtil;
import org.cryptomator.common.locationpresets.LocationPreset;
import org.cryptomator.common.locationpresets.LocationPresetsProvider;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
@@ -39,7 +38,6 @@ import javafx.stage.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;
@@ -66,7 +64,6 @@ public class CreateNewVaultLocationController implements FxController {
private final BooleanProperty loadingPresetLocations = new SimpleBooleanProperty(false);
private final ObservableList<Node> radioButtons;
private final ObservableList<Node> sortedRadioButtons;
private final Settings settings;
private Path customVaultPath = DEFAULT_CUSTOM_VAULT_PATH;
@@ -85,7 +82,6 @@ public class CreateNewVaultLocationController implements FxController {
@FxmlScene(FxmlFile.ADDVAULT_NEW_EXPERT_SETTINGS) Lazy<Scene> chooseExpertSettingsScene, //
ObjectProperty<Path> vaultPath, //
@Named("vaultName") StringProperty vaultName, //
Settings settings, //
ExecutorService backgroundExecutor, ResourceBundle resourceBundle) {
this.window = window;
this.chooseNameScene = chooseNameScene;
@@ -100,18 +96,6 @@ public class CreateNewVaultLocationController implements FxController {
this.usePresetPath = new SimpleBooleanProperty();
this.radioButtons = FXCollections.observableArrayList();
this.sortedRadioButtons = radioButtons.sorted(this::compareLocationPresets);
this.settings = settings;
Path previouslyUsedDirectory = settings.previouslyUsedVaultDirectory.get();
if (previouslyUsedDirectory != null) {
try {
if (Files.exists(previouslyUsedDirectory) && Files.isDirectory(previouslyUsedDirectory) && isActuallyWritable(previouslyUsedDirectory)) {
this.customVaultPath = previouslyUsedDirectory;
}
} catch (InvalidPathException | NullPointerException e) {
LOG.warn("Invalid previously used vault directory path: {}", previouslyUsedDirectory, e);
}
}
}
private VaultPathStatus validatePath(Path p) throws NullPointerException {
@@ -212,12 +196,6 @@ public class CreateNewVaultLocationController implements FxController {
@FXML
public void next() {
if (validVaultPath.getValue()) {
if (this.getVaultPath() != null) {
Path parentPath = this.getVaultPath().getParent();
if (parentPath != null) {
this.settings.previouslyUsedVaultDirectory.setValue(parentPath);
}
}
window.setScene(chooseExpertSettingsScene.get());
}
}

View File

@@ -49,7 +49,7 @@ public class EventViewController implements FxController {
}
/**
* Comparison method for the lru cache. During comparison the map is accessed.
* Comparison method for the lru cache. During comparsion the map is accessed.
* First the entries are compared by the event timestamp, then vaultId, then identifying path and lastly by class name.
*
* @param left an entry of a {@link FSEventBucket} and its content

View File

@@ -110,7 +110,7 @@ public class FxApplicationTerminator {
} else if (settings.autoCloseVaults.get() && !preventQuitWithGracefulLock.get()) {
var lockAllTask = vaultService.createLockAllTask(vaults.filtered(Vault::isUnlocked), false);
lockAllTask.setOnSucceeded(event -> {
LOG.info("Locked remaining vaults was successful.");
LOG.info("Locked remaining vaults was succesful.");
exitingResponse.performQuit();
});
lockAllTask.setOnFailed(event -> {

View File

@@ -46,16 +46,15 @@ public interface KeyLoadingStrategy extends MasterkeyLoader {
/**
* Determines whether the provided key loader scheme corresponds to a Masterkey File Vault.
* <p>
* This method checks if the {@code keyLoader} parameter starts with the known Masterkey File Vault scheme
* This method checks if the {@code keyLoader} parameter matches the known Masterkey File Vault scheme
* {@link MasterkeyFileLoadingStrategy#SCHEME}.
* This allows identifying not only exact matches but also variants or extended schemes based on the Masterkey scheme.
* </p>
*
* @param keyLoader A string representing the key loader scheme to be checked.
* @return {@code true} if the given key loader scheme starts with the Masterkey File Vault scheme; {@code false} otherwise.
* @return {@code true} if the given key loader scheme represents a Masterkey File Vault; {@code false} otherwise.
*/
static boolean isMasterkeyFileVault(String keyLoader) {
return keyLoader.startsWith(MasterkeyFileLoadingStrategy.SCHEME);
return MasterkeyFileLoadingStrategy.SCHEME.equals(keyLoader);
}
/**

View File

@@ -19,7 +19,7 @@ public class ShareVaultController implements FxController {
private static final String SCHEME_PREFIX = "hub+";
private static final String VISIT_HUB_URL = "https://cryptomator.org/hub/";
private static final String BEST_PRACTICES_URL = "https://docs.cryptomator.org/security/best-practices/#sharing-of-vaults";
private static final String BEST_PRACTICES_URL = "https://docs.cryptomator.org/en/latest/security/best-practices/#sharing-of-vaults";
private final Stage window;
private final Lazy<Application> application;

View File

@@ -62,9 +62,9 @@ addvaultwizard.new.locationIsOk=الموقع المناسب للمخزن الخ
addvaultwizard.new.invalidName=اسم المخزن غير صالح
addvaultwizard.new.validName=اسم المخزن صالح
addvaultwizard.new.validCharacters.message=قد يحتوي اسم المخزن على الأحرف التالية:
addvaultwizard.new.validCharacters.chars=أحرف لكن دون علامات (#, $, !, @...)
addvaultwizard.new.validCharacters.numbers=الأرقام
addvaultwizard.new.validCharacters.dashes=ناقص (%s) أو شِرْطَةٌ سفلية (%s)
addvaultwizard.new.validCharacters.chars=أحرف الكلمات (أمثلة: a, ж, )
addvaultwizard.new.validCharacters.numbers=الأعداد
addvaultwizard.new.validCharacters.dashes=الشرطة (%s) أو الشرطة السفلية (%s)
### Expert Settings
addvaultwizard.new.expertSettings.enableExpertSettingsCheckbox=تمكين إعدادات الخبراء
addvaultwizard.new.expertSettings.shorteningThreshold.invalid=أدخل قيمة بين 36 و 220 (الافتراضي 220)
@@ -319,7 +319,7 @@ preferences.volume.feature.readOnly=تحميل للقراءة فقط
## Updates
preferences.updates=تحديثات
preferences.updates.currentVersion=الإصدار الحالي: %s
preferences.updates.autoUpdateCheck=التحقق من وجود تحديثات تلقائياً
preferences.updates.autoUpdateCheck=تحقق من التحديثات اوتوماتيكيا
preferences.updates.checkNowBtn=تحقق الان
preferences.updates.updateAvailable=التحديث إلى الإصدار %s متاح.
preferences.updates.lastUpdateCheck=آخر فحص: %s
@@ -395,7 +395,6 @@ main.vaultlist.contextMenu.vaultoptions=إظهار خيارات المخزن
main.vaultlist.contextMenu.reveal=اظهار القرص
main.vaultlist.addVaultBtn.menuItemNew=إنشاء مخزن جديد...
main.vaultlist.addVaultBtn.menuItemExisting=افتح مخزن موجود...
main.vaultlist.showEventsButton.tooltip=عرض الإشعارات
##Notificaition
main.notification.updateAvailable=هناك تحديث متاح.
main.notification.support=دعم Cryptomator.
@@ -424,9 +423,7 @@ main.vaultDetail.stats=إحصائيات الخزنة
main.vaultDetail.locateEncryptedFileBtn=تحديد موقع الملف المشفر
main.vaultDetail.locateEncryptedFileBtn.tooltip=اختر ملف من خزانتك لتحديد مكان نظيره المشفر
main.vaultDetail.encryptedPathsCopied=تم نسخ مسارات الملفات إلى الحافظة!
main.vaultDetail.locateEncrypted.filePickerTitle=اختر الملَف من الخزنة
main.vaultDetail.decryptName.buttonLabel=فك تشفير اسم الملف
main.vaultDetail.decryptName.tooltip=اختر ملَف مشفر لفك تشفير اسمه
### Missing
main.vaultDetail.missing.info=لم يتمكن Cryptomator من العثور على خزنة في هذا المسار.
main.vaultDetail.missing.recheck=إعادة الفحص
@@ -476,7 +473,7 @@ vaultOptions.mount.mountPoint.custom=استخدام المجلد المختار
vaultOptions.mount.mountPoint.directoryPickerButton=اختر…
vaultOptions.mount.mountPoint.directoryPickerTitle=إختر مجلد
vaultOptions.mount.volumeType.default=الافتراضي (%s)
vaultOptions.mount.volumeType.restartRequired=لاستخدام هذا النوع من وحدة التخزين يحتاج Cryptomator إلى إعادة تشغيل.
vaultOptions.mount.volumeType.restartRequired=لاستخدام هذا النوع من وحدة التخزين يحتاج Cryptomator إلى إعادة تشغيله.
vaultOptions.mount.volume.tcp.port=منفذ TCP
vaultOptions.mount.volume.type=‮نوع وحدة التخزين
## Master Key
@@ -583,40 +580,7 @@ shareVault.hub.instruction.2=2. امنح الوصول لعضو الفريق في
shareVault.hub.openHub=زيارة Cryptomator Hub
# Decrypt File Names
decryptNames.title=فك تشفير اسم الملَف
decryptNames.filePicker.title=اختر ملَف مشفر
decryptNames.filePicker.extensionDescription=ملف مشفر
decryptNames.copyTable.tooltip=نسخ الجدول
decryptNames.clearTable.tooltip=مسح الجدول
decryptNames.copyHint=نسخ محتوى الخلية مع %s
decryptNames.dropZone.message=إسقاط الملفات أو انقر لتحديد
decryptNames.dropZone.error.vaultInternalFiles=مخزن الملفات الداخلية مع عدم تحديد اسم قابل للتشفير
decryptNames.dropZone.error.foreignFiles=الملفات لا تنتمي إلى مخزن "%s"
decryptNames.dropZone.error.noDirIdBackup=مسار الملفات المحددة لا يحتوي على ملَف dirId.c9r
decryptNames.dropZone.error.generic=فشل فك تشفير أسماء الملفات
# Event View
eventView.title=أحداث
eventView.filter.allVaults=الكل
eventView.clearListButton.tooltip=تفريغ القائمة
## event list entries
eventView.entry.vaultLocked.description=فتح "%s" للحصول على التفاصيل
eventView.entry.conflictResolved.message=تم حل التضارب
eventView.entry.conflictResolved.showDecrypted=إظهار الملف غير المشفر
eventView.entry.conflictResolved.copyDecrypted=نسخ المسار غير المشفر
eventView.entry.conflict.message=فشل حل التضارب
eventView.entry.conflict.showDecrypted=إظهار الملَف غير المشفر الأصلي
eventView.entry.conflict.copyDecrypted=نسخ المسار غير المشفر والأصلي
eventView.entry.conflict.showEncrypted=إظهار ملف متضارب ومشفر
eventView.entry.conflict.copyEncrypted=نسخ مسار التشفير المتعارض
eventView.entry.decryptionFailed.message=فشل فك التشفير
eventView.entry.decryptionFailed.showEncrypted=عرض ملَف المشفر
eventView.entry.decryptionFailed.copyEncrypted=نسخ مسار المشفر
eventView.entry.brokenDirFile.message=رابط الدليل المكسور
eventView.entry.brokenDirFile.showEncrypted=إظهار الرابط المكسور، المشفر
eventView.entry.brokenDirFile.copyEncrypted=نسخ مسار الرابط المكسور
eventView.entry.brokenFileNode.message=عقدة ملفات النظام التافلة
eventView.entry.brokenFileNode.showEncrypted=عرض العقدة المشفّرة التافلة
eventView.entry.brokenFileNode.copyEncrypted=نسخ مسار العقدة المشفّرة التافلة
eventView.entry.brokenFileNode.copyDecrypted=نسخ المسار غير المشفر

View File

@@ -283,7 +283,6 @@ preferences.title=Præferencer
## General
preferences.general=Generelt
preferences.general.startHidden=Skjul vinduet når Cryptomator starter
preferences.general.autoCloseVaults=Lås bokse uden at spørge ved afslutning af applikationen
preferences.general.debugLogging=Aktivér fejllogning
preferences.general.debugDirectory=Vis logfiler
preferences.general.autoStart=Start Cryptomator automatisk ved opstart
@@ -302,7 +301,6 @@ preferences.interface.interfaceOrientation=Brugerflade retning
preferences.interface.interfaceOrientation.ltr=Venstre til højre
preferences.interface.interfaceOrientation.rtl=Højre til venstre
preferences.interface.showTrayIcon=Vis ikon i system-bakken (kræver genstart)
preferences.interface.compactMode=Aktivér kompakt bokse-liste
## Volume
preferences.volume=Virtuelt drev
preferences.volume.type=Standard Drev Type
@@ -322,13 +320,7 @@ preferences.updates.currentVersion=Nuværende version: %s
preferences.updates.autoUpdateCheck=Søg automatisk efter opdateringer
preferences.updates.checkNowBtn=Kontrollér nu
preferences.updates.updateAvailable=Opdatering til version %s er tilgængelig.
preferences.updates.lastUpdateCheck=Seneste tjek: %s
preferences.updates.lastUpdateCheck.never=aldrig
preferences.updates.lastUpdateCheck.recently=for nylig
preferences.updates.lastUpdateCheck.daysAgo=%s dage siden
preferences.updates.lastUpdateCheck.hoursAgo=%s timer siden
preferences.updates.checkFailed=Søgning efter opdateringer fejlede. Tjek din internetforbindelse eller forsøg igen senere.
preferences.updates.upToDate=Cryptomator er opdateret.
## Contribution
preferences.contribute=Støt os
@@ -336,14 +328,8 @@ preferences.contribute.registeredFor=Registreret supporter-certifikat for %s
preferences.contribute.noCertificate=Hjælp Cryptomator, og modtag et supporter-certifikat. Det er ligesom en license-nøgle, men til fantastiske mennesker som bruger fri software. ;-)
preferences.contribute.getCertificate=Har du ikke et allerede? Se her hvordan du kan få et.
preferences.contribute.promptText=Indsæt koden for supporter-certifikatet her
preferences.contribute.thankYou=Tak fordi du støtter Cryptomators open source-udvikling!
preferences.contribute.donate=Donér
preferences.contribute.sponsor=Sponsor
### Remove License Key Dialog
removeCert.title=Fjern certifikat
removeCert.message=Fjern supporter-certifikat?
removeCert.description=Cryptomators kernefunktioner påvirkes ikke af dette. Hverken adgangen er begrænset, eller sikkerhedsniveauet sænket til dine bokse.
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -393,9 +379,6 @@ main.vaultlist.contextMenu.unlock=Lås op…
main.vaultlist.contextMenu.unlockNow=Lås op nu
main.vaultlist.contextMenu.vaultoptions=Vis boksindstillinger
main.vaultlist.contextMenu.reveal=Vis drev
main.vaultlist.addVaultBtn.menuItemNew=Opret ny boks...
main.vaultlist.addVaultBtn.menuItemExisting=Åbn eksisterende boks...
main.vaultlist.showEventsButton.tooltip=Åbn begivenhedsvisning
##Notificaition
main.notification.updateAvailable=Opdatering er tilgængelig.
main.notification.support=Støt Cryptomator.
@@ -421,12 +404,9 @@ main.vaultDetail.throughput.idle=afventer
main.vaultDetail.throughput.kbps=%.1f KiB/s
main.vaultDetail.throughput.mbps=%.1f MiB/s
main.vaultDetail.stats=Boks statistik
main.vaultDetail.locateEncryptedFileBtn=Find krypteret fil
main.vaultDetail.locateEncryptedFileBtn=Find Krypteret Fil
main.vaultDetail.locateEncryptedFileBtn.tooltip=Vælg en fil fra din boks for at finde dens krypterede modpart
main.vaultDetail.encryptedPathsCopied=Stier kopieret!
main.vaultDetail.locateEncrypted.filePickerTitle=Vælg fil inde i boks
main.vaultDetail.decryptName.buttonLabel=Dekryptér filnavn
main.vaultDetail.decryptName.tooltip=Vælg en krypteret fil i boks for at dekryptere dets navn
### Missing
main.vaultDetail.missing.info=Cryptomator kunne ikke finde en boks på denne sti.
main.vaultDetail.missing.recheck=Kontrollér igen
@@ -551,15 +531,9 @@ updateReminder.yesOnce=Ja, én gang
updateReminder.yesAutomatically=Ja, automatisk
#Dokany Support End
dokanySupportEnd.title=Meddelelse om udfasning
dokanySupportEnd.message=Understøttelse slutter for Dokany
dokanySupportEnd.description=Drevtypen Dokany understøttes ikke længere af Cryptomator. Dine indstillinger er justeret for at bruge standard drevtypen nu. Du kan se standardtypen i indstillingerne.
dokanySupportEnd.preferencesBtn=Åbn Indstillinger
#Retry If Readonly
retryIfReadonly.title=Begrænset boksadgang
retryIfReadonly.message=Ingen skriveadgang til boksens mappe
retryIfReadonly.description=Cryptomator kan ikke skrive til boksens mappe. Du kan ændre boksen til at være skrivebeskyttet og prøve igen. Denne indstilling kan være deaktiveret i boksens indstillinger.
# Share Vault
shareVault.title=Del Boks
@@ -582,11 +556,7 @@ shareVault.hub.instruction.2=2. Giv adgang til holdmedlem i Cryptomator Hub.
shareVault.hub.openHub=Åben Cryptomator Hub
# Decrypt File Names
decryptNames.title=Dekryptér Filnavne
decryptNames.copyHint=Kopiér celleindhold med %s
decryptNames.dropZone.message=Slip filer eller klik for at vælge
# Event View
eventView.title=Begivenheder
## event list entries

View File

@@ -395,7 +395,6 @@ main.vaultlist.contextMenu.vaultoptions=Εμφάνιση επιλογών Vault
main.vaultlist.contextMenu.reveal=Αποκάλυψη εικονικού δίσκου
main.vaultlist.addVaultBtn.menuItemNew=Δημιουργία Νέας Κρύπτης...
main.vaultlist.addVaultBtn.menuItemExisting=Άνοιγμα Υπάρχοντος Κρύπτης...
main.vaultlist.showEventsButton.tooltip=Άνοιγμα προβολής συμβάντων
##Notificaition
main.notification.updateAvailable=Η ενημέρωση είναι διαθέσιμη.
main.notification.support=Υποστήριξη Cryptomator.
@@ -424,9 +423,6 @@ main.vaultDetail.stats=Στατιστικά Vault
main.vaultDetail.locateEncryptedFileBtn=Εντοπισμός Κρυπτογραφημένου Αρχείου
main.vaultDetail.locateEncryptedFileBtn.tooltip=Επιλέξτε ένα αρχείο από την κρύπτη σας για να εντοπίσετε το κρυπτογραφημένο αντίστοιχο
main.vaultDetail.encryptedPathsCopied=Οι Διαδρομές Αντιγράφηκαν στο Πρόχειρο!
main.vaultDetail.locateEncrypted.filePickerTitle=Επιλογή Αρχείου Μέσα Στην Κρύπτη
main.vaultDetail.decryptName.buttonLabel=Αποκρυπτογράφηση Ονόματος Αρχείου
main.vaultDetail.decryptName.tooltip=Επιλέξτε ένα κρυπτογραφημένο αρχείο κρύπτης για να αποκρυπτογραφήσετε το όνομά του
### Missing
main.vaultDetail.missing.info=Cryptomator δεν βρήκε vault σε αυτόν τον κατάλογο.
main.vaultDetail.missing.recheck=Επανέλεγχος
@@ -583,40 +579,8 @@ shareVault.hub.instruction.2=2. Παραχωρήστε πρόσβαση σε μ
shareVault.hub.openHub=Ανοίξτε το Cryptomator Hub
# Decrypt File Names
decryptNames.title=Αποκρυπτογράφηση Ονομάτων Αρχείων
decryptNames.filePicker.title=Επιλογή κρυπτογραφημένου αρχείου
decryptNames.filePicker.extensionDescription=Κρυπτογραφημένο κρυπτογραφημένου αρχείο Cryptomator
decryptNames.copyTable.tooltip=Αντιγραφή πίνακα
decryptNames.clearTable.tooltip=Εκκαθάριση πίνακα
decryptNames.copyHint=Αντιγραφή περιεχομένου κελιού με %s
decryptNames.dropZone.message=Απόθεση αρχείων ή κλικ για επιλογή
decryptNames.dropZone.error.vaultInternalFiles=Εσωτερικά αρχεία κρύπτης χωρίς να επιλεχθεί όνομα αποκρυπτογράφησης
decryptNames.dropZone.error.foreignFiles=Τα αρχεία δεν ανήκουν στην κρύπτη "%s"
decryptNames.dropZone.error.noDirIdBackup=Ο κατάλογος των επιλεγμένων αρχείων δεν περιέχει αρχείο dirId.c9r
decryptNames.dropZone.error.generic=Αποτυχία αποκρυπτογράφησης ονομάτων αρχείων
# Event View
eventView.title=Συμβάντα
eventView.filter.allVaults=Όλες
eventView.clearListButton.tooltip=Εκκαθάριση λίστας
## event list entries
eventView.entry.vaultLocked.description=Ξεκλείδωμα "%s" για λεπτομέρειες
eventView.entry.conflictResolved.message=Επίλυση σύγκρουσης
eventView.entry.conflictResolved.showDecrypted=Εμφάνιση αποκρυπτογραφημένου αρχείου
eventView.entry.conflictResolved.copyDecrypted=Αντιγραφή αποκρυπτογραφημένης διαδρομής
eventView.entry.conflict.message=Η επίλυση συγκρούσεων απέτυχε
eventView.entry.conflict.showDecrypted=Εμφάνιση αποκρυπτογραφημένων, αρχικό αρχείο
eventView.entry.conflict.copyDecrypted=Αντιγραφή αποκρυπτογραφημένων, αρχική διαδρομή
eventView.entry.conflict.showEncrypted=Εμφάνιση αντικρουόμενου, κρυπτογραφημένο αρχείο
eventView.entry.conflict.copyEncrypted=Αντιγραφή σύγκρουσης, κρυπτογραφημένη διαδρομή
eventView.entry.decryptionFailed.message=Η αποκρυπτογράφηση απέτυχε
eventView.entry.decryptionFailed.showEncrypted=Εμφάνιση κρυπτογραφημένου αρχείου
eventView.entry.decryptionFailed.copyEncrypted=Αντιγραφή κρυπτογραφημένης διαδρομής
eventView.entry.brokenDirFile.message=Μη λειτουργικός σύνδεσμος καταλόγου
eventView.entry.brokenDirFile.showEncrypted=Εμφάνιση μη λειτουργικού, κρυπτογραφημένου συνδέσμου
eventView.entry.brokenDirFile.copyEncrypted=Αντιγραφή διαδρομής του μη λειτουργικού συνδέσμου
eventView.entry.brokenFileNode.message=Μη λειτουργικός κόμβος συστήματος αρχείων
eventView.entry.brokenFileNode.showEncrypted=Εμφάνιση μη λειτουργικού, κρυπτογραφημένου κόμβου
eventView.entry.brokenFileNode.copyEncrypted=Αντιγραφή διαδρομής του μη λειτουργικού, κρυπτογραφημένου κόμβου
eventView.entry.brokenFileNode.copyDecrypted=Αντιγραφή αποκρυπτογραφημένης διαδρομής

View File

@@ -590,7 +590,6 @@ decryptNames.copyTable.tooltip=Copier le tableau
decryptNames.clearTable.tooltip=Effacer le tableau
decryptNames.copyHint=Copier le contenu de la cellule avec %s
decryptNames.dropZone.message=Déposer des fichiers ou cliquer pour en sélectionner
decryptNames.dropZone.error.vaultInternalFiles=Fichiers internes du coffre sans nom déchiffrable sélectionnés
decryptNames.dropZone.error.foreignFiles=Les fichiers n'appartiennent pas au coffre « %s »
decryptNames.dropZone.error.noDirIdBackup=Le répertoire des fichiers sélectionnés ne contient pas de fichier dirId.c9r
decryptNames.dropZone.error.generic=Impossible de déchiffrer les noms de fichiers

View File

@@ -588,10 +588,8 @@ decryptNames.filePicker.title=암호화된 파일 선택
decryptNames.filePicker.extensionDescription=Cryptomator로 암호화된 파일
decryptNames.copyTable.tooltip=테이블 복사
decryptNames.clearTable.tooltip=테이블 비우기
decryptNames.copyHint=%s로 셀 내용 복사하기
decryptNames.dropZone.message=파일을 여기에 드롭하거나 클릭하세요
decryptNames.dropZone.error.vaultInternalFiles=복호화 가능한 이름이 선택되지 않은 Vailt 내부 파일
decryptNames.dropZone.error.foreignFiles=Vault "%s"에 포함되지 않은 파일
decryptNames.dropZone.error.noDirIdBackup=선택된 파일 폴더에 dirId.c9r 파일이 포함되어 있지 않습니다
decryptNames.dropZone.error.generic=파일 이름 복호화 실패

View File

@@ -395,7 +395,6 @@ main.vaultlist.contextMenu.vaultoptions=Pokaż opcje sejfu
main.vaultlist.contextMenu.reveal=Otwórz lokalizację
main.vaultlist.addVaultBtn.menuItemNew=Utwórz Nowy Sejf...
main.vaultlist.addVaultBtn.menuItemExisting=Otwórz Istniejący Sejf...
main.vaultlist.showEventsButton.tooltip=Otwórz widok wydarzeń
##Notificaition
main.notification.updateAvailable=Dostępna aktualizacja.
main.notification.support=Wspomóż Cryptomatora.
@@ -424,9 +423,6 @@ main.vaultDetail.stats=Statystyki sejfu
main.vaultDetail.locateEncryptedFileBtn=Zlokalizuj zaszyfrowany plik
main.vaultDetail.locateEncryptedFileBtn.tooltip=Wybierz plik z sejfu, aby zlokalizować jego zaszyfrowany odpowiednik
main.vaultDetail.encryptedPathsCopied=Ścieżki skopiowane do schowka!
main.vaultDetail.locateEncrypted.filePickerTitle=Wybierz plik wewnątrz sejfu
main.vaultDetail.decryptName.buttonLabel=Odszyfruj nazwę pliku
main.vaultDetail.decryptName.tooltip=Wybierz zaszyfrowany plik sejfu do odszyfrowania jego nazwy
### Missing
main.vaultDetail.missing.info=Cryptomator nie mógł znaleźć sejfu w tej lokalizacji.
main.vaultDetail.missing.recheck=Ponów próbę
@@ -583,40 +579,7 @@ shareVault.hub.instruction.2=2. Udziel dostępu członkowi zespołu w Cryptomato
shareVault.hub.openHub=Otwórz Cryptomator Hub
# Decrypt File Names
decryptNames.title=Odszyfruj nazwy plików
decryptNames.filePicker.title=Wybierz zaszyfrowany plik
decryptNames.filePicker.extensionDescription=Zaszyfrowany plik Cryptomator
decryptNames.copyTable.tooltip=Kopiuj tabelę
decryptNames.clearTable.tooltip=Wyczyść tabelę
decryptNames.copyHint=Kopiuj zawartość komórki z %s
decryptNames.dropZone.message=Upuść pliki lub kliknij, aby wybrać
decryptNames.dropZone.error.vaultInternalFiles=Wybrano wewnętrzne pliki sejfu z nazwami niemożliwymi do odszyfrowania
decryptNames.dropZone.error.foreignFiles=Pliki nie należą do sejfu "%s"
decryptNames.dropZone.error.noDirIdBackup=Katalog wybranych plików nie zawiera pliku dirId.c9r
decryptNames.dropZone.error.generic=Nie udało się odszyfrować nazw plików
# Event View
eventView.title=Zdarzenia
eventView.filter.allVaults=Wszystkie
eventView.clearListButton.tooltip=Wyczyść listę
## event list entries
eventView.entry.vaultLocked.description=Odblokuj "%s" po szczegóły
eventView.entry.conflictResolved.message=Konflikt rozwiązany
eventView.entry.conflictResolved.showDecrypted=Pokaż odszyfrowany plik
eventView.entry.conflictResolved.copyDecrypted=Kopiuj odszyfrowaną ścieżkę
eventView.entry.conflict.message=Rozwiązywanie konfliktu nie powiodło się
eventView.entry.conflict.showDecrypted=Pokaż odszyfrowany, oryginalny plik
eventView.entry.conflict.copyDecrypted=Kopiuj odszyfrowaną, oryginalną ścieżkę
eventView.entry.conflict.showEncrypted=Pokaż sprzeczny, zaszyfrowany plik
eventView.entry.conflict.copyEncrypted=Kopiuj sprzeczną, zaszyfrowaną ścieżkę
eventView.entry.decryptionFailed.message=Odszyfrowywanie nie powiodło się
eventView.entry.decryptionFailed.showEncrypted=Pokaż zaszyfrowany plik
eventView.entry.decryptionFailed.copyEncrypted=Kopiuj zaszyfrowaną ścieżkę
eventView.entry.brokenDirFile.message=Uszkodzony link do katalogu
eventView.entry.brokenDirFile.showEncrypted=Pokaż uszkodzony, zaszyfrowany link
eventView.entry.brokenDirFile.copyEncrypted=Kopiuj ścieżkę uszkodzonego linku
eventView.entry.brokenFileNode.message=Uszkodzony węzeł systemu plików
eventView.entry.brokenFileNode.showEncrypted=Pokaż uszkodzony, zaszyfrowany węzeł
eventView.entry.brokenFileNode.copyEncrypted=Kopiuj ścieżkę uszkodzonego, zaszyfrowanego węzła
eventView.entry.brokenFileNode.copyDecrypted=Kopiuj odszyfrowaną ścieżkę

View File

@@ -424,9 +424,9 @@ main.vaultDetail.stats=Estatísticas do Cofre
main.vaultDetail.locateEncryptedFileBtn=Localizar Ficheiro Encriptado
main.vaultDetail.locateEncryptedFileBtn.tooltip=Escolha um ficheiro do seu cofre para localizar a sua contraparte encriptada
main.vaultDetail.encryptedPathsCopied=Caminhos copiados para a área de transferência!
main.vaultDetail.locateEncrypted.filePickerTitle=Selecione o ficheiro no cofre
main.vaultDetail.decryptName.buttonLabel=Descriptografar o nome do ficheiro
main.vaultDetail.decryptName.tooltip=Escolha um ficheiro encriptado do cofre para desencriptar o seu nome
main.vaultDetail.locateEncrypted.filePickerTitle=Selecionar ficheiro dentro do cofre
main.vaultDetail.decryptName.buttonLabel=Desencriptar nome do ficheiro
main.vaultDetail.decryptName.tooltip=Escolha um ficheiro de cofre encriptado para desencriptar o seu nome
### Missing
main.vaultDetail.missing.info=O Cryptomator não conseguiu encontrar um cofre neste diretório.
main.vaultDetail.missing.recheck=Verificar novamente
@@ -583,17 +583,17 @@ shareVault.hub.instruction.2=2. Conceder acesso ao membro da equipe no Hub Crypt
shareVault.hub.openHub=Abrir Hub do Cryptomator
# Decrypt File Names
decryptNames.title=Desencriptar os nomes dos ficheiros
decryptNames.title=Desencriptar nomes de ficheiros
decryptNames.filePicker.title=Selecione o ficheiro encriptado
decryptNames.filePicker.extensionDescription=Ficheiro encriptado pelo Criptomator
decryptNames.copyTable.tooltip=Copiar a tabela
decryptNames.clearTable.tooltip=Limpar a tabela
decryptNames.copyHint=Copiar o conteúdo da célula com %s
decryptNames.dropZone.message=Largue os ficheiros ou clique para selecionar
decryptNames.dropZone.error.vaultInternalFiles=Ficheiros internos do coftre sem nome desencriptável selecionado
decryptNames.dropZone.error.foreignFiles=Os ficheiros não pertencem ao cofre "%s"
decryptNames.filePicker.extensionDescription=Ficheiro encriptado do Cryptomator
decryptNames.copyTable.tooltip=Copiar tabela
decryptNames.clearTable.tooltip=Limpar tabela
decryptNames.copyHint=Copiar conteúdo da célula com %s
decryptNames.dropZone.message=Solte os ficheiros ou clique para selecionar
decryptNames.dropZone.error.vaultInternalFiles=Ficheiros internos do cofre sem nome decifrável selecionado
decryptNames.dropZone.error.foreignFiles=Ficheiros não pertencem ao cofre "%s"
decryptNames.dropZone.error.noDirIdBackup=O diretório dos ficheiros selecionados não contém o ficheiro dirId.c9r
decryptNames.dropZone.error.generic=Falha ao desencriptar os nomes dos ficheiros
decryptNames.dropZone.error.generic=Falha ao desencriptar nomes de ficheiros
# Event View
@@ -603,20 +603,20 @@ eventView.clearListButton.tooltip=Limpar lista
## event list entries
eventView.entry.vaultLocked.description=Desbloquear "%s" para detalhes
eventView.entry.conflictResolved.message=Conflito resolvido
eventView.entry.conflictResolved.showDecrypted=Mostrar o ficheiro desencriptado
eventView.entry.conflictResolved.copyDecrypted=Copiar o caminho desencriptado
eventView.entry.conflict.message=A resolução do conflito falhou
eventView.entry.conflict.showDecrypted=Mostrar o ficheiro original desencriptado
eventView.entry.conflict.copyDecrypted=Copie o caminho original desencriptado
eventView.entry.conflict.showEncrypted=Mostrar o ficheiro encriptado em conflito
eventView.entry.conflict.copyEncrypted=Copiar o caminho encriptado em conflito
eventView.entry.decryptionFailed.message=A desencriptação falhou
eventView.entry.conflictResolved.showDecrypted=Mostrar ficheiro desencriptado
eventView.entry.conflictResolved.copyDecrypted=Copiar caminho desencriptado
eventView.entry.conflict.message=Resolução de conflito falhou
eventView.entry.conflict.showDecrypted=Mostrar ficheiro original desencriptado
eventView.entry.conflict.copyDecrypted=Copie caminho original desencriptado
eventView.entry.conflict.showEncrypted=Mostrar ficheiro encriptado conflitante
eventView.entry.conflict.copyEncrypted=Copiar caminho encriptado conflituante
eventView.entry.decryptionFailed.message=Falha na desencriptação
eventView.entry.decryptionFailed.showEncrypted=Mostrar ficheiro encriptado
eventView.entry.decryptionFailed.copyEncrypted=Copiar o caminho encriptado
eventView.entry.decryptionFailed.copyEncrypted=Copiar caminho de encriptação
eventView.entry.brokenDirFile.message=Link de diretório quebrado
eventView.entry.brokenDirFile.showEncrypted=Mostrar o link quebrado e encriptado
eventView.entry.brokenDirFile.showEncrypted=Mostrar link quebrado e encriptado
eventView.entry.brokenDirFile.copyEncrypted=Copiar caminho do link quebrado
eventView.entry.brokenFileNode.message=Nó do sistema de ficheiros avariado
eventView.entry.brokenFileNode.showEncrypted=Mostrar nó encriptado e danificado
eventView.entry.brokenFileNode.showEncrypted=Mostrar nó encriptado quebrado
eventView.entry.brokenFileNode.copyEncrypted=Copiar o caminho do nó encriptado e danificado
eventView.entry.brokenFileNode.copyDecrypted=Copiar o caminho desencriptado
eventView.entry.brokenFileNode.copyDecrypted=Copiar caminho desencriptado

View File

@@ -283,7 +283,6 @@ preferences.title=Inställningar
## General
preferences.general=Allmänt
preferences.general.startHidden=Dölj fönster när Cryptomator startar
preferences.general.autoCloseVaults=Lås valv utan att fråga när du avslutar applikationen
preferences.general.debugLogging=Aktivera loggning för felsökning
preferences.general.debugDirectory=Visa loggfiler
preferences.general.autoStart=Starta Cryptomator vid systemstart

View File

@@ -15,17 +15,17 @@ generic.button.copied=Скопійовано!
generic.button.done=Завершити
generic.button.next=Далі
generic.button.print=Друкувати
generic.button.remove=Вилучити
generic.button.remove=Прибрати
# Error
error.message=Виникла помилка
error.description=Ой! Cryptomator не очікував, що це станеться. Ви можете спробувати знайти рішення для цієї помилки. Або, якщо про неї ще не повідомляли, не соромтеся зробити це.
error.message=Сталася помилка
error.description=Ой! Cryptomator не очікував, що таке трапиться. Ви можете знайти існуючі рішення цієї помилки. Або, якщо про це ще не повідомили, то не соромтеся зробити це.
error.hyperlink.lookup=Дізнатися більше про цю помилку
error.hyperlink.report=Повідомити про цю помилку
error.technicalDetails=Докладно:
error.existingSolutionDescription=Cryptomator не очікував, що це станеться. Однак ми знайшли рішення для цієї помилки. Будь ласка, перегляньте наступне посилання.
error.existingSolutionDescription=Cryptomator не очікував, що це станеться. Але ми знайшли спосіб розв'язання цієї проблеми. Ознайомтесь з ним, будь ласка, далі.
error.hyperlink.solution=Ознайомтесь із рішенням
error.lookupPermissionMessage=Cryptomator може спробувати знайти рішення для цієї проблеми онлайн. Це передбачає відправку запиту до нашої бази даних проблем з вашої IP-адреси.
error.lookupPermissionMessage=Cryptomator може спробувати знайти спосіб розв'язання цієї проблеми онлайн. Це передбачає відправку запиту до нашої бази даних проблем з вашої ІР.
error.dismiss=Відхилити
error.lookUpSolution=Пошук рішення
@@ -35,14 +35,14 @@ defaults.vault.vaultName=Сховище
# Tray Menu
traymenu.showMainWindow=Показати
traymenu.showPreferencesWindow=Налаштування
traymenu.lockAllVaults=Заблокувати всі
traymenu.lockAllVaults=Заблокувати все
traymenu.quitApplication=Вийти
traymenu.vault.unlock=Розблокувати
traymenu.vault.lock=Заблокувати
traymenu.vault.reveal=Відкрити диск
traymenu.vault.reveal=Розгорнути вікно
# Add Vault Wizard
addvaultwizard.title=Додати сховище
addvaultwizard.title=Додавання сховища
## New
addvaultwizard.new.title=Додавання нового сховища
### Name
@@ -50,68 +50,68 @@ addvaultwizard.new.nameInstruction=Оберіть назву для сховищ
addvaultwizard.new.namePrompt=Назва сховища
### Location
addvaultwizard.new.locationInstruction=Де Cryptomator має зберігати зашифровані файли вашого сховища?
addvaultwizard.new.locationLoading=Перевірка локальної файлової системи на наявність каталогів хмарних сховищ…
addvaultwizard.new.locationLoading=Перевірка локальної файлової системи на предмет наявності папок клієнтів хмарних сховищ…
addvaultwizard.new.locationLabel=Розташування сховища
addvaultwizard.new.locationPrompt=
addvaultwizard.new.directoryPickerLabel=Власне розташування
addvaultwizard.new.directoryPickerButton=Обрати…
addvaultwizard.new.directoryPickerTitle=Обрати каталог
addvaultwizard.new.fileAlreadyExists=Файл або каталог з такою назвою сховища вже існує
addvaultwizard.new.locationDoesNotExist=Каталог за вказаним шляхом не існує або недоступний
addvaultwizard.new.locationIsNotWritable=Немає дозволу на запис за вказаним шляхом
addvaultwizard.new.directoryPickerTitle=Обрати папку
addvaultwizard.new.fileAlreadyExists=Файл чи папка з вказаним іменем сховища вже існує
addvaultwizard.new.locationDoesNotExist=Папка недоступна за вказаною адресою або не існує
addvaultwizard.new.locationIsNotWritable=Вказана адреса доступна лише для читання
addvaultwizard.new.locationIsOk=Це місце підходить для сховища
addvaultwizard.new.invalidName=Недійсна назва сховища
addvaultwizard.new.validName=Дійсна назва сховища
addvaultwizard.new.invalidName=Недопустима назва сховища
addvaultwizard.new.validName=Допустима назва сховища
addvaultwizard.new.validCharacters.message=Назва сховища може містити такі символи:
addvaultwizard.new.validCharacters.chars=Літери (напр. a, ж або 수)
addvaultwizard.new.validCharacters.chars=Літери (напр. a, ж or 수)
addvaultwizard.new.validCharacters.numbers=Цифри
addvaultwizard.new.validCharacters.dashes=Дефіс (%s) або підкреслення (%s)
### Expert Settings
addvaultwizard.new.expertSettings.enableExpertSettingsCheckbox=Увімкнути експертні налаштування
addvaultwizard.new.expertSettings.shorteningThreshold.invalid=Введіть значення від 36 до 220 (за замовчуванням 220)
addvaultwizard.new.expertSettings.shorteningThreshold.invalid=Введіть значення від 36 до 220 (типово 220)
addvaultwizard.new.expertSettings.shorteningThreshold.tooltip=Відкрийте документацію, щоб дізнатися більше.
addvaultwizard.new.expertSettings.shorteningThreshold.title=Максимальна довжина зашифрованих назв файлів
addvaultwizard.new.expertSettings.shorteningThreshold.title=Максимальна довжина зашифрованих імен файлів
addvaultwizard.new.expertSettings.shorteningThreshold.valid=Вірний
### Password
addvaultwizard.new.createVaultBtn=Створити сховище
addvaultwizard.new.generateRecoveryKeyChoice=Ви не зможете отримати доступ до своїх даних без пароля. Хочете створити ключ відновлення на випадок втрати паролю?
addvaultwizard.new.generateRecoveryKeyChoice.yes=Так, будь ласка, краще перестрахуватися
addvaultwizard.new.generateRecoveryKeyChoice.yes=Так, будь ласка, береженого Бог береже
addvaultwizard.new.generateRecoveryKeyChoice.no=Ні, дякую, я не втрачу свій пароль
### Information
addvault.new.readme.storageLocation.fileName=ВАЖЛИВО.rtf
addvault.new.readme.storageLocation.1=⚠️ ФАЙЛИ СХОВИЩА ⚠️
addvault.new.readme.storageLocation.2=Це місце, де зберігається ваше сховище.
addvault.new.readme.storageLocation.3=НЕ РОБІТЬ ЦЬОГО
addvault.new.readme.storageLocation.4= не змінюйте будь-які файли в цьому каталозі, та
addvault.new.readme.storageLocation.5=не додавайте безпосередньо до цього каталогу будь-які файли для їх шифрування.
addvault.new.readme.storageLocation.3=НЕ
addvault.new.readme.storageLocation.4=• змінюйте будь-які файли в цій папці, або
addvault.new.readme.storageLocation.5=• додавайте безпосередньо до цієї папки будь-які файли для їх шифрування.
addvault.new.readme.storageLocation.6=Якщо ви хочете зашифрувати файли та переглянути вміст сховища, зробіть так:
addvault.new.readme.storageLocation.7=1. Додайте це сховище у Cryptomator.
addvault.new.readme.storageLocation.7=1. Додайте це сховище (папку) у Cryptomator.
addvault.new.readme.storageLocation.8=2. Розблокуйте його через Cryptomator.
addvault.new.readme.storageLocation.9=3. Натисніть кнопку «Відкрити диск», щоб отримати доступ до вмісту сховища.
addvault.new.readme.storageLocation.10=Якщо вам потрібна допомога, відвідайте документацію: %s
addvault.new.readme.accessLocation.fileName=ПРИВІТ.rtf
addvault.new.readme.storageLocation.9=3. Отримайте доступ до вмісту сховища, натиснувши кнопку "Розгорнути".
addvault.new.readme.storageLocation.10=Якщо вам потрібна допомога, почитайте документацію: %s
addvault.new.readme.accessLocation.fileName=ПРОЧИТАЙ_МЕНЕ.rtf
addvault.new.readme.accessLocation.1=🔐️ ЗАШИФРОВАНИЙ ТОМ 🔐️
addvault.new.readme.accessLocation.2=Це розташування для доступу до вашого сховища.
addvault.new.readme.accessLocation.2=Це місце розташування вашого сховища.
addvault.new.readme.accessLocation.3=Будь-які файли, додані до цього тому, будуть зашифровані за допомогою Cryptomator. Ви можете працювати із ним як із будь-якою іншою директорією або накопичувачем. Це лише розшифрований вигляд вмісту сховища, ваші файли завжди знаходяться в зашифрованому вигляді на диску.
addvault.new.readme.accessLocation.4=Цей файл можна видалити, якщо бажаєте.
## Existing
addvaultwizard.existing.title=Додати наявне сховище
addvaultwizard.existing.instruction=Оберіть файл «vault.cryptomator» свого наявного сховища. Якщо існує лише файл з назвою «masterkey.cryptomator», оберіть його.
addvaultwizard.existing.instruction=Виберіть файл "vault.cryptomator" вашого наявного сховища. Якщо існує лише файл з назвою "masterkey.cryptomator", виберіть його.
addvaultwizard.existing.chooseBtn=Обрати…
addvaultwizard.existing.filePickerTitle=Виберіть файл сховища
addvaultwizard.existing.filePickerMimeDesc=Сховище Cryptomator
## Success
addvaultwizard.success.nextStepsInstructions=Сховище «%s» додано.\nЩоб отримати доступ або додати вміст, вам потрібно розблокувати це сховище. Також ви можете розблокувати його пізніше в будь-який час.
addvaultwizard.success.nextStepsInstructions=Додано сховище "%s".\nЦе сховище необхідно розблокувати для доступу або додавання вмісту. Але ви можете розблокувати його пізніше.
addvaultwizard.success.unlockNow=Розблокувати
# Remove Vault
removeVault.title=Вилучити «%s»
removeVault.message=Вилучити сховище?
removeVault.description=Це лише змусить Cryptomator забути про сховище. Ви зможете додати його знову. Зашифровані файли не будуть видалені з вашого накопичувача.
removeVault.title=Видалити "%s"
removeVault.message=Видалити сховище?
removeVault.description=Це лише змусить Cryptomator забути про це сховище. Його можна буде додати знову пізніше. Зашифровані файли на вашому жорсткому диску не буде втрачено.
# Change Password
changepassword.title=Зміна паролю
changepassword.enterOldPassword=Введіть поточний пароль для «%s»
changepassword.enterOldPassword=Введіть поточний пароль для "%s"
changepassword.finalConfirmation=Я розумію, що не зможу отримати доступ до даних, якщо забуду свій пароль
# Forget Password
@@ -121,202 +121,201 @@ forgetPassword.description=Ця дія видалить збережений п
forgetPassword.confirmBtn=Забути пароль
# Unlock
unlock.title=Розблокування «%s»
unlock.passwordPrompt=Введіть пароль для «%s»:
unlock.title=Розблокування "%s"
unlock.passwordPrompt=Введіть пароль для "%s":
unlock.savePassword=Запам'ятати пароль
unlock.unlockBtn=Розблокувати
## Select
unlock.chooseMasterkey.message=Файл майстер-ключа не знайдено
unlock.chooseMasterkey.description=Cryptomator не зміг знайти файл майстер-ключа для сховища «%s». Будь ласка, виберіть файл ключа вручну.
unlock.chooseMasterkey.description=Cryptomator не зміг знайти файл майстер-ключа для сховища "%s". Будь ласка, виберіть ключ вручну.
unlock.chooseMasterkey.filePickerTitle=Виберіть файл майстер-ключа
unlock.chooseMasterkey.filePickerMimeDesc=Майстер-ключ Cryptomator
## Success
unlock.success.message=Успішно розблоковано
unlock.success.description=Вміст сховища «%s» тепер доступний через точку монтування.
unlock.success.description=Вміст сховища "%s" тепер доступний через точку монтування.
unlock.success.rememberChoice=Запам'ятайте мій вибір та більше не запитуйте
unlock.success.revealBtn=Відкрити диск
unlock.success.revealBtn=Розгорнути диск
## Failure
unlock.error.customPath.message=Не вдалося змонтувати сховище за вказаним шляхом
unlock.error.customPath.description.notSupported=Якщо ви хочете надалі використовувати власний шлях, будь ласка, перейдіть до налаштувань та виберіть тип тому, що його підтримує. В іншому випадку перейдіть до параметрів сховища та оберіть точку монтування, що підтримується.
unlock.error.customPath.description.notExists=Вказаний шлях монтування не існує. Створіть його в локальній файловій системі або змініть його в параметрах сховища.
unlock.error.customPath.description.inUse=Літера диска або власний шлях монтування «%s» уже використовується.
unlock.error.customPath.description.hideawayNotDir=Тимчасовий прихований файл «%3$s», що використовувався для розблокування, не вдалося видалити. Будь ласка, перевірте файл, а потім видаліть його вручну.
unlock.error.customPath.description.couldNotBeCleaned=Ваше сховище неможливо змонтувати за шляхом «%s». Будь ласка, спробуйте знову або оберіть інший шлях.
unlock.error.customPath.description.notEmptyDir=Власний шлях монтування «%s» не є порожньою папкою. Будь ласка, оберіть порожню папку та спробуйте ще раз.
unlock.error.customPath.description.generic=Ви обрали власний шлях монтування для цього сховища, але його використання не вдалося з таким повідомленням: %2$s
unlock.error.customPath.description.inUse=Зараз використовується літера або користувацький шлях монтування "%s".
unlock.error.customPath.description.hideawayNotDir=Цей тимчасовий прихований файл "%3$s" використовується для розблокування і не може бути видалений. Будь ласка, перевірте файл та видаліть його вручну.
unlock.error.customPath.description.couldNotBeCleaned=Ваше сховище неможливо змонтувати за шляхом "%s". Будь ласка, спробуйте знову або оберіть інший шлях.
unlock.error.customPath.description.notEmptyDir=Користувацький шлях монтування "%s" не є порожньою папкою. Будь ласка, оберіть порожню папку і спробуйте ще раз.
unlock.error.customPath.description.generic=Ви вибрали користувацький шлях монтування для цього сховища, але його використання призвело до помилки з текстом: %2$s
unlock.error.restartRequired.message=Не вдалося розблокувати сховище
unlock.error.restartRequired.description=Змініть тип тому в параметрах сховища або перезапустіть Cryptomator.
unlock.error.title=Розблокувати «%s» не вдалося
unlock.error.restartRequired.description=Змініть тип носія в налаштуваннях сховища або перезапустіть Cryptomator.
unlock.error.title=Розблокувати "%s" не вдалося
## Hub
hub.noKeychain.message=Не вдалося отримати доступ до ключа пристрою
hub.noKeychain.description=Щоб розблокувати сховища Hub, необхідний ключ пристрою, який захищено за допомогою зв'язки ключів. Щоб продовжити, увімкніть «%s» та виберіть зв'язку ключів у налаштуваннях.
hub.noKeychain.description=Щоб розблокувати сховища Hub, необхідний ключ пристрою, який захищено за допомогою зв'язки ключів. Щоб продовжити, увімкніть %s та виберіть зв'язку ключів у налаштуваннях.
hub.noKeychain.openBtn=Відкрити налаштування
### Waiting
hub.auth.message=Очікування завершення автентифікації…
hub.auth.description=Вас буде автоматично перенаправлено на сторінку входу.
hub.auth.loginLink=Не перенаправлено? Натисніть тут, щоб відкрити її.
hub.auth.description=Вас буде автоматично переспрямовано на сторінку входу.
hub.auth.loginLink=Не переспрямовано? Натисніть тут, щоб відкрити її.
### Receive Key
hub.receive.message=Обробка відповіді…
hub.receive.description=Cryptomator отримує та опрацьовує відповідь від Hub. Будь ласка, зачекайте.
### Register Device
hub.register.message=Новий пристрій
hub.register.description=Це перший доступ до Hub з цього пристрою. Будь ласка, зареєструйтесь за допомогою вашого ключа облікового запису.
hub.register.description=Це перший доступ до Хабу Cryptomator з цього пристрою. Будь ласка, зареєструйтесь за допомогою вашого ключа облікового запису.
hub.register.nameLabel=Назва пристрою
hub.register.invalidAccountKeyLabel=Недійсний ключ облікового запису
hub.register.registerBtn=Зареєструватись
### Register Device Legacy
hub.register.legacy.occupiedMsg=Таке ім’я уже існує
hub.register.legacy.description=Це перший доступ до Hub з цього пристрою. Будь ласка, зареєструйте його.
hub.register.legacy.description=Це перший доступ до Хабу Cryptomator з цього пристрою. Будь ласка, зареєструйте його.
### Registration Success
hub.registerSuccess.message=Пристрій зареєстровано
hub.registerSuccess.description=Ваш пристрій успішно зареєстровано. Тепер ви можете продовжити розблокування сховища.
hub.registerSuccess.unlockBtn=Розблокувати
hub.registerSuccess.legacy.description=Щоб отримати доступ до сховища, ваш пристрій має бути додатково авторизованим власником сховища.
hub.registerSuccess.legacy.description=Щоб отримати доступ до сховища, ваш пристрій повинен бути додатково авторизованим власником сховища.
### Registration Failed
hub.registerFailed.message=Не вдалося зареєструвати пристрій
hub.registerFailed.description.generic=Під час реєстрації виникла помилка. Для отримання додаткової інформації перегляньте журнал програми.
hub.registerFailed.description.deviceAlreadyExists=Цей пристрій вже зареєстровано для іншого користувача. Спробуйте змінити обліковий запис або скористайтеся іншим пристроєм.
hub.registerFailed.message=Помилка реєстрації пристрою
hub.registerFailed.description.generic=Помилка виникла у процесі реєстрації. Для більш докладної інформації перегляньте журнал додатка.
hub.registerFailed.description.deviceAlreadyExists=Цей пристрій вже зареєстровано для іншого користувача. Спробуйте змінити обліковий запис користувача або скористайтеся іншим пристроєм.
### Unauthorized
hub.unauthorized.message=У доступі відмовлено
hub.unauthorized.description=Ви не авторизовані для відкриття цього сховища. Зв'яжіться з його власником, щоб отримати доступ.
hub.unauthorized.description=Ви не маєте права для відкриття цього сховища. Зверніться до власника сховища, щоб запитати доступ.
### Requires Account Initialization
hub.requireAccountInit.message=Необхідна дія
hub.requireAccountInit.description.0=Щоб продовжити, будь ласка, виконайте необхідні кроки у вашому
hub.requireAccountInit.description.1=профілі користувача Hub
hub.requireAccountInit.description.0=Для продовження, будь ласка, завершіть виконання обов'язкових кроків
hub.requireAccountInit.description.1=Профіль користувача Хабу
hub.requireAccountInit.description.2=.
### License Exceeded
hub.invalidLicense.message=Недійсна ліцензія Hub
hub.invalidLicense.description=Ваш екземпляр Cryptomator Hub має недійсну ліцензію. Будь ласка, повідомте адміністратора Hub для оновлення або поновлення ліцензії.
hub.invalidLicense.description=У вашого Cryptomator Hub недійсна ліцензія. Будь ласка, зв'яжіться з адміністратором Hub, щоб оновити або продовжити дію ліцензії.
# Lock
## Force
lock.forced.message=Помилка блокування
lock.forced.description=Блокуванню «%s» заважає виконання операцій або відкриті файли. Ви можете примусово заблокувати це сховище, однак переривання операцій читання/запису може призвести до втрати незбережених даних.
lock.forced.retryBtn=Повторити спробу
lock.forced.forceBtn=Примусово заблокувати
lock.forced.description=Блокуванню "%s" заважає виконання операцій або відкриті файли. Ви можете примусово заблокувати це сховище, однак переривання операцій чинання/запису може призвести до втрати незбережених даних.
lock.forced.retryBtn=Повторити
lock.forced.forceBtn=Примусове блокування
## Failure
lock.fail.message=Не вдалося заблокувати сховище
lock.fail.description=Не вдалося заблокувати сховище «%s». Переконайтеся, що незбережена робота збережена в іншому місці, а важливі операції читання/запису завершені. Щоб закрити сховище, завершіть процес Cryptomator.
lock.fail.description=Сховище "%s" не можна заблокувати. Переконайтеся, що незавершену роботу збережено в іншому місці, а також важливі операції читання/запису закінчені. Щоб закрити сховище, завершіть процес Cryptomator.
# Migration
migration.title=Покращення сховища
## Start
migration.start.header=Покращення сховища до наступної версії
migration.start.text=Для того, щоб відкрити сховище «%s» у новій версії Cryptomator, воно має бути оновлене до новішого формату. Перед тим, як це зробити, ви повинні знати таке:
migration.start.text=Для того, щоб відкрити сховище "%s" у новій версії Cryptomator, воно має бути оновлене до новішого формату. Перед тим, як це зробити, ви повинні знати таке:
migration.start.remarkUndone=Це оновлення не може бути скасовано.
migration.start.remarkVersions=Старіші версії Cryptomator не зможуть відкрити оновлене сховище.
migration.start.remarkCanRun=Ви повинні бути впевнені, що кожен пристрій, з якого ви маєте доступ до сховища, підтримує цю версію Cryptomator.
migration.start.remarkSynced=Ви маєте бути впевнені, що ваше сховище повністю синхронізовано на цьому пристрої та на інших ваших пристроях, перш ніж оновити його.
migration.start.confirm=Я прочитав(ла) і зрозумів(ла) наведену вище інформацію
migration.start.confirm=Я прочитав та зрозумів вищевказану інформацію
## Run
migration.run.enterPassword=Введіть пароль для «%s»
migration.run.startMigrationBtn=Розпочати оновлення
migration.run.enterPassword=Введіть пароль для "%s"
migration.run.startMigrationBtn=Розпочати міграцію
migration.run.progressHint=Це може зайняти деякий час…
## Success
migration.success.nextStepsInstructions=Оновлення «%s» успішно завершено.\nТепер ви можете розблокувати ваше сховище.
migration.success.nextStepsInstructions=Міграцію "%s" успішно завершено.\nТепер ви можете розблокувати ваше сховище.
migration.success.unlockNow=Розблокувати
## Missing file system capabilities
migration.error.missingFileSystemCapabilities.title=Файлова система не підтримується
migration.error.missingFileSystemCapabilities.description=Оновлення не було розпочато, оскільки ваше сховище знаходиться в несумісній файловій системі.
migration.error.missingFileSystemCapabilities.description=Перенесення не було розпочато, оскільки ваше сховище знаходиться в несумісній файловій системі.
migration.error.missingFileSystemCapabilities.reason.LONG_FILENAMES=Файлова система не підтримує довгі назви файлів.
migration.error.missingFileSystemCapabilities.reason.LONG_PATHS=Файлова система не підтримує довгі шляхи.
migration.error.missingFileSystemCapabilities.reason.READ_ACCESS=Файлова система не дозволяє зчитувати дані.
migration.error.missingFileSystemCapabilities.reason.WRITE_ACCESS=Файлова система не дозволяє записувати дані.
## Impossible
migration.impossible.heading=Не вдалося оновити сховище
migration.impossible.reason=Сховище не можливо автоматично оновити через його розташування на диску або несумісність точки доступу.
migration.impossible.moreInfo=Сховище все ще можна відкрити старішою версією. Для інструкцій, як вручну оновити сховище, відвідайте
migration.impossible.heading=Не вдалося перенести сховище
migration.impossible.reason=Сховище не можливо автоматично перенести через його розташуванням на диску або несумісність точки доступу.
migration.impossible.moreInfo=Сховище все ще може бути відкрите старішою версією. Для інструкцій, як вручну перенести сховище, перейдіть
# Health Check
## Start
health.title=Перевірка стану «%s»
health.intro.header=Перевірка стану
health.intro.text=«Перевірка стану» — це набір перевірок для виявлення та, можливо, виправлення проблем у внутрішній структурі вашого сховища. Будь ласка, врахуйте:
health.title=Перевірка працездатності "%s"
health.intro.header=Перевірка працездатності
health.intro.text=Перевірка працездатності передбачає ряд тестів для виявлення та за можливості виправлення проблем у внутрішній структурі вашого сховища. Будь ласка, пам'ятайте:
health.intro.remarkSync=Переконайтеся, що всі пристрої повністю синхронізовані, це вирішує більшість проблем.
health.intro.remarkFix=Не всі проблеми можна виправити.
health.intro.remarkBackup=Якщо дані пошкоджено, допоможе лише резервна копія.
health.intro.affirmation=Я прочитав(ла) і зрозумів(ла) наведену вище інформацію
health.intro.remarkBackup=Якщо дані пошкоджено, то може допомогти тільки резервна копія.
health.intro.affirmation=Я прочитав та зрозумів вищевказану інформацію
## Start Failure
health.fail.header=Помилка при завантаженні конфігурації сховища
health.fail.ioError=Під час доступу та читання файлу конфігурації сталася помилка.
health.fail.parseError=Під час аналізу конфігурації сховища сталася помилка.
health.fail.ioError=Сталася помилка під час спроби доступу до файлу конфігурації.
health.fail.parseError=Сталася помилка під час опрацювання конфігурації сховища.
health.fail.moreInfo=Більше інформації
## Check Selection
health.checkList.description=Виберіть перевірки зі списку ліворуч або скористайтеся кнопками нижче.
health.checkList.description=Оберіть прапорець зі списку ліворуч або використовуйте кнопки нижче.
health.checkList.selectAllButton=Вибрати всі перевірки
health.checkList.deselectAllButton=Зняти вибір з усіх перевірок
health.check.runBatchBtn=Розпочати обрані перевірки
## Detail view
health.check.detail.noSelectedCheck=Щоб переглянути результати, виберіть завершену перевірку стану зі списку ліворуч.
health.check.detail.noSelectedCheck=Для перегляду результатів оберіть завершену перевірку працездатності зі списку ліворуч.
health.check.detail.checkScheduled=Перевірку заплановано.
health.check.detail.checkRunning=Перевірка триває…
health.check.detail.checkSkipped=Цю перевірку не було обрано для запуску.
health.check.detail.checkSkipped=Перевірку не вибрано для запуску.
health.check.detail.checkFinished=Перевірку завершено успішно.
health.check.detail.checkFinishedAndFound=Перевірку завершено. Будь ласка, ознайомтесь з результатами.
health.check.detail.checkFailed=Перевірку перервано через помилку.
health.check.detail.checkFailed=Перевірка завершилась через помилку.
health.check.detail.checkCancelled=Перевірку було скасовано.
health.check.detail.listFilters.label=Фільтр
health.check.detail.fixAllSpecificBtn=Виправити всі цього типу
health.check.detail.fixAllSpecificBtn=Виправити все
health.check.exportBtn=Експортувати звіт
## Result view
health.result.severityFilter.all=Ступінь серйозності Усі
health.result.severityFilter.all=Рівень критичності - Усі
health.result.severityFilter.good=В нормі
health.result.severityFilter.info=Інформація
health.result.severityFilter.warn=Попередження
health.result.severityFilter.crit=Критично
health.result.severityTip.good=Ступінь серйозності: В нормі.\nЗвичайна структура сховища.
health.result.severityTip.info=Ступінь серйозності: Інформація.\nСтруктура сховища ціла, запропоновано виправлення.
health.result.severityTip.warn=Ступінь серйозності: Попередження.\nСтруктура сховища пошкоджена, наполегливо рекомендуємо виправити.
health.result.severityTip.crit=Ступінь серйозності: Критичний.\nСтруктура сховища пошкоджена, виявлено втрату даних.
health.result.fixStateFilter.all=Стан виправлення Усі
health.result.fixStateFilter.fixable=Можна виправити
health.result.fixStateFilter.notFixable=Неможливо виправити
health.result.severityTip.good=Рівень критичності: в нормі\nЗвичайна структура сховища.
health.result.severityTip.info=Рівень критичності: інформація\nСтруктура сховища цілісна, виправлення рекомендовані.
health.result.severityTip.warn=Рівень критичності: попередження\nСтруктуру сховища пошкоджено, це слід виправити.
health.result.severityTip.crit=Рівень критичності: критичний\nСтруктуру сховища пошкоджено, виявлено втрату даних.
health.result.fixStateFilter.all=Статус виправлення - Всі
health.result.fixStateFilter.fixable=Поправні
health.result.fixStateFilter.notFixable=Не поправні
health.result.fixStateFilter.fixing=Виправляються…
health.result.fixStateFilter.fixed=Виправлено
health.result.fixStateFilter.fixFailed=Не вдалося виправити
health.result.fixStateFilter.fixed=Виправлені
health.result.fixStateFilter.fixFailed=Невдале виправлення
## Fix Application
health.fix.fixBtn=Виправити
health.fix.successTip=Успішно виправлено
health.fix.failTip=Не вдалося виправити, перегляньте журнал для отримання подробиць
health.fix.successTip=Виправлення успішне
health.fix.failTip=Виправити не вдалось, перегляньте журнал для ознайомлення з подробицями
# Preferences
preferences.title=Налаштування
## General
preferences.general=Загальні
preferences.general.startHidden=Приховувати вікно під час запуску Cryptomator
preferences.general.autoCloseVaults=Блокувати сховища без запиту при виході з програми
preferences.general.startHidden=Приховати вікно під час запуску Cryptomator
preferences.general.debugLogging=Увімкнути ведення журналу налагодження
preferences.general.debugDirectory=Показати файли журналу
preferences.general.autoStart=Запускати Cryptomator під час запуску системи
preferences.general.keychainBackend=Зберігати паролі за допомогою
preferences.general.quickAccessService=Додавати розблоковані сховища до області швидкого доступу
preferences.general.quickAccessService=Додати до області швидкого доступу розблоковані сховища
## Interface
preferences.interface=Вигляд
preferences.interface.theme=Вигляд і поведінка
preferences.interface.theme=Колір і стиль
preferences.interface.theme.automatic=Автоматично
preferences.interface.theme.dark=Темний
preferences.interface.theme.light=Світлий
preferences.interface.unlockThemes=Розблокувати темний режим
preferences.interface.language=Мова (потрібен перезапуск)
preferences.interface.language=Мова (потребує перезавантаження)
preferences.interface.language.auto=Мова системи
preferences.interface.interfaceOrientation=Орієнтація інтерфейсу
preferences.interface.interfaceOrientation=Відображення елементів
preferences.interface.interfaceOrientation.ltr=Зліва направо
preferences.interface.interfaceOrientation.rtl=Справа наліво
preferences.interface.showTrayIcon=Показувати іконку в треї (потрібен перезапуск)
preferences.interface.showTrayIcon=Показувати піктограму на панелі завдань (потрібен перезапуск)
preferences.interface.compactMode=Активувати компактний список сховищ
## Volume
preferences.volume=Віртуальний диск
preferences.volume.type=Тип тому за замовчуванням
preferences.volume.type.automatic=Автоматично
preferences.volume.docsTooltip=Відкрийте документацію, щоб дізнатися більше про різні типи томів.
preferences.volume.fuseRestartRequired=Щоб застосувати зміни, Cryptomator потрібно перезапустити.
preferences.volume.fuseRestartRequired=Слід перезапустити Cryptomator, щоб зміни набули чинності.
preferences.volume.tcp.port=TCP порт за замовчуванням
preferences.volume.supportedFeatures=Обраний тип тому підтримує такі можливості:
preferences.volume.supportedFeatures=Обраний тип тому підтримує такі функції:
preferences.volume.feature.mountAuto=Автоматичний вибір точки монтування
preferences.volume.feature.mountToDir=Власний каталог як точка монтування
preferences.volume.feature.mountToDriveLetter=Літера диска як точка монтування
preferences.volume.feature.mountFlags=Власні параметри монтування
preferences.volume.feature.readOnly=Монтування лише для читання
preferences.volume.feature.mountToDir=Користувацька папка як точка монтування
preferences.volume.feature.mountToDriveLetter=Точка монтування у вигляді букви диска
preferences.volume.feature.mountFlags=Користувацькі параметри монтування
preferences.volume.feature.readOnly=Монтування в режимі "лише для читання"
## Updates
preferences.updates=Оновлення
preferences.updates.currentVersion=Поточна версія: %s
@@ -327,24 +326,24 @@ preferences.updates.lastUpdateCheck=Остання перевірка: %s
preferences.updates.lastUpdateCheck.never=ніколи
preferences.updates.lastUpdateCheck.recently=нещодавно
preferences.updates.lastUpdateCheck.daysAgo=%s дні(в) тому
preferences.updates.lastUpdateCheck.hoursAgo=%s годин(и) тому
preferences.updates.lastUpdateCheck.hoursAgo=%s годин тому
preferences.updates.checkFailed=Не вдалось перевірити наявність оновлень. Будь ласка, перевірте підключення до Інтернету або спробуйте ще раз пізніше.
preferences.updates.upToDate=Ваш Cryptomator не потребує оновлення.
## Contribution
preferences.contribute=Підтримайте нас
preferences.contribute.registeredFor=Сертифікат помічника зареєстровано для %s
preferences.contribute.noCertificate=Підтримайте Cryptomator та отримайте сертифікат помічника. Це як ліцензійний ключ, але для чудових людей, які користуються безплатним програмним забезпеченням. ;-)
preferences.contribute.noCertificate=Підтримайте Cryptomator та отримайте сертифікат помічника - це як ліцензійний ключ, але для чудових людей, які користуються безкоштовним програмним забезпеченням. ;-)
preferences.contribute.getCertificate=Ще немає такого? Дізнайтеся, як його отримати.
preferences.contribute.promptText=Вставте код сертифікату помічника тут
preferences.contribute.thankYou=Дякуємо, що підтримуєте розробку Cryptomator з відкритим вихідним кодом!
preferences.contribute.donate=Зробити пожертву
preferences.contribute.sponsor=Спонсори
preferences.contribute.donate=Підтримати
preferences.contribute.sponsor=Спонсор
### Remove License Key Dialog
removeCert.title=Вилучити сертифікат
removeCert.message=Вилучити сертифікат помічника?
removeCert.description=Основні функції Cryptomator не будуть зачеплені. Ані доступ до ваших сховищ не буде обмежено, ані рівень безпеки не буде знижено.
removeCert.title=Видалити сертифікат
removeCert.message=Видалити сертифікат помічника?
removeCert.description=Основний функціонал Cryptomator не змінюється. Ні доступ до вашого сховища, а ні рівень безпеки не буде понижено/обмежено.
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -352,33 +351,33 @@ preferences.about=Про додаток
# Vault Statistics
stats.title=Статистика %s
stats.cacheHitRate=Коефіцієнт влучань кеша
stats.cacheHitRate=Відсоток потрапляння до кешу
## Read
stats.read.throughput.idle=Читання: простоює
stats.read.throughput.kibs=Читання: %.2f КіБ/с
stats.read.throughput.mibs=Читання: %.2f МіБ/с
stats.read.total.data.none=Прочитано даних:
stats.read.total.data.kib=Прочитано даних: %.1f КіБ
stats.read.total.data.mib=Прочитано даних: %.1f МіБ
stats.read.total.data.gib=Прочитано даних: %.1f ГіБ
stats.decr.total.data.none=Розшифровано даних:
stats.decr.total.data.kib=Розшифровано даних: %.1f КіБ
stats.decr.total.data.mib=Розшифровано даних: %.1f МіБ
stats.decr.total.data.gib=Розшифровано даних: %.1f ГіБ
stats.read.accessCount=Усього прочитань: %d
stats.read.throughput.idle=Читання: очікування
stats.read.throughput.kibs=Зчитування: %.2f КіБ/с
stats.read.throughput.mibs=Зчитування: %.2f МіБ/с
stats.read.total.data.none=Зчитано даних: -
stats.read.total.data.kib=Зчитано даних: %.1f Кб
stats.read.total.data.mib=Зчитано даних: %.1f Мб
stats.read.total.data.gib=Зчитано даних: %.1f Гб
stats.decr.total.data.none=Розшифровано даних: -
stats.decr.total.data.kib=Розшифровано даних: %.1f Кб
stats.decr.total.data.mib=Розшифровано даних: %.1f Мб
stats.decr.total.data.gib=Розшифровано даних: %.1f Гб
stats.read.accessCount=Всього зчитувань: %d
## Write
stats.write.throughput.idle=Запис: простоює
stats.write.throughput.idle=Запис: очікування
stats.write.throughput.kibs=Запис: %.2f KіБ/с
stats.write.throughput.mibs=Запис: %.2f MіБ/с
stats.write.total.data.none=Записано даних:
stats.write.total.data.kib=Записано даних: %.1f КіБ
stats.write.total.data.mib=Записано даних: %.1f МіБ
stats.write.total.data.gib=Записано даних: %.1f ГіБ
stats.encr.total.data.none=Зашифровано даних:
stats.encr.total.data.kib=Зашифровано даних: %.1f КіБ
stats.encr.total.data.mib=Зашифровано даних: %.1f МіБ
stats.encr.total.data.gib=Зашифровано даних: %.1f ГіБ
stats.write.accessCount=Усього записів: %d
stats.write.total.data.none=Записано даних: -
stats.write.total.data.kib=Записано даних: %.1f Кб
stats.write.total.data.mib=Записано даних: %.1f Мб
stats.write.total.data.gib=Записано даних: %.1f Гб
stats.encr.total.data.none=Зашифровано даних: -
stats.encr.total.data.kib=Зашифровано даних: %.1f Кб
stats.encr.total.data.mib=Зашифровано даних: %.1f Мб
stats.encr.total.data.gib=Зашифровано даних: %.1f Гб
stats.write.accessCount=Всього записувань: %d
## Accesses
stats.access.current=Отримано доступ: %d
@@ -388,46 +387,42 @@ stats.access.total=Усього отримано доступ: %d
# Main Window
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Натисніть тут, щоб додати сховище
main.vaultlist.contextMenu.remove=Вилучити…
main.vaultlist.contextMenu.remove=Видалити…
main.vaultlist.contextMenu.lock=Заблокувати
main.vaultlist.contextMenu.unlock=Розблокувати…
main.vaultlist.contextMenu.unlockNow=Розблокувати
main.vaultlist.contextMenu.vaultoptions=Показати параметри сховища
main.vaultlist.contextMenu.reveal=Відкрити диск
main.vaultlist.contextMenu.reveal=Розгорнути диск
main.vaultlist.addVaultBtn.menuItemNew=Створити нове сховище...
main.vaultlist.addVaultBtn.menuItemExisting=Відкрити наявне сховище...
main.vaultlist.showEventsButton.tooltip=Відкрити журнал подій
##Notificaition
main.notification.updateAvailable=Доступне оновлення.
main.notification.updateAvailable=Оновлення доступне.
main.notification.support=Підтримайте Cryptomator.
## Vault Detail
### Welcome
main.vaultDetail.welcomeOnboarding=Дякуємо, що обрали Cryptomator для захисту ваших файлів. Якщо вам потрібна допомога, ознайомтеся з нашими посібниками для початку роботи:
main.vaultDetail.welcomeOnboarding=Дякуємо, що обрали Cryptomator для захисту ваших файлів. Якщо вам потрібна допомога, перегляньте наші інструкції з роботи:
### Locked
main.vaultDetail.lockedStatus=ЗАБЛОКОВАНО
main.vaultDetail.unlockBtn=Розблокувати…
main.vaultDetail.unlockNowBtn=Розблокувати
main.vaultDetail.optionsBtn=Параметри сховища
main.vaultDetail.optionsBtn=Налаштування сховища
main.vaultDetail.passwordSavedInKeychain=Пароль збережено
main.vaultDetail.share=Поділитися…
### Unlocked
main.vaultDetail.unlockedStatus=РОЗБЛОКОВАНО
main.vaultDetail.accessLocation=Вміст вашого сховища доступний тут:
main.vaultDetail.revealBtn=Відкрити диск
main.vaultDetail.copyUri=Копіювати URI
main.vaultDetail.accessLocation=Щоб отримати доступ до вмісту сховища - натисніть кнопку:
main.vaultDetail.revealBtn=Розгорнути диск
main.vaultDetail.copyUri=Скопіювати адресу
main.vaultDetail.lockBtn=Заблокувати
main.vaultDetail.bytesPerSecondRead=Читання:
main.vaultDetail.bytesPerSecondRead=Зчитування:
main.vaultDetail.bytesPerSecondWritten=Запис:
main.vaultDetail.throughput.idle=простоює
main.vaultDetail.throughput.idle=простоювання
main.vaultDetail.throughput.kbps=%.1f КіБ/c
main.vaultDetail.throughput.mbps=%.1f МіБ/c
main.vaultDetail.stats=Статистика сховища
main.vaultDetail.locateEncryptedFileBtn=Знайти зашифрований файл
main.vaultDetail.locateEncryptedFileBtn.tooltip=Виберіть файл зі сховища, щоб знайти його зашифрований відповідник
main.vaultDetail.locateEncryptedFileBtn.tooltip=Виберіть файл із вашого сховища, щоб знайти розташування його зашифрованого відповідника
main.vaultDetail.encryptedPathsCopied=Шляхи скопійовано в буфер обміну!
main.vaultDetail.locateEncrypted.filePickerTitle=Виберіть файл у сховищі
main.vaultDetail.decryptName.buttonLabel=Розшифрувати назву файлу
main.vaultDetail.decryptName.tooltip=Виберіть зашифрований файл сховища, щоб розшифрувати його назву
### Missing
main.vaultDetail.missing.info=Cryptomator не зміг знайти сховище за цим шляхом.
main.vaultDetail.missing.recheck=Перевірити знову
@@ -435,7 +430,7 @@ main.vaultDetail.missing.remove=Вилучити зі списку сховищ
main.vaultDetail.missing.changeLocation=Змінити розташування сховища…
### Needs Migration
main.vaultDetail.migrateButton=Покращити сховище
main.vaultDetail.migratePrompt=Ваше сховище потрібно оновити до нового формату, перш ніж ви зможете отримати до нього доступ
main.vaultDetail.migratePrompt=Ваше сховище слід покращити (перетворити) у новий формат, перш ніж ви зможете отримати до нього доступ
### Error
main.vaultDetail.error.info=Виникла помилка під час завантаження сховища з диска.
main.vaultDetail.error.reload=Перезавантажити
@@ -444,10 +439,10 @@ main.vaultDetail.error.windowTitle=Помилка завантаження сх
# Wrong File Alert
wrongFileAlert.title=Як зашифрувати файли
wrongFileAlert.message=Ви намагалися зашифрувати ці файли?
wrongFileAlert.description=Для цього Cryptomator надає том у системному файловому менеджері.
wrongFileAlert.description=Для цього Cryptomator додає том у ваш системний файловий менеджер.
wrongFileAlert.instruction.0=Щоб зашифрувати файли, виконайте такі кроки:
wrongFileAlert.instruction.1=1. Розблокуйте ваше сховище.
wrongFileAlert.instruction.2=2. Натисніть «Відкрити диск», щоб відкрити том у вашому файловому менеджері.
wrongFileAlert.instruction.2=2. Натисніть "Розгорнути", щоб відкрити том у вашому файловому менеджері.
wrongFileAlert.instruction.3=3. Додайте ваші файли до цього тому.
wrongFileAlert.link=Для отримання подальшої допомоги, відвідайте
@@ -455,27 +450,27 @@ wrongFileAlert.link=Для отримання подальшої допомог
## General
vaultOptions.general=Загальні
vaultOptions.general.vaultName=Назва сховища
vaultOptions.general.autoLock.lockAfterTimePart1=Блокувати після простою протягом
vaultOptions.general.autoLock.lockAfterTimePart1=Заблокувати коли не використовується протягом
vaultOptions.general.autoLock.lockAfterTimePart2=хвилин
vaultOptions.general.unlockAfterStartup=Розблоковувати сховище під час запуску Cryptomator
vaultOptions.general.actionAfterUnlock=Після успішного розблокування
vaultOptions.general.actionAfterUnlock.ignore=Нічого не робити
vaultOptions.general.actionAfterUnlock.reveal=Відкривати диск
vaultOptions.general.actionAfterUnlock.ask=Запитувати
vaultOptions.general.startHealthCheckBtn=Розпочати перевірку стану
vaultOptions.general.actionAfterUnlock.reveal=Розгорнути диск
vaultOptions.general.actionAfterUnlock.ask=Запитати
vaultOptions.general.startHealthCheckBtn=Розпочати перевірку працездатності
## Mount
vaultOptions.mount=Монтування
vaultOptions.mount.info=Відкрийте налаштування віртуального диска, щоб змінити параметри за замовчуванням.
vaultOptions.mount.info=Відкрийте вибір віртуального носія, щоб змінити налаштування за замовчуванням.
vaultOptions.mount.readonly=Тільки для перегляду
vaultOptions.mount.customMountFlags=Власні прапори монтування
vaultOptions.mount.customMountFlags=Користувацькі опції монтування
vaultOptions.mount.winDriveLetterOccupied=зайнято
vaultOptions.mount.mountPoint=Точка монтування
vaultOptions.mount.mountPoint.auto=Автоматично вибрати відповідне розташування
vaultOptions.mount.mountPoint.driveLetter=Використовувати призначену літеру диска
vaultOptions.mount.mountPoint.custom=Використовувати обраний каталог
vaultOptions.mount.mountPoint.auto=Автоматично підбирати зручне розташування
vaultOptions.mount.mountPoint.driveLetter=Використовувати призначену літеру для диска
vaultOptions.mount.mountPoint.custom=Використовувати обрану папку
vaultOptions.mount.mountPoint.directoryPickerButton=Обрати…
vaultOptions.mount.mountPoint.directoryPickerTitle=Виберіть каталог
vaultOptions.mount.mountPoint.directoryPickerTitle=Виберіть папку
vaultOptions.mount.volumeType.default=За замовчуванням (%s)
vaultOptions.mount.volumeType.restartRequired=Щоб використовувати цей тип тому, необхідно перезапустити Cryptomator.
vaultOptions.mount.volume.tcp.port=TCP порт
@@ -484,140 +479,107 @@ vaultOptions.mount.volume.type=Тип тому
vaultOptions.masterkey=Пароль
vaultOptions.masterkey.changePasswordBtn=Змінити пароль
vaultOptions.masterkey.forgetSavedPasswordBtn=Забути збережений пароль
vaultOptions.masterkey.recoveryKeyExplanation=Ключ відновлення — це ваш єдиний спосіб відновити доступ до сховища, якщо ви втратите пароль.
vaultOptions.masterkey.recoveryKeyExplanation=У разі втрати пароля, лише ключ відновлення залишиться єдиним способом отримання доступу до сховища.
vaultOptions.masterkey.showRecoveryKeyBtn=Показати ключ відновлення
vaultOptions.masterkey.recoverPasswordBtn=Скинути пароль
## Hub
vaultOptions.hub=Відновлення
vaultOptions.hub.convertInfo=Ви можете використати ключ відновлення, щоб у надзвичайній ситуації перетворити це Hub-сховище на сховище, захищене паролем.
vaultOptions.hub.convertBtn=Перетворити на сховище, захищене паролем
vaultOptions.hub.convertInfo=Ви можете використати ключ відновлення, щоб перетворити це сховище Hub у сховище на основі пароля в разі крайньої потреби.
vaultOptions.hub.convertBtn=Перетворити на сховище з паролем
# Recovery Key
## Display Recovery Key
recoveryKey.display.title=Показати ключ відновлення
recoveryKey.create.message=Потрібен пароль
recoveryKey.create.description=Введіть пароль для «%s», щоб показати його ключ відновлення.
recoveryKey.display.description=Зазначений ключ відновлення можна використовувати для відновлення доступу до «%s»:
recoveryKey.display.StorageHints=Зберігайте його в дуже надійному місці, наприклад:\n • Збережіть його за допомогою менеджера паролів\n • Збережіть його на USB-накопичувачі\n • Роздрукуйте його на папері
recoveryKey.create.description=Введіть пароль для "%s", щоб показати його ключ відновлення.
recoveryKey.display.description=Цей ключ можна використати для відновлення доступу до "%s":
recoveryKey.display.StorageHints=Зберігайте його у дуже безпечному місці, наприклад:\n • в менеджері паролів\n • на захищеному USB-носії\n • роздрукуйте на папері та зберігайте у недоступному для інших місці
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=Скинути пароль
recoveryKey.recover.prompt=Введіть ключ відновлення для «%s»:
recoveryKey.recover.correctKey=Цей ключ відновлення правильний
recoveryKey.recover.wrongKey=Цей ключ відновлення належить іншому сховищу
recoveryKey.recover.prompt=Введіть ключ відновлення для "%s:
recoveryKey.recover.correctKey=Цей ключ відновлення є правильним
recoveryKey.recover.wrongKey=Цей ключ відновлення належить до іншого сховища
recoveryKey.recover.invalidKey=Невірний ключ відновлення
recoveryKey.printout.heading=Ключ відновлення Cryptomator\n«%s»\n
recoveryKey.printout.heading=Ключ відновлення Cryptomator\n"%s"\n
### Reset Password
recoveryKey.recover.resetBtn=Скинути
### Recovery Key Password Reset Success
recoveryKey.recover.resetSuccess.message=Пароль успішно скинуто
recoveryKey.recover.resetSuccess.message=Пароль скинуто успішно
recoveryKey.recover.resetSuccess.description=Ви можете розблокувати своє сховище за допомогою нового пароля.
# Convert Vault
convertVault.title=Перетворити сховище
convertVault.convert.convertBtn.before=Перетворити
convertVault.convert.convertBtn.processing=Перетворення…
convertVault.success.message=Перетворення успішно виконано
convertVault.hubToPassword.success.description=Тепер ви можете розблокувати сховище за допомогою обраного пароля, не вимагаючи доступу до Hub.
convertVault.success.message=Перетворення виконано успішно
convertVault.hubToPassword.success.description=Тепер ви можете розблокувати сховище за допомогою обраного пароля без необхідності доступу до Hub.
# New Password
newPassword.promptText=Введіть новий пароль
newPassword.reenterPassword=Підтвердіть новий пароль
newPassword.passwordsMatch=Паролі збігаються!
newPassword.passwordsDoNotMatch=Паролі не збігаються
passwordStrength.messageLabel.tooShort=Використайте щонайменше %d символів
passwordStrength.messageLabel.tooShort=Введіть принаймні %d символів
passwordStrength.messageLabel.0=Дуже слабкий
passwordStrength.messageLabel.1=Слабкий
passwordStrength.messageLabel.2=Задовільний
passwordStrength.messageLabel.2=Посередній
passwordStrength.messageLabel.3=Надійний
passwordStrength.messageLabel.4=Дуже надiйний
# Quit
quit.title=Вийти з додатка
quit.message=Є розблоковані сховища
quit.description=Ви дійсно хочете вийти? Cryptomator коректно заблокує всі розблоковані сховища, щоб запобігти втраті даних.
quit.lockAndQuitBtn=Заблокувати та вийти
quit.description=Будь ласка, підтвердіть що ви хочете вийти. Cryptomator правильно заблокує всі розблоковані сховища, щоб запобігти втраті даних.
quit.lockAndQuitBtn=Заблокувати і вийти
# Forced Quit
quit.forced.message=Деякі сховища не вдалося заблокувати
quit.forced.description=Блокування сховищ було заблоковано через незавершені операції або відкриті файли. Ви можете примусово заблокувати сховища, що залишилися, однак переривання операцій читання/запису може призвести до втрати незбережених даних.
quit.forced.forceAndQuitBtn=Примусово заблокувати та вийти
quit.forced.message=Деякі сховища неможливо заблокувати
quit.forced.description=Блокування сховищ було перерване через операції з ними або відкриті файли. Ви можете примусово заблокувати сховища, проте переривання операцій зчитування-запису може призвести до втрати незбережених даних.
quit.forced.forceAndQuitBtn=Завершити роботу примусово
# Update Reminder
updateReminder.title=Перевірити наявність оновлень
updateReminder.message=Перевірити наявність оновлень?
updateReminder.description=Залишайтеся в курсі нових функцій, виправлень помилок та вдосконалень безпеки. Ми рекомендуємо автоматично перевіряти наявність оновлень.
updateReminder.description=Будьте в курсі нових функцій, виправлення помилок і вдосконалення безпеки. Ми рекомендуємо автоматично перевіряти наявність оновлень.
updateReminder.notNow=Не зараз
updateReminder.yesOnce=Так, лише раз
updateReminder.yesAutomatically=Так, автоматично
#Dokany Support End
dokanySupportEnd.title=Повідомлення про припинення підтримки
dokanySupportEnd.title=Застаріле повідомлення
dokanySupportEnd.message=Закінчення підтримки Dokany
dokanySupportEnd.description=Тип тому Dokany більше не підтримується Cryptomator. Ваші налаштування змінено на використання типу тому за замовчуванням. Переглянути стандартний тип можна в налаштуваннях.
dokanySupportEnd.description=Тип сховища Dokany більше не підтримується в Cryptomator. Тепер ваші налаштування змінено для використання типового типу сховища. Ви можете переглянути тип сховища за замовчуванням в налаштуваннях.
dokanySupportEnd.preferencesBtn=Відкрити налаштування
#Retry If Readonly
retryIfReadonly.title=Обмежений доступ до сховища
retryIfReadonly.message=Немає доступу для запису до каталогу сховища
retryIfReadonly.description=Cryptomator не може здійснити запис до каталогу сховища. Ви можете перевести сховище в режим «лише для читання» і спробувати знову. Цю опцію можна вимкнути в параметрах сховища.
retryIfReadonly.retry=Змінити та повторити спробу
retryIfReadonly.message=Немає прав на запис до папки сховища
retryIfReadonly.description=Cryptomator не може записувати в папку сховища. Ви можете змінити режим доступу до сховища на "лише для читання" і повторити спробу. Цей параметр можна вимкнути у налаштуваннях сховища.
retryIfReadonly.retry=Змінити і повторити спробу
# Share Vault
shareVault.title=Поділитися сховищем
shareVault.message=Хочете поділитися сховищем з іншими?
shareVault.description=Завжди будьте обережні, коли ділитесь своїм сховищем з іншими людьми. Якщо коротко, дотримуйтеся таких кроків:
shareVault.instruction.1=1. Надайте спільний доступ до зашифрованої папки сховища через хмарне сховище.
shareVault.instruction.2=2. Передайте пароль сховища безпечним способом.
shareVault.remarkBestPractices=Для отримання додаткової інформації перегляньте поради щодо найкращих практик у нашій документації.
shareVault.docsTooltip=Відкрийте документацію, щоб дізнатися більше про спільний доступ до сховищ.
shareVault.hubAd.description=Надійний спосіб для командної роботи
shareVault.hubAd.keyManagement=• Управління ключами за принципом «zero-knowledge»
shareVault.hubAd.authentication=Надійна автентифікація
shareVault.message=Ви хочете поділитися своїм сховищем з іншими?
shareVault.description=Завжди будьте обережні, коли ділитесь своїм сховищем з іншими людьми. Якщо коротко, виконайте ці кроки:
shareVault.instruction.1=1. Діліться доступом до зашифрованої папки сховища через хмарне сховище.
shareVault.instruction.2=2. Передавайте пароль сховища безпечним способом.
shareVault.remarkBestPractices=Для отримання додаткової інформації - ознайомтесь з кращим досвідом з наших документів.
shareVault.docsTooltip=Відкрийте документацію, щоб дізнатися більше про надання доступу до сховищ.
shareVault.hubAd.description=Безпечний спосіб роботи в командах
shareVault.hubAd.keyManagement=• Управління ключами без інформації про їх значення
shareVault.hubAd.authentication=Сильні механізми перевірки особи (автентифікації)
shareVault.hubAd.encryption=• Наскрізне шифрування
shareVault.visitHub=Відвідати Cryptomator Hub
shareVault.hub.message=Як надати спільний доступ до сховища Hub
shareVault.hub.description=Щоб надати спільний доступ до вмісту сховища іншому учаснику команди, потрібно виконати два кроки:
shareVault.hub.instruction.1=1. Надайте спільний доступ до зашифрованої папки сховища через хмарне сховище.
shareVault.hub.message=Як поділитись сховищем у хабі (Hub)
shareVault.hub.description=Щоб поділитися вмістом сховища з іншим членом команди, ви повинні виконати два кроки:
shareVault.hub.instruction.1=1. Поділіться доступом до зашифрованої папки сховища через хмарне сховище.
shareVault.hub.instruction.2=2. Надайте доступ учаснику команди у Cryptomator Hub.
shareVault.hub.openHub=Відкрити Cryptomator Hub
# Decrypt File Names
decryptNames.title=Розшифрування назв файлів
decryptNames.filePicker.title=Виберіть зашифрований файл
decryptNames.filePicker.extensionDescription=Зашифрований файл Cryptomator
decryptNames.copyTable.tooltip=Копіювати таблицю
decryptNames.clearTable.tooltip=Очистити таблицю
decryptNames.copyHint=Скопіювати вміст комірки за допомогою %s
decryptNames.dropZone.message=Перетягніть файли або натисніть, щоб вибрати
decryptNames.dropZone.error.vaultInternalFiles=Вибрано службові файли сховища, які не можна розшифрувати
decryptNames.dropZone.error.foreignFiles=Файли не належать до сховища «%s»
decryptNames.dropZone.error.noDirIdBackup=Каталог вибраних файлів не містить файл dirId.c9r
decryptNames.dropZone.error.generic=Не вдалося розшифрувати назви файлів
# Event View
eventView.title=Події
eventView.filter.allVaults=Усі
eventView.clearListButton.tooltip=Очистити список
## event list entries
eventView.entry.vaultLocked.description=Розблокуйте «%s» для отримання деталей
eventView.entry.conflictResolved.message=Конфлікт вирішено
eventView.entry.conflictResolved.showDecrypted=Показати розшифрований файл
eventView.entry.conflictResolved.copyDecrypted=Копіювати розшифрований шлях
eventView.entry.conflict.message=Не вдалося вирішити конфлікт
eventView.entry.conflict.showDecrypted=Показати розшифрований оригінальний файл
eventView.entry.conflict.copyDecrypted=Скопіювати розшифрований оригінальний шлях
eventView.entry.conflict.showEncrypted=Показати конфліктуючий зашифрований файл
eventView.entry.conflict.copyEncrypted=Скопіювати конфліктуючий зашифрований шлях
eventView.entry.decryptionFailed.message=Не вдалося розшифрувати
eventView.entry.decryptionFailed.showEncrypted=Показати зашифрований файл
eventView.entry.decryptionFailed.copyEncrypted=Копіювати зашифрований шлях
eventView.entry.brokenDirFile.message=Пошкоджене посилання на каталог
eventView.entry.brokenDirFile.showEncrypted=Показати пошкоджене зашифроване посилання
eventView.entry.brokenDirFile.copyEncrypted=Копіювати шлях пошкодженого посилання
eventView.entry.brokenFileNode.message=Пошкоджений вузол файлової системи
eventView.entry.brokenFileNode.showEncrypted=Показати пошкоджений зашифрований вузол
eventView.entry.brokenFileNode.copyEncrypted=Скопіювати шлях до пошкодженого зашифрованого вузла
eventView.entry.brokenFileNode.copyDecrypted=Копіювати розшифрований шлях

View File

@@ -291,7 +291,7 @@ preferences.general.keychainBackend=Lưu mật khẩu với
preferences.general.quickAccessService=Thêm các vault đã mở khóa vào khu vực truy cập nhanh
## Interface
preferences.interface=Giao diện
preferences.interface.theme=Chủ đề giao diện
preferences.interface.theme=Cái nhìn và cảm nhận
preferences.interface.theme.automatic=Tự động
preferences.interface.theme.dark=Tối
preferences.interface.theme.light=Sáng

View File

@@ -583,39 +583,21 @@ shareVault.hub.instruction.2=2. 在Cryptomator Hub中允許團隊成員對加密
shareVault.hub.openHub=打開 Cryptomator Hub
# Decrypt File Names
decryptNames.title=解密檔案名稱
decryptNames.filePicker.title=選擇已加密的檔案
decryptNames.filePicker.extensionDescription=Cryptomator 加密檔案
decryptNames.copyTable.tooltip=複製表格
decryptNames.clearTable.tooltip=清除表格
decryptNames.dropZone.message=拖放檔案或點擊選取
decryptNames.dropZone.error.vaultInternalFiles=所選取的加密檔案庫內部檔案並沒有可解密的檔名
decryptNames.dropZone.error.foreignFiles=檔案不屬於加密檔案庫「%s」
decryptNames.dropZone.error.noDirIdBackup=選取的檔案的資料夾並不包含dirId.c9r檔案
decryptNames.dropZone.error.generic=解密檔案名稱失敗
# Event View
eventView.title=事件
eventView.filter.allVaults=全部
eventView.clearListButton.tooltip=清空列表
## event list entries
eventView.entry.vaultLocked.description=解鎖「%s」以顯示詳細資訊
eventView.entry.conflictResolved.message=以解決的衝突
eventView.entry.conflictResolved.showDecrypted=顯示解密的檔案
eventView.entry.conflictResolved.copyDecrypted=複製解密路徑
eventView.entry.conflict.message=解決衝突失敗
eventView.entry.conflict.showDecrypted=顯示解密、原始的檔案
eventView.entry.conflict.copyDecrypted=複製解密、原始的路徑
eventView.entry.conflict.showEncrypted=顯示衝突的加密檔案
eventView.entry.conflict.copyEncrypted=複製衝突的加密檔案
eventView.entry.decryptionFailed.message=解密失敗
eventView.entry.decryptionFailed.showEncrypted=顯示加密的檔案
eventView.entry.decryptionFailed.copyEncrypted=複製加密路徑
eventView.entry.brokenDirFile.message=損壞的目錄連結
eventView.entry.brokenDirFile.showEncrypted=顯示損壞的加密路徑
eventView.entry.brokenDirFile.copyEncrypted=複製損壞的路徑連結
eventView.entry.brokenFileNode.message=損壞的檔案系統節點
eventView.entry.brokenFileNode.showEncrypted=顯示損壞的加密節點
eventView.entry.brokenFileNode.copyEncrypted=複製損壞的加密節點路徑
eventView.entry.brokenFileNode.copyDecrypted=複製解密路徑