diff --git a/.claude/rules/api-and-config.md b/.claude/rules/api-and-config.md index 83d3473c8..bf64a8c9e 100644 --- a/.claude/rules/api-and-config.md +++ b/.claude/rules/api-and-config.md @@ -2,6 +2,8 @@ - Respect precedence: `options.yml` overrides CLI/env values, which override defaults. - Adding a new option: update `internal/config/options.go` (yaml/flag tags), register in `internal/config/flags.go`, expose a getter, surface it in `*config.Report()`, and write generated values back to `options.yml`. Use `CliTestContext` in `internal/config/test.go` to exercise new flags. +- Adding a `customize.FeatureSettings` flag: a new field defaults to `true` via reflection (`features_default.go`) and is operator-disableable through `PHOTOPRISM_DISABLE_FEATURES` — no new CLI option needed. It cascades: update the full-struct literals in `internal/config/customize/{acl,scope}_test.go` and `internal/config/client_config_test.go` (the longest field name re-aligns every literal via gofmt), and `testdata/settings.yml` self-updates via `TestSettings_Save`. If the flag is only meaningful for accounts/roles, gate it per-session in `customize.Settings.ApplyACL` / `ApplyScope` (e.g. `Account`/`AppPasswords` require `ResourcePassword`/`ActionUpdate`); that shapes the Web UI client config only — enforce server-side behavior on the global flag via a `Config.DisableX()` helper. +- Identify an app-password credential by its session, not its token: `(*entity.Session).IsApplication()` (auth provider `application`) covers every grant that mints one (`password`/`session`/`cli`). The token format and grant type vary, so don't gate on `rnd.IsAppPassword` or `GrantType`. - For `options.yml` writes, prefer config-owned persistence helpers: `Config.SaveOptionsPatch(...)` for generic merges, `Config.SaveClusterOptionsUpdate(...)` for cluster-managed metadata. - Use `pkg/fs.ConfigFilePath` for config filenames so existing `.yml` files stay valid and new installs can adopt `.yaml` transparently. - Use the public accessors on `*config.Config` (e.g. `JWKSUrl()`, `SetJWKSUrl()`) instead of mutating `Config.Options()` directly; reserve raw option tweaks for test fixtures. @@ -20,6 +22,7 @@ ## API Shape Checklist When renaming or adding fields: +- Field casing: **TitleCase** (`UUID`, `Name`, `SiteUrl`) for fields backed by a DB entity (mirror the entity/model), **camelCase** (`storageNamespace`, `redirectUri`) for generated/artificial payloads (client config, session, action/RPC bodies). A filtered/computed entity projection stays TitleCase; an action payload stays camelCase but MAY TitleCase its single entity-identity field (e.g. `UUID`). See `specs/common/field-casing.md`. - Update DTOs in `internal/service/cluster/response.go` and any mappers. - Update handlers and regenerate Swagger: `make fmt-go swag-fmt swag`. - Update tests (search/replace old field names) and examples in `specs/`. @@ -35,5 +38,5 @@ When renaming or adding fields: - Map roles via the shared tables: users through `acl.ParseRole(s)` / `acl.UserRoles[...]`, clients through `acl.ClientRoles[...]`. - Treat `RoleAliasNone` ("none") and an empty string as `RoleNone`; default unknown client roles to `RoleClient`. -- Build CLI role help from `Roles.CliUsageString()` (e.g. `acl.ClientRoles.CliUsageString()`) — never hand-maintain role lists. +- Build CLI role help from the registered role map (never hand-maintained literals) so each edition lists exactly the roles it accepts: `commands.UserRoleUsageFor()` / `Roles.CliUsageString()`, passing CE `acl.UserRoles` or an edition's own static `auth.UserRoles` (reference the edition map directly, not the runtime-reassigned `acl.UserRoles`, to avoid the init-order trap; Portal's map includes `cluster_admin`). For federatable / cluster-instance contexts (LDAP, OIDC group→role, cluster grants) use `acl.ClusterInstanceRolesCliUsageString()` — it excludes `cluster_admin`/`visitor`. `pkg/txt.JoinOr` renders the "a, b, or c" style. - For JWT/client scope checks, use the shared helpers (`acl.ScopePermits` / `acl.ScopeAttrPermits`). diff --git a/.claude/rules/commit-and-docs-style.md b/.claude/rules/commit-and-docs-style.md index 5d17e8db1..284073b74 100644 --- a/.claude/rules/commit-and-docs-style.md +++ b/.claude/rules/commit-and-docs-style.md @@ -27,6 +27,10 @@ Descriptions MUST conclude with a checklist of **Acceptance Criteria**: - `MUST` — required for the issue to be considered complete - `SHOULD` — strongly recommended but not strictly required - `MAY` — optional enhancement +- Keep the checklist current: once the work for a criterion is implemented **and verified**, mark it done (`- [x]`). +- Leave items that are unverified, not yet implemented, or skipped optional (`MAY`) enhancements unchecked. +- An issue is complete only when every `MUST` is checked; never tick a box on the strength of a plan alone or an unrun test. +- When referencing an issue from a commit that fulfills some of its criteria, update the matching boxes first. > Agents MUST create, edit, close, reopen, relabel, or otherwise modify GitHub issues only when explicitly requested by the user. diff --git a/.claude/rules/frontend-rules.md b/.claude/rules/frontend-rules.md index ced3e024e..982f2e9f7 100644 --- a/.claude/rules/frontend-rules.md +++ b/.claude/rules/frontend-rules.md @@ -39,11 +39,11 @@ ## Frontend Test Gotchas -- Hidden-route UI checks under `/library/hidden` or `/portal/admin/hidden` require both `files.file_error` and `photos.photo_quality = -1`; `file_error` alone will not surface the row. +- Hidden-route UI checks under `/library/hidden` or `/portal/hidden` require both `files.file_error` and `photos.photo_quality = -1`; `file_error` alone will not surface the row. ## Playwright MCP Usage -- Endpoint `http://localhost:2342/`; logins at `/library/login` (CE/Plus/Pro) and `/portal/admin/login` (Portal). Use local compose admin credentials; if login fails, inspect the active compose env. +- Endpoint `http://localhost:2342/`; logins at `/library/login` (CE/Plus/Pro) and `/portal/login` (Portal). Use local compose admin credentials; if login fails, inspect the active compose env. - Viewports: desktop `1280x900`; mobile uses the mobile Playwright server at `375x667`. Close the browser tab after scripted interactions. - Prefer waits over sleeps; click only visible/enabled elements; use role/label/text selectors (not XPath). - Screenshots: small and reproducible — JPEG, visible viewport, deterministic `.local/screenshots//__.jpg` names, no large inline screenshots. @@ -60,8 +60,12 @@ ## Frontend Translations - Never hardcode locale strings in templates or scripts — every user-visible string MUST go through `$gettext` / `T` so it appears in `frontend/src/locales/translations.pot`. -- Extraction source of truth: root `make gettext-extract` (via `scripts/gettext-extract.sh`), which scans `frontend/src` plus available overlays in `plus/frontend`, `pro/frontend`, `portal/frontend`. +- **Exception — standardized technical identifiers stay untranslated.** Render protocol/acronym/identifier field labels and option values as literal strings, not via `$gettext`: e.g. `Client ID`, `Client Credentials`, `OIDC`, `UUID`, `Node UUID`. Translating them adds catalog noise and risks ambiguous renderings (e.g. "Client" → German "Kunde"). Common English field names like `Site URL` or `Advertise URL` stay translated. +- **Share role/provider labels, not the selectable lists.** Display names live once in `frontend/src/options/auth.js` (`Roles()` / `Providers()` maps, with `RoleOptions(keys, labelKey)` / `ProviderOptions(keys, labelKey)` builders). Private editions (`plus`/`pro`/`portal`) import these and pass their own key list — the selectable sets legitimately differ per edition (cluster_admin, LDAP/AD, reduced Plus set) but the labels must not be re-listed. +- Extraction source of truth: root `make gettext-extract` (via `scripts/gettext-extract.sh`), which scans `frontend/src` plus available overlays in `plus/frontend`, `pro/frontend`, `portal/frontend`. Feature PRs do **not** commit the resulting `.pot`/`.po` churn — Weblate re-extracts on its refresh cycle (see `specs/frontend/translations.md`); a dedicated "Regenerate translation catalogs" commit is the exception. - Avoid punctuation-only gettext keys (e.g. `$gettext("—")`) — they clutter `frontend/src/locales/translations.pot`. +- Catalog integrity gate: run `make gettext-lint` (`scripts/gettext-lint.mjs`) after any `.po`/`.pot` edit. It flags placeholder-set mismatches between `msgid` and `msgstr` (frontend `%{name}`, backend printf verbs), edge-whitespace drift, and `msgfmt -c` c-format fatals — defects that silently break variable substitution at runtime. Leading/trailing/internal whitespace inside a `msgid` is itself runtime-inert (`vue3-gettext` trims + collapses keys on load and lookup), so trailing-space findings are cleanliness, not correctness. +- Trimming a source string's trailing space must stay consistent across template + `.po` + `.pot`: trim the literal, then `make gettext-extract`. Caveat: `msgmerge --no-fuzzy-matching` treats the trimmed `msgid` as new, blanks its `msgstr`, and moves the old translation to an obsolete `#~` block — so carry that translation onto the active trimmed entry (collapse any folded multi-line `#~ msgstr`) before `make gettext-compile`, or every locale renders untranslated. This only fills `msgstr`, so Weblate merges it cleanly. ## Web Templates & Shared Assets diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 19c0508ec..9c259a0a5 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -13,7 +13,7 @@ PLEASE PROCEED ONLY IF YOU ARE SURE THAT THIS IS NOT A TECHNICAL SUPPORT INCIDEN 1. Thoroughly review our [Getting Started](https://docs.photoprism.app/getting-started/) and [User Guides](https://docs.photoprism.app/user-guide/). 2. Work through the [Troubleshooting Checklists](https://docs.photoprism.app/getting-started/troubleshooting/) we provide. 3. Do not report [known issues](https://docs.photoprism.app/known-issues/) or [missing features](https://github.com/photoprism/photoprism/issues) as bugs. -4. Use [GitHub Discussions](https://github.com/photoprism/photoprism/discussions) for community help, and visit our [Support Guide](https://www.photoprism.app/kb/getting-support) to learn more about support options. +4. Use [GitHub Discussions](https://github.com/photoprism/photoprism/discussions) for community help, and visit our [Support Guide](https://www.photoprism.app/kb/getting-support/) to learn more about support options. THANK YOU! 💎 @@ -23,7 +23,7 @@ THANK YOU! 💎 Links to the related documentation on [docs.photoprism.app](https://docs.photoprism.app/): - ... -*Please never report [known issues](https://docs.photoprism.app/known-issues/) or [missing features](https://github.com/photoprism/photoprism/issues) as bugs, and do not submit bug reports for the purpose of getting [technical support](https://www.photoprism.app/kb/getting-support) or because you have not received a response in our [public community forums](https://github.com/photoprism/photoprism/discussions). Thank you very much!* +*Please never report [known issues](https://docs.photoprism.app/known-issues/) or [missing features](https://github.com/photoprism/photoprism/issues) as bugs, and do not submit bug reports for the purpose of getting [technical support](https://www.photoprism.app/kb/getting-support/) or because you have not received a response in our [public community forums](https://github.com/photoprism/photoprism/discussions). Thank you very much!* ### 1. How can we reproduce it? @@ -46,7 +46,7 @@ Always try to determine the cause of your problem using the checklists at for details. +Please include sample files or screenshots that help to reproduce your problem. You can also email files or share a download link, see for details. Visit to learn how to diagnose frontend issues. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 01ac9afce..0f3349f00 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -11,7 +11,7 @@ body: 1. Thoroughly review our [Getting Started](https://docs.photoprism.app/getting-started/) and [User Guides](https://docs.photoprism.app/user-guide/). 2. Work through the [Troubleshooting Checklists](https://docs.photoprism.app/getting-started/troubleshooting/) we provide. 3. Do not report [known issues](https://docs.photoprism.app/known-issues/) or [missing features](https://github.com/photoprism/photoprism/issues) as bugs. - 4. Use [GitHub Discussions](https://github.com/photoprism/photoprism/discussions) for community help, and visit our [Support Guide](https://www.photoprism.app/kb/getting-support) to learn more about support options. + 4. Use [GitHub Discussions](https://github.com/photoprism/photoprism/discussions) for community help, and visit our [Support Guide](https://www.photoprism.app/kb/getting-support/) to learn more about support options. - type: textarea id: documented-behavior attributes: diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 5cea95fd2..090c11be8 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -4,5 +4,5 @@ contact_links: url: https://github.com/photoprism/photoprism/discussions about: Use Discussions for general questions, community support, and troubleshooting help. - name: Read Our Support Guide - url: https://www.photoprism.app/kb/getting-support + url: https://www.photoprism.app/kb/getting-support/ about: Learn about official support options and how to get assistance with PhotoPrism. diff --git a/AGENTS.md b/AGENTS.md index 4cbec0164..d919667d8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -54,6 +54,10 @@ Optional nested repositories such as `plus/`, `pro/`, `portal/`, and `specs/` ma - Use level-3 Markdown headings for sections within issue descriptions, for example `### Acceptance Criteria`. - Follow with behavior, rationale, technical considerations, and constraints. - End with `- [ ]` checklist items for the acceptance criteria, each using `MUST`, `SHOULD`, or `MAY`. + - Keep the checklist current: once the work for a criterion is implemented **and verified**, mark it done (`- [x]`). + - Leave items that are unverified, not yet implemented, or skipped optional (`MAY`) enhancements unchecked. + - An issue is complete only when every `MUST` is checked; never tick a box on the strength of a plan alone or an unrun test. + - When referencing an issue from a commit that fulfills some of its criteria, update the matching boxes first. - Agents MUST create, edit, close, reopen, relabel, or otherwise modify GitHub issues only when explicitly requested by the user. ### Specifications & Documentation diff --git a/CODEMAP.md b/CODEMAP.md index 1d5e5559c..133312f9e 100644 --- a/CODEMAP.md +++ b/CODEMAP.md @@ -70,7 +70,7 @@ HTTP API - `make swag-json` runs a stabilization step (`swaggerfix`) removing duplicated enums for `time.Duration`; API uses integer nanoseconds for durations. - `/api/v1/metrics` (see `internal/api/metrics.go`) exposes Prometheus metrics, including cached filesystem/account usage derived from `config.Usage()`, registered user/guest totals, and portal cluster node counts when `NodeRole=portal`; the handler returns the standard Prometheus exposition content type (`text/plain; version=0.0.4`). - Common groups in `routes.go`: sessions, OAuth/OIDC, config, users, services, thumbnails, video, downloads/zip, index/import, photos/files/labels/subjects/faces, batch ops, cluster, technical (metrics, status, echo). -- Hidden search behavior (used by the hidden route under the configured frontend URI, default `/library/hidden` for CE/Plus/Pro and `/portal/admin/hidden` for Portal) is implemented in `internal/entity/search/photos.go`: +- Hidden search behavior (used by the hidden route under the configured frontend URI, default `/library/hidden` for CE/Plus/Pro and `/portal/hidden` for Portal) is implemented in `internal/entity/search/photos.go`: - `frm.Hidden` enforces `photos.photo_quality = -1` and `photos.deleted_at IS NULL`. - Non-hidden searches exclude errored files by default (`files.file_error = ''`) unless `frm.Error` is explicitly set. - Search DTOs in `internal/entity/search/photos_results.go` expose `FileError` (`files.file_error`) so clients can render hidden reasons without loading full file details first. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 1d7943784..5d3e6cef7 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,8 +1,8 @@ # PhotoPrism® Code of Conduct -**By using the software and services we provide, you agree to our [Terms of Service](https://www.photoprism.app/terms), including our [Privacy Policy](https://www.photoprism.app/privacy) and the following Code of Conduct. It explains the "dos and don’ts" when interacting with our team and other community members.** +**By using the software and services we provide, you agree to our [Terms of Service](https://www.photoprism.app/terms/), including our [Privacy Policy](https://www.photoprism.app/privacy/) and the following Code of Conduct. It explains the "dos and don’ts" when interacting with our team and other community members.** -*This Code of Conduct was last updated on May 30, 2026. A German translation is available at [photoprism.app/de/code-of-conduct](https://www.photoprism.app/de/code-of-conduct).* +*This Code of Conduct was last updated on May 30, 2026. A German translation is available at [photoprism.app/de/code-of-conduct](https://www.photoprism.app/de/code-of-conduct/).* ## Rules @@ -30,7 +30,7 @@ We have found that many of the issues that new users get upset about when they r ## Reporting -We encourage all community members to resolve problems on their own whenever possible. Serious and persistent violations, such as disrespectful, abusive, harassing, or otherwise unacceptable behavior, [may be reported](https://www.photoprism.app/contact) to us. +We encourage all community members to resolve problems on their own whenever possible. Serious and persistent violations, such as disrespectful, abusive, harassing, or otherwise unacceptable behavior, [may be reported](https://www.photoprism.app/contact/) to us. ## Enforcement @@ -38,4 +38,4 @@ Our community standards will be enforced as necessary to protect everyone's well In cases where violations may be unintentional and improvement seems possible, we aim to issue warnings before taking further action. -In serious cases, we may use technical measures to restrict your access to our infrastructure, including GitHub, forums, and chats, either temporarily or permanently. We also reserve the right to delete rants, personal attacks, spam, and unsolicited advertisements. If you believe we made a mistake, you may [email us](https://www.photoprism.app/contact) to request an appeal. \ No newline at end of file +In serious cases, we may use technical measures to restrict your access to our infrastructure, including GitHub, forums, and chats, either temporarily or permanently. We also reserve the right to delete rants, personal attacks, spam, and unsolicited advertisements. If you believe we made a mistake, you may [email us](https://www.photoprism.app/contact/) to request an appeal. \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b4d175e3c..1fba42708 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,9 +4,9 @@ We welcome contributions of any kind, including blog posts, tutorials, testing, ## Join the Community ## -Follow us on [Mastodon](https://floss.social/@photoprism), [Bluesky](https://bsky.app/profile/photoprism.app), or join the [Community Chat](https://link.photoprism.app/chat) to get regular updates, connect with other users, and discuss your ideas. Our [Code of Conduct](https://www.photoprism.app/code-of-conduct) explains the "dos and don’ts" when interacting with other community members. +Follow us on [Mastodon](https://floss.social/@photoprism), [Bluesky](https://bsky.app/profile/photoprism.app), or join the [Community Chat](https://link.photoprism.app/chat) to get regular updates, connect with other users, and discuss your ideas. Our [Code of Conduct](https://www.photoprism.app/code-of-conduct/) explains the "dos and don’ts" when interacting with other community members. -As a [contributor](https://docs.photoprism.app/developer-guide/), you are also welcome to [contact us directly](https://www.photoprism.app/contact) if you have something on your mind that you don't want to discuss publicly. Please note, however, that due to the high volume of emails we receive, our team may be unable to get back to you immediately. We do our best to respond within five business days or less. +As a [contributor](https://docs.photoprism.app/developer-guide/), you are also welcome to [contact us directly](https://www.photoprism.app/contact/) if you have something on your mind that you don't want to discuss publicly. Please note, however, that due to the high volume of emails we receive, our team may be unable to get back to you immediately. We do our best to respond within five business days or less. ## Not a Developer? No Problem ## @@ -36,7 +36,7 @@ We kindly ask you not to report bugs via GitHub Issues **unless you are certain - When reporting a problem, always include the software versions you are using and other information about your environment such as [browser, browser plugins](https://docs.photoprism.app/getting-started/troubleshooting/browsers/), operating system, [storage type](https://docs.photoprism.app/getting-started/troubleshooting/performance/#storage), [memory size](https://docs.photoprism.app/getting-started/troubleshooting/performance/#memory), and [processor](https://docs.photoprism.app/getting-started/troubleshooting/performance/#server-cpu) - Note that all issue **subscribers receive an email notification** from GitHub whenever a new comment is added, so these should only be used for sharing important information and not for discussions, questions or expressing personal opinions -- [Contact us](https://www.photoprism.app/contact) or [a community member](https://link.photoprism.app/discussions) if you need help, it could be a local configuration problem, or a misunderstanding in how the software works +- [Contact us](https://www.photoprism.app/contact/) or [a community member](https://link.photoprism.app/discussions) if you need help, it could be a local configuration problem, or a misunderstanding in how the software works - This gives our team the opportunity to [improve the docs](https://docs.photoprism.app/getting-started/troubleshooting/) and provide best-in-class support to you, instead of handling unclear/duplicate bug reports or triggering a flood of notifications by responding to comments ## Submitting Pull Requests ## @@ -51,7 +51,7 @@ Pull requests solving ["help wanted"](https://github.com/photoprism/photoprism/l ## Contributor License Agreement (CLA) ## -After you submit your first pull request, you will be asked to accept our Contributor License Agreement (CLA). Visit [photoprism.app/cla](https://www.photoprism.app/cla) and [photoprism.app/oss/faq](https://www.photoprism.app/oss/faq#cla) to learn more. +After you submit your first pull request, you will be asked to accept our Contributor License Agreement (CLA). Visit [photoprism.app/cla](https://www.photoprism.app/cla/) and [photoprism.app/oss/faq](https://www.photoprism.app/oss/faq/#cla) to learn more. ## Thank You to All Current and Past Sponsors 💎 ## @@ -76,4 +76,4 @@ Because many of these apps and tools were originally developed for internal use ---- -*PhotoPrism® is a [registered trademark](https://www.photoprism.app/trademark). By using the software and services we provide, you agree to our [Terms of Service](https://www.photoprism.app/terms), [Privacy Policy](https://www.photoprism.app/privacy), and [Code of Conduct](https://www.photoprism.app/code-of-conduct). Docs are [available](https://link.photoprism.app/github-docs) under the [CC BY-NC-SA 4.0 License](https://creativecommons.org/licenses/by-nc-sa/4.0/); [additional terms](https://github.com/photoprism/photoprism/blob/develop/assets/README.md) may apply.* +*PhotoPrism® is a [registered trademark](https://www.photoprism.app/trademark/). By using the software and services we provide, you agree to our [Terms of Service](https://www.photoprism.app/terms/), [Privacy Policy](https://www.photoprism.app/privacy/), and [Code of Conduct](https://www.photoprism.app/code-of-conduct/). Docs are [available](https://link.photoprism.app/github-docs) under the [CC BY-NC-SA 4.0 License](https://creativecommons.org/licenses/by-nc-sa/4.0/); [additional terms](https://github.com/photoprism/photoprism/blob/develop/assets/README.md) may apply.* diff --git a/Dockerfile b/Dockerfile index e5bdd9a9e..2a5bbfc1d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Ubuntu 26.04 LTS (Resolute Raccoon) -FROM photoprism/develop:260531-resolute +FROM photoprism/develop:260709-resolute # Harden npm usage by default (applies to npm ci / install in dev container) ENV NPM_CONFIG_IGNORE_SCRIPTS=true diff --git a/FUNDING.yml b/FUNDING.yml index 6aef57e9c..59ac9122e 100644 --- a/FUNDING.yml +++ b/FUNDING.yml @@ -1,3 +1,3 @@ -custom: "https://www.photoprism.app/editions#compare" +custom: "https://www.photoprism.app/editions/#compare" github: photoprism patreon: photoprism \ No newline at end of file diff --git a/LICENSE b/LICENSE index ca13a5762..aec49a5f5 100644 --- a/LICENSE +++ b/LICENSE @@ -625,7 +625,7 @@ corporate design, product and service names, and any other brand features and elements, whether registered or unregistered („Brand Assets“) — are proprietary assets owned exclusively by PhotoPrism UG („PhotoPrism“). We reserve the right to object to any use or misuse in any jurisdiction -worldwide. Visit to learn more. +worldwide. Visit to learn more. (b) Contributors, licensees, business partners, and other third parties may never claim ownership of PhotoPrism's Brand Assets or brands confusingly diff --git a/Makefile b/Makefile index 3c681b212..ea696d52b 100644 --- a/Makefile +++ b/Makefile @@ -89,21 +89,22 @@ test-commands: run-test-commands test-photoprism: run-test-photoprism test-short: run-test-short test-mariadb: reset-acceptance run-test-mariadb -acceptance-run-chromium: storage/acceptance acceptance-auth-sqlite-restart wait acceptance-auth acceptance-auth-sqlite-stop acceptance-sqlite-restart wait-2 acceptance acceptance-sqlite-stop -acceptance-run-chromium-short: storage/acceptance acceptance-auth-sqlite-restart wait acceptance-auth-short acceptance-auth-sqlite-stop acceptance-sqlite-restart wait-2 acceptance-short acceptance-sqlite-stop -acceptance-auth-run-chromium: storage/acceptance acceptance-auth-sqlite-restart wait acceptance-auth acceptance-auth-sqlite-stop -acceptance-public-run-chromium: storage/acceptance acceptance-sqlite-restart wait acceptance acceptance-sqlite-stop +acceptance-run-chromium: storage/acceptance acceptance-sqlite-restart-1 wait-1 acceptance-api acceptance-sqlite-stop-1 acceptance-auth-sqlite-restart wait-2 acceptance-auth acceptance-auth-sqlite-stop acceptance-sqlite-restart-3 wait-3 acceptance acceptance-sqlite-stop-3 +acceptance-run-chromium-short: storage/acceptance acceptance-auth-sqlite-restart wait-1 acceptance-auth-short acceptance-auth-sqlite-stop acceptance-sqlite-restart-2 wait-2 acceptance-short acceptance-sqlite-stop-2 +acceptance-auth-run-chromium: storage/acceptance acceptance-auth-sqlite-restart wait-1 acceptance-auth acceptance-auth-sqlite-stop +acceptance-public-run-chromium: storage/acceptance acceptance-sqlite-restart-1 wait-1 acceptance acceptance-sqlite-stop-1 +acceptance-api-run-chromium: storage/acceptance acceptance-sqlite-restart-1 wait-1 acceptance-api acceptance-sqlite-stop-1 help: list list: @awk '/^[[:alnum:]]+[^[:space:]]+:/ {printf "%s",substr($$1,1,length($$1)-1); if (match($$0,/#/)) {desc=substr($$0,RSTART+1); sub(/^[[:space:]]+/,"",desc); printf " - %s\n",desc} else printf "\n" }' "$(firstword $(MAKEFILE_LIST))" -wait: - sleep 20 -wait-2: +wait-%: sleep 20 show-rev: @git rev-parse HEAD show-build: @echo "$(BUILD_TAG)" +tag-release: + scripts/tag-release.sh $(EDITION) $(TAG_ARGS) test-all: test acceptance-run-chromium fmt: fmt-js fmt-go fmt-swag format: format-tables fmt-go fmt-swag @@ -180,6 +181,8 @@ gettext-compile: $(MAKE) -C frontend gettext-compile gettext-clear-fuzzy: ./scripts/gettext-clear-fuzzy.sh +gettext-lint: + node scripts/gettext-lint.mjs clean: rm -f *.log .test* [ ! -f "$(BINARY_NAME)" ] || rm -f $(BINARY_NAME) @@ -224,7 +227,7 @@ install-onnx: sudo scripts/dist/install-onnx.sh install-darktable: sudo scripts/dist/install-darktable.sh -acceptance-sqlite-restart: acceptance-sqlite-stop +acceptance-sqlite-restart-%: acceptance-sqlite-stop-% cp -f storage/acceptance/backup.db storage/acceptance/index.db cp -f storage/acceptance/config-sqlite/settingsBackup.yml storage/acceptance/config-sqlite/settings.yml rm -rf storage/acceptance/sidecar/2020 @@ -235,7 +238,7 @@ acceptance-sqlite-restart: acceptance-sqlite-stop rm -rf storage/acceptance/originals/2013 rm -rf storage/acceptance/originals/2017 ./photoprism --auth-mode="public" -c "./storage/acceptance/config-sqlite" start -d -acceptance-sqlite-stop: +acceptance-sqlite-stop-%: ./photoprism --auth-mode="public" -c "./storage/acceptance/config-sqlite" stop acceptance-auth-sqlite-restart: acceptance-auth-sqlite-stop cp -f storage/acceptance/backup.db storage/acceptance/index.db @@ -436,21 +439,23 @@ build-static: scripts/build.sh static $(BINARY_NAME) build-libheif: build-libheif-amd64 build-libheif-arm64 build-libheif-armv7 build-libheif-amd64: - docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:resolute ./scripts/dist/build-libheif.sh v1.22.2 - docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:questing ./scripts/dist/build-libheif.sh v1.22.2 - docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:plucky ./scripts/dist/build-libheif.sh v1.22.2 - docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:noble ./scripts/dist/build-libheif.sh v1.22.2 - docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:jammy ./scripts/dist/build-libheif.sh v1.22.2 - docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:bookworm ./scripts/dist/build-libheif.sh v1.22.2 + docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:resolute ./scripts/dist/build-libheif.sh v1.23.1 + docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:questing ./scripts/dist/build-libheif.sh v1.23.1 + docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:plucky ./scripts/dist/build-libheif.sh v1.23.1 + docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:noble ./scripts/dist/build-libheif.sh v1.23.1 + docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:jammy ./scripts/dist/build-libheif.sh v1.23.1 + docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:bookworm ./scripts/dist/build-libheif.sh v1.23.1 + docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:trixie ./scripts/dist/build-libheif.sh v1.23.1 build-libheif-arm64: - docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:resolute ./scripts/dist/build-libheif.sh v1.22.2 - docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:questing ./scripts/dist/build-libheif.sh v1.22.2 - docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:plucky ./scripts/dist/build-libheif.sh v1.22.2 - docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:noble ./scripts/dist/build-libheif.sh v1.22.2 - docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:jammy ./scripts/dist/build-libheif.sh v1.22.2 - docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:bookworm ./scripts/dist/build-libheif.sh v1.22.2 + docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:resolute ./scripts/dist/build-libheif.sh v1.23.1 + docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:questing ./scripts/dist/build-libheif.sh v1.23.1 + docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:plucky ./scripts/dist/build-libheif.sh v1.23.1 + docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:noble ./scripts/dist/build-libheif.sh v1.23.1 + docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:jammy ./scripts/dist/build-libheif.sh v1.23.1 + docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:bookworm ./scripts/dist/build-libheif.sh v1.23.1 + docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:trixie ./scripts/dist/build-libheif.sh v1.23.1 build-libheif-armv7: - docker run --rm -u $(UID) --platform=arm --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm -e SYSTEM_ARCH=arm photoprism/develop:armv7 ./scripts/dist/build-libheif.sh v1.22.2 + docker run --rm -u $(UID) --platform=arm --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm -e SYSTEM_ARCH=arm photoprism/develop:armv7 ./scripts/dist/build-libheif.sh v1.23.1 build-libheif-latest: build-libheif-amd64-latest build-libheif-arm64-latest build-libheif-armv7-latest build-libheif-amd64-latest: docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:resolute ./scripts/dist/build-libheif.sh @@ -468,9 +473,9 @@ build-libheif-armv7-latest: docker run --rm -u $(UID) --platform=arm --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm -e SYSTEM_ARCH=arm photoprism/develop:armv7 ./scripts/dist/build-libheif.sh build-libheif-deb: build-libheif-deb-amd64 build-libheif-deb-arm64 build-libheif-deb-amd64: - docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:resolute ./scripts/dist/build-libheif-deb.sh v1.22.2 + docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:resolute ./scripts/dist/build-libheif-deb.sh v1.23.1 build-libheif-deb-arm64: - docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:resolute ./scripts/dist/build-libheif-deb.sh v1.22.2 + docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:resolute ./scripts/dist/build-libheif-deb.sh v1.23.1 build-tensorflow: docker-tensorflow-amd64 docker-tensorflow: docker-tensorflow-amd64 docker-tensorflow-amd64: @@ -496,20 +501,23 @@ test-js: (cd frontend && npm run test) acceptance: $(info Running public-mode tests in Chrome...) - (cd frontend && find ./tests/acceptance -type f -name "*.js" | xargs -i perl -0777 -ne 'while(/(?:mode: \"auth[^,]*\,)|(Multi-Window\:[A-Za-z 0-9\-_]*)/g){print "$$1\n" if ($$1);}' {} | xargs -I testname bash -c 'npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --experimental-multiple-windows --test-meta mode=public --config-file ./testcaferc.json --test "testname" "tests/acceptance"') - (cd frontend && npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --test-grep "^(Common|Core)\:*" --test-meta mode=public --config-file ./testcaferc.json "tests/acceptance") + (cd frontend && find ./tests/acceptance -type f -name "*.js" | xargs -i perl -0777 -ne 'while(/(?:mode: \"auth[^,]*\,)|(Multi-Window\:[A-Za-z 0-9\-_]*)/g){print "$$1\n" if ($$1);}' {} | xargs -I testname bash -c 'npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --experimental-multiple-windows --test-meta mode=public --config-file ./.testcaferc.cjs --test "testname" "tests/acceptance"') + (cd frontend && npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --test-grep "^(Common|Core)\:*" --test-meta mode=public --config-file ./.testcaferc.cjs "tests/acceptance") acceptance-short: $(info Running JS acceptance tests in Chrome...) - (cd frontend && find ./tests/acceptance -type f -name "*.js" | xargs -i perl -0777 -ne 'while(/(?:mode: \"auth[^,]*\,)|(Multi-Window\:[A-Za-z 0-9\-_]*)/g){print "$$1\n" if ($$1);}' {} | xargs -I testname bash -c 'npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --experimental-multiple-windows --test-meta mode=public,type=short --config-file ./testcaferc.json --test "testname" "tests/acceptance"') - (cd frontend && npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --test-grep "^(Common|Core)\:*" --test-meta mode=public,type=short --config-file ./testcaferc.json "tests/acceptance") + (cd frontend && find ./tests/acceptance -type f -name "*.js" | xargs -i perl -0777 -ne 'while(/(?:mode: \"auth[^,]*\,)|(Multi-Window\:[A-Za-z 0-9\-_]*)/g){print "$$1\n" if ($$1);}' {} | xargs -I testname bash -c 'npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --experimental-multiple-windows --test-meta mode=public,type=short --config-file ./.testcaferc.cjs --test "testname" "tests/acceptance"') + (cd frontend && npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --test-grep "^(Common|Core)\:*" --test-meta mode=public,type=short --config-file ./.testcaferc.cjs "tests/acceptance") acceptance-auth: $(info Running JS acceptance-auth tests in Chrome...) - (cd frontend && find ./tests/acceptance -type f -name "*.js" | xargs -i perl -0777 -ne 'while(/(?:mode: \"public[^,]*\,)|(Multi-Window\:[A-Za-z 0-9\-_]*)/g){print "$$1\n" if ($$1);}' {} | xargs -I testname bash -c 'npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --experimental-multiple-windows --test-meta mode=auth --config-file ./testcaferc.json --test "testname" "tests/acceptance"') - (cd frontend && npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --test-grep "^(Common|Core)\:*" --test-meta mode=auth --config-file ./testcaferc.json "tests/acceptance") + (cd frontend && find ./tests/acceptance -type f -name "*.js" | xargs -i perl -0777 -ne 'while(/(?:mode: \"public[^,]*\,)|(Multi-Window\:[A-Za-z 0-9\-_]*)/g){print "$$1\n" if ($$1);}' {} | xargs -I testname bash -c 'npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --experimental-multiple-windows --test-meta mode=auth --config-file ./.testcaferc.cjs --test "testname" "tests/acceptance"') + (cd frontend && npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --test-grep "^(Common|Core)\:*" --test-meta mode=auth --config-file ./.testcaferc.cjs "tests/acceptance") acceptance-auth-short: $(info Running JS acceptance-auth tests in Chrome...) - (cd frontend && find ./tests/acceptance -type f -name "*.js" | xargs -i perl -0777 -ne 'while(/(?:mode: \"public[^,]*\,)|(Multi-Window\:[A-Za-z 0-9\-_]*)/g){print "$$1\n" if ($$1);}' {} | xargs -I testname bash -c 'npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --experimental-multiple-windows --test-meta mode=auth,type=short --config-file ./testcaferc.json --test "testname" "tests/acceptance"') - (cd frontend && npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --test-grep "^(Common|Core)\:*" --test-meta mode=auth,type=short --config-file ./testcaferc.json "tests/acceptance") + (cd frontend && find ./tests/acceptance -type f -name "*.js" | xargs -i perl -0777 -ne 'while(/(?:mode: \"public[^,]*\,)|(Multi-Window\:[A-Za-z 0-9\-_]*)/g){print "$$1\n" if ($$1);}' {} | xargs -I testname bash -c 'npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --experimental-multiple-windows --test-meta mode=auth,type=short --config-file ./.testcaferc.cjs --test "testname" "tests/acceptance"') + (cd frontend && npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --test-grep "^(Common|Core)\:*" --test-meta mode=auth,type=short --config-file ./.testcaferc.cjs "tests/acceptance") +acceptance-api: + $(info Running JS acceptance-api tests in Chrome...) + (cd frontend && npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --test-meta mode=api --config-file ./.testcaferc.cjs "tests/acceptance") vitest-watch: $(info Running Vitest unit tests in watch mode...) (cd frontend && npm run test-watch) @@ -603,7 +611,7 @@ docker-pull: $(DOCKER_COMPOSE) -f compose.latest.yaml pull --ignore-pull-failures build-docker: docker-build docker-build: - $(DOCKER_COMPOSE) --profile=all pull --ignore-pull-failures + $(DOCKER_COMPOSE) --profile=postgres --profile=keycloak pull --ignore-pull-failures $(DOCKER_COMPOSE) down --remove-orphans $(DOCKER_COMPOSE) build --pull nvidia: nvidia-up @@ -1074,9 +1082,6 @@ docker-local-develop-resolute: docker-ddns: docker pull golang:alpine scripts/docker/buildx-multi.sh ddns linux/amd64,linux/arm64 $(BUILD_DATE) -docker-goproxy: - docker pull golang:alpine - scripts/docker/buildx-multi.sh goproxy linux/amd64,linux/arm64 $(BUILD_DATE) demo: docker-demo docker-demo: docker-demo-latest docker-demo-all: docker-demo-latest docker-demo-debian diff --git a/NOTICE b/NOTICE index 4754dd06c..1c2ce81f0 100644 --- a/NOTICE +++ b/NOTICE @@ -9,7 +9,7 @@ The following 3rd-party software packages may be used by or distributed with PhotoPrism. Any information relevant to third-party vendors listed below are collected using common, reasonable means. -Date generated: 2026-05-31 +Date generated: 2026-07-09 ================================================================================ @@ -267,8 +267,8 @@ limitations under the License. -------------------------------------------------------------------------------- Package: github.com/abema/go-mp4 -Version: v1.6.0 -License: MIT (https://github.com/abema/go-mp4/blob/v1.6.0/LICENSE) +Version: v1.7.1 +License: MIT (https://github.com/abema/go-mp4/blob/v1.7.1/LICENSE) MIT License @@ -294,6 +294,52 @@ SOFTWARE. -------------------------------------------------------------------------------- +Package: github.com/antchfx/xmlquery +Version: v1.5.1 +License: MIT (https://github.com/antchfx/xmlquery/blob/v1.5.1/LICENSE) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +-------------------------------------------------------------------------------- + +Package: github.com/antchfx/xpath +Version: v1.3.6 +License: MIT (https://github.com/antchfx/xpath/blob/v1.3.6/LICENSE) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +-------------------------------------------------------------------------------- + Package: github.com/beorn7/perks/quantile Version: v1.0.1 License: MIT (https://github.com/beorn7/perks/blob/v1.0.1/LICENSE) @@ -2387,8 +2433,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI -------------------------------------------------------------------------------- Package: github.com/golang/geo -Version: v0.0.0-20260526120156-e21b7802b0ee -License: Apache-2.0 (https://github.com/golang/geo/blob/e21b7802b0ee/LICENSE) +Version: v0.0.0-20260706204034-7a8d33c78269 +License: Apache-2.0 (https://github.com/golang/geo/blob/7a8d33c78269/LICENSE) Apache License @@ -2595,6 +2641,204 @@ License: Apache-2.0 (https://github.com/golang/geo/blob/e21b7802b0ee/LICENSE) -------------------------------------------------------------------------------- +Package: github.com/golang/groupcache/lru +Version: v0.0.0-20210331224755-41bb18bfe9da +License: Apache-2.0 (https://github.com/golang/groupcache/blob/41bb18bfe9da/LICENSE) + +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +-------------------------------------------------------------------------------- + Package: github.com/google/jsonschema-go/jsonschema Version: v0.4.3 License: MIT (https://github.com/google/jsonschema-go/blob/v0.4.3/LICENSE) @@ -3816,8 +4060,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Package: github.com/klauspost/compress -Version: v1.18.6 -License: Apache-2.0 (https://github.com/klauspost/compress/blob/v1.18.6/LICENSE) +Version: v1.19.0 +License: Apache-2.0 (https://github.com/klauspost/compress/blob/v1.19.0/LICENSE) Copyright (c) 2012 The Go Authors. All rights reserved. Copyright (c) 2019 Klaus Post. All rights reserved. @@ -4127,8 +4371,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI -------------------------------------------------------------------------------- Package: github.com/klauspost/compress/internal/snapref -Version: v1.18.6 -License: BSD-3-Clause (https://github.com/klauspost/compress/blob/v1.18.6/internal/snapref/LICENSE) +Version: v1.19.0 +License: BSD-3-Clause (https://github.com/klauspost/compress/blob/v1.19.0/internal/snapref/LICENSE) Copyright (c) 2011 The Snappy-Go Authors. All rights reserved. @@ -4161,8 +4405,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Package: github.com/klauspost/compress/zstd/internal/xxhash -Version: v1.18.6 -License: MIT (https://github.com/klauspost/compress/blob/v1.18.6/zstd/internal/xxhash/LICENSE.txt) +Version: v1.19.0 +License: MIT (https://github.com/klauspost/compress/blob/v1.19.0/zstd/internal/xxhash/LICENSE.txt) Copyright (c) 2016 Caleb Spare @@ -4190,8 +4434,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- Package: github.com/klauspost/cpuid/v2 -Version: v2.3.0 -License: MIT (https://github.com/klauspost/cpuid/blob/v2.3.0/LICENSE) +Version: v2.4.0 +License: MIT (https://github.com/klauspost/cpuid/blob/v2.4.0/LICENSE) The MIT License (MIT) @@ -5894,8 +6138,8 @@ License: Apache-2.0 (https://github.com/prometheus/client_model/blob/v0.6.2/LICE -------------------------------------------------------------------------------- Package: github.com/prometheus/common -Version: v0.68.0 -License: Apache-2.0 (https://github.com/prometheus/common/blob/v0.68.0/LICENSE) +Version: v0.69.0 +License: Apache-2.0 (https://github.com/prometheus/common/blob/v0.69.0/LICENSE) Apache License Version 2.0, January 2004 @@ -6973,8 +7217,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- Package: github.com/yalue/onnxruntime_go -Version: v1.30.1 -License: MIT (https://github.com/yalue/onnxruntime_go/blob/v1.30.1/LICENSE) +Version: v1.31.0 +License: MIT (https://github.com/yalue/onnxruntime_go/blob/v1.31.0/LICENSE) Copyright (c) 2023 Nathan Otterness @@ -8817,8 +9061,8 @@ License: Apache-2.0 (https://github.com/go4org/go4/blob/a5071408f32f/LICENSE) -------------------------------------------------------------------------------- Package: golang.org/x/crypto -Version: v0.52.0 -License: BSD-3-Clause (https://cs.opensource.google/go/x/crypto/+/v0.52.0:LICENSE) +Version: v0.54.0 +License: BSD-3-Clause (https://cs.opensource.google/go/x/crypto/+/v0.54.0:LICENSE) Copyright 2009 The Go Authors. @@ -8851,8 +9095,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Package: golang.org/x/image -Version: v0.41.0 -License: BSD-3-Clause (https://cs.opensource.google/go/x/image/+/v0.41.0:LICENSE) +Version: v0.44.0 +License: BSD-3-Clause (https://cs.opensource.google/go/x/image/+/v0.44.0:LICENSE) Copyright 2009 The Go Authors. @@ -8885,8 +9129,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Package: golang.org/x/mod/semver -Version: v0.36.0 -License: BSD-3-Clause (https://cs.opensource.google/go/x/mod/+/v0.36.0:LICENSE) +Version: v0.38.0 +License: BSD-3-Clause (https://cs.opensource.google/go/x/mod/+/v0.38.0:LICENSE) Copyright 2009 The Go Authors. @@ -8919,8 +9163,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Package: golang.org/x/net -Version: v0.55.0 -License: BSD-3-Clause (https://cs.opensource.google/go/x/net/+/v0.55.0:LICENSE) +Version: v0.57.0 +License: BSD-3-Clause (https://cs.opensource.google/go/x/net/+/v0.57.0:LICENSE) Copyright 2009 The Go Authors. @@ -8987,8 +9231,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Package: golang.org/x/sync/errgroup -Version: v0.20.0 -License: BSD-3-Clause (https://cs.opensource.google/go/x/sync/+/v0.20.0:LICENSE) +Version: v0.22.0 +License: BSD-3-Clause (https://cs.opensource.google/go/x/sync/+/v0.22.0:LICENSE) Copyright 2009 The Go Authors. @@ -9021,8 +9265,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Package: golang.org/x/sys -Version: v0.45.0 -License: BSD-3-Clause (https://cs.opensource.google/go/x/sys/+/v0.45.0:LICENSE) +Version: v0.47.0 +License: BSD-3-Clause (https://cs.opensource.google/go/x/sys/+/v0.47.0:LICENSE) Copyright 2009 The Go Authors. @@ -9055,8 +9299,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Package: golang.org/x/text -Version: v0.37.0 -License: BSD-3-Clause (https://cs.opensource.google/go/x/text/+/v0.37.0:LICENSE) +Version: v0.40.0 +License: BSD-3-Clause (https://cs.opensource.google/go/x/text/+/v0.40.0:LICENSE) Copyright 2009 The Go Authors. @@ -9402,94 +9646,95 @@ License: Apache-2.0 (https://github.com/go-yaml/yaml/blob/v2.4.0/LICENSE) -------------------------------------------------------------------------------- Package License Copyright -------------------------------------------------------------------------------- -@babel/cli MIT The Babel Team (https://babel.dev/team) -@babel/core MIT The Babel Team (https://babel.dev/team) -@babel/plugin-transform-runtime MIT The Babel Team (https://babel.dev/team) -@babel/preset-env MIT The Babel Team (https://babel.dev/team) -@babel/register MIT The Babel Team (https://babel.dev/team) -@babel/runtime MIT The Babel Team (https://babel.dev/team) -@eslint/eslintrc MIT Nicholas C. Zakas -@eslint/js MIT n/a -@mdi/font Apache-2.0 Austin Andrews -@testing-library/jest-dom MIT Ernesto Garcia (http://gnapse.github.io) -@vitejs/plugin-vue MIT Evan You -@vitest/browser MIT n/a -@vitest/coverage-v8 MIT Anthony Fu -@vitest/ui MIT n/a -@vue/compiler-sfc MIT Evan You -@vue/language-server MIT n/a -@vue/test-utils MIT Lachlan Miller lachlan.miller.1990@outlook.com -@vvo/tzdb MIT Vincent Voyer -axios MIT Matt Zabriskie -axios-mock-adapter MIT Colin Timmermans -babel-loader MIT Luis Couto -babel-plugin-istanbul BSD-3-Clause Thai Pangsakulyanont @dtinth -babel-plugin-polyfill-corejs3 MIT n/a -browserslist MIT Andrey Sitnik -core-js MIT Denis Pushkarev zloirock@zloirock.ru http://zloirock.ru -cross-env MIT Kent C. Dodds (https://kentcdodds.com) -css-loader MIT Tobias Koppers @sokra -cssnano MIT Ben Briggs beneb.info@gmail.com http://beneb.info -eslint MIT Nicholas C. Zakas -eslint-config-prettier MIT Simon Lydell -eslint-formatter-pretty MIT Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com -eslint-plugin-html ISC n/a -eslint-plugin-import MIT Ben Mosher -eslint-plugin-node MIT Toru Nagashima -eslint-plugin-vue MIT Toru Nagashima (https://github.com/mysticatea) -eslint-plugin-vuetify MIT Kael Watts-Deuchar -eslint-webpack-plugin MIT Ricardo Gobbo de Souza -eventsource-polyfill MIT amvtek -file-loader MIT Tobias Koppers @sokra -file-saver MIT Eli Grey -globals MIT Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com -hls.js Apache-2.0 n/a -i MIT Pavan Kumar Sunkara (pksunkara.github.com) -jsdom MIT n/a -luxon MIT Isaac Cambron -maplibre-gl BSD-3-Clause n/a -memoize-one MIT Alex Reardon -mini-css-extract-plugin MIT Tobias Koppers @sokra -minimist MIT James Halliday mail@substack.net http://substack.net -node-storage-shim ISC Michael Nahkies -passive-events-support MIT Ignas Damunskis -photoswipe MIT Dmytro Semenov (https://dimsemenov.com) -playwright Apache-2.0 Microsoft Corporation -postcss MIT Andrey Sitnik -postcss-import MIT Maxime Thirouin -postcss-loader MIT Andrey Sitnik -postcss-preset-env MIT-0 n/a -postcss-reporter MIT David Clark david.dave.clark@gmail.com https://davidtheclark.com -prettier MIT James Long -pubsub-js MIT Morgan Roderick morgan@roderick.dk http://roderick.dk -regenerator-runtime MIT Ben Newman -resolve-url-loader MIT bholloway -sanitize-html MIT Apostrophe Technologies, Inc. -sass MIT Natalie Weizenbaum nweiz@google.com https://github.com/nex3 -sass-loader MIT J. Tangelder -sockette MIT Luke Edwards luke.edwards05@gmail.com lukeed.com -style-loader MIT Tobias Koppers @sokra -svg-url-loader MIT Hovhannes Babayan -tar BlueOak-1.0.0 Isaac Z. Schlueter -url-loader MIT Tobias Koppers @sokra -util MIT Joyent http://www.joyent.com -vitest MIT Anthony Fu -vue MIT Evan You -vue-3-sanitize MIT Vannsl, Vanessa Otto -vue-loader MIT Evan You -vue-loader-plugin ISC Ivan liu -vue-luxon MIT Cas Bloem -vue-router MIT Eduardo San Martin Morote posva13@gmail.com -vue-sanitize-directive MIT Leonardo Piccioni de Almeida leopiccionia@gmail.com -vue-style-loader MIT Evan You -vue3-gettext MIT Leo Zurbriggen -vuetify MIT John Leider john@vuetifyjs.com -webpack MIT Tobias Koppers @sokra -webpack-bundle-analyzer MIT Yury Grunin -webpack-cli MIT n/a -webpack-hot-middleware MIT Glen Mailer -webpack-manifest-plugin MIT Dane Thurber -webpack-md5-hash MIT Kirill Ermolov -webpack-merge MIT Juho Vepsalainen -webpack-plugin-vuetify MIT Kael Watts-Deuchar -workbox-webpack-plugin MIT Google's Web DevRel Team and Google's Aurora Team +@babel/cli MIT The Babel Team (https://babel.dev/team) +@babel/core MIT The Babel Team (https://babel.dev/team) +@babel/plugin-transform-runtime MIT The Babel Team (https://babel.dev/team) +@babel/preset-env MIT The Babel Team (https://babel.dev/team) +@babel/register MIT The Babel Team (https://babel.dev/team) +@babel/runtime MIT The Babel Team (https://babel.dev/team) +@eslint/eslintrc MIT Nicholas C. Zakas +@eslint/js MIT n/a +@mdi/font Apache-2.0 Austin Andrews +@photo-sphere-viewer/core MIT Damien 'Mistic' Sorel contact@git.strangeplanet.fr +@photo-sphere-viewer/equirectangular-video-adapter MIT Damien 'Mistic' Sorel contact@git.strangeplanet.fr +@photo-sphere-viewer/video-plugin MIT Damien 'Mistic' Sorel contact@git.strangeplanet.fr +@testing-library/jest-dom MIT Ernesto Garcia (http://gnapse.github.io) +@vitejs/plugin-vue MIT Evan You +@vitest/coverage-v8 MIT Anthony Fu +@vue/compiler-sfc MIT Evan You +@vue/language-server MIT n/a +@vue/test-utils MIT Lachlan Miller lachlan.miller.1990@outlook.com +@vvo/tzdb MIT Vincent Voyer +axios MIT Matt Zabriskie +axios-mock-adapter MIT Colin Timmermans +babel-loader MIT Luis Couto +babel-plugin-polyfill-corejs3 MIT n/a +browserslist MIT Andrey Sitnik +core-js MIT Denis Pushkarev zloirock@zloirock.ru http://zloirock.ru +cross-env MIT Kent C. Dodds (https://kentcdodds.com) +css-loader MIT Tobias Koppers @sokra +cssnano MIT Ben Briggs beneb.info@gmail.com http://beneb.info +eslint MIT Nicholas C. Zakas +eslint-config-prettier MIT Simon Lydell +eslint-formatter-pretty MIT Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com +eslint-plugin-html ISC n/a +eslint-plugin-import MIT Ben Mosher +eslint-plugin-node MIT Toru Nagashima +eslint-plugin-vue MIT Toru Nagashima (https://github.com/mysticatea) +eslint-plugin-vuetify MIT Kael Watts-Deuchar +eslint-webpack-plugin MIT Ricardo Gobbo de Souza +eventsource-polyfill MIT amvtek +file-loader MIT Tobias Koppers @sokra +file-saver MIT Eli Grey +globals MIT Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com +hls.js Apache-2.0 n/a +i MIT Pavan Kumar Sunkara (pksunkara.github.com) +jsdom MIT n/a +luxon MIT Isaac Cambron +maplibre-gl BSD-3-Clause n/a +memoize-one MIT Alex Reardon +mini-css-extract-plugin MIT Tobias Koppers @sokra +minimist MIT James Halliday mail@substack.net http://substack.net +node-storage-shim ISC Michael Nahkies +passive-events-support MIT Ignas Damunskis +photoswipe MIT Dmytro Semenov (https://dimsemenov.com) +playwright Apache-2.0 Microsoft Corporation +postcss MIT Andrey Sitnik +postcss-import MIT Maxime Thirouin +postcss-loader MIT Andrey Sitnik +postcss-preset-env MIT-0 n/a +postcss-reporter MIT David Clark david.dave.clark@gmail.com https://davidtheclark.com +prettier MIT James Long +pubsub-js MIT Morgan Roderick morgan@roderick.dk http://roderick.dk +regenerator-runtime MIT Ben Newman +resolve-url-loader MIT bholloway +sanitize-html MIT Apostrophe Technologies, Inc. +sass MIT Natalie Weizenbaum nweiz@google.com https://github.com/nex3 +sass-loader MIT J. Tangelder +sockette MIT Luke Edwards luke.edwards05@gmail.com lukeed.com +style-loader MIT Tobias Koppers @sokra +svg-url-loader MIT Hovhannes Babayan +tar BlueOak-1.0.0 Isaac Z. Schlueter +url-loader MIT Tobias Koppers @sokra +util MIT Joyent http://www.joyent.com +vite MIT Evan You +vitest MIT Anthony Fu +vue MIT Evan You +vue-3-sanitize MIT Vannsl, Vanessa Otto +vue-loader MIT Evan You +vue-loader-plugin ISC Ivan liu +vue-luxon MIT Cas Bloem +vue-router MIT Eduardo San Martin Morote posva13@gmail.com +vue-sanitize-directive MIT Leonardo Piccioni de Almeida leopiccionia@gmail.com +vue-style-loader MIT Evan You +vue3-gettext MIT Leo Zurbriggen +vuetify MIT John Leider john@vuetifyjs.com +webpack MIT Tobias Koppers @sokra +webpack-bundle-analyzer MIT Yury Grunin +webpack-cli MIT n/a +webpack-hot-middleware MIT Glen Mailer +webpack-manifest-plugin MIT Dane Thurber +webpack-md5-hash MIT Kirill Ermolov +webpack-merge MIT Juho Vepsalainen +webpack-plugin-vuetify MIT Kael Watts-Deuchar +workbox-webpack-plugin MIT Google's Web DevRel Team and Google's Aurora Team diff --git a/README.md b/README.md index 354f11d7d..8f39569d3 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,7 @@ PhotoPrism: Browse Your Life in Pictures [![Bluesky Social](https://dl.photoprism.app/img/badges/badge-bluesky.svg)](https://bsky.app/profile/photoprism.app) [![Mastodon](https://dl.photoprism.app/img/badges/badge-floss-social.svg)](https://floss.social/@photoprism) -PhotoPrism® is an AI-Powered Photos App for the [Decentralized Web](https://en.wikipedia.org/wiki/Decentralized_web). -It makes use of the latest technologies to tag and find pictures automatically without getting in your way. -You can run it at home, on a private server, or in the cloud. +PhotoPrism® is an AI-powered, privacy-first app for browsing, organizing, and sharing photos and videos. It helps tag, search, and rediscover media without getting in your way, whether self-hosted or in the cloud. ![](https://dl.photoprism.app/img/ui/2025/desktop-search.jpg) @@ -22,7 +20,7 @@ To get a first impression, you are welcome to play with our [public demo](https: -* Browse [all your pictures](https://docs.photoprism.app/user-guide/organize/browse/) without worrying about [RAW images](https://www.photoprism.app/kb/file-formats) or [video formats](https://docs.photoprism.app/user-guide/organize/video/) +* Browse [all your pictures](https://docs.photoprism.app/user-guide/organize/browse/) without worrying about [RAW images](https://www.photoprism.app/kb/file-formats/) or [video formats](https://docs.photoprism.app/user-guide/organize/video/) * Whether you're using a phone, tablet, or desktop computer, our [intuitive PWA](https://try.photoprism.app/) provides a native app-like experience and can be [easily installed](https://docs.photoprism.app/user-guide/pwa/) on your home screen * Quickly find specific photos and videos with [powerful search filters](https://docs.photoprism.app/user-guide/search/filters/) that can be combined and are available for [many different properties](https://docs.photoprism.app/user-guide/search/filters/#filter-reference), including [labels](https://try.photoprism.app/library/labels), [location](https://try.photoprism.app/library/places?q=s2:47a85a63f764), [resolution](https://try.photoprism.app/library/browse?view=cards&q=mp:4), [color](https://try.photoprism.app/library/browse?view=cards&q=color:red), [chroma](https://try.photoprism.app/library/browse?view=cards&q=mono%3Atrue), and [quality](https://try.photoprism.app/library/review) * [Automatically labels your pictures](https://try.photoprism.app/library/labels) based on content and location, and recognizes the faces of [your family and friends](https://try.photoprism.app/library/people/new) @@ -32,7 +30,7 @@ To get a first impression, you are welcome to play with our [public demo](https: * [Use compatible apps](https://docs.photoprism.app/user-guide/native-apps/) like [PhotoSync](https://link.photoprism.app/photosync) to back up iOS and Android phones in the background * WebDAV clients such as [Microsoft's Windows Explorer](https://docs.photoprism.app/user-guide/sync/webdav/#__tabbed_1_2) and [Apple's Finder](https://docs.photoprism.app/user-guide/sync/webdav/#connect-to-a-webdav-server) can [connect directly to PhotoPrism](https://docs.photoprism.app/user-guide/sync/webdav/), allowing you to open, edit, and delete files from your computer as if they were local -Being completely [**self-funded and independent**](https://link.photoprism.app/membership), we can promise you that we will [never sell your data](https://www.photoprism.app/privacy) and that we will [always be transparent](https://www.photoprism.app/terms) about our software and services. Your data will never be shared with Google, Amazon, Microsoft or Apple unless you intentionally upload files to one of their services. 🔒 +Being completely [**self-funded and independent**](https://link.photoprism.app/membership), we can promise you that we will [never sell your data](https://www.photoprism.app/privacy/) and that we will [always be transparent](https://www.photoprism.app/terms/) about our software and services. Your data will never be shared with Google, Amazon, Microsoft or Apple unless you intentionally upload files to one of their services. 🔒 ## Getting Started ## @@ -45,18 +43,18 @@ See our [Getting Started FAQ](https://docs.photoprism.app/getting-started/faq/#h ## Support Our Mission 💎 ## -**PhotoPrism is 100% self-funded and independent.** Your [continued support](https://link.photoprism.app/membership) helps us [provide more features to the public](https://www.photoprism.app/oss/faq#what-functionality-is-generally-available), release [regular updates](https://docs.photoprism.app/release-notes/), and remain independent! +**PhotoPrism is 100% self-funded and independent.** Your [continued support](https://link.photoprism.app/membership) helps us [provide more features to the public](https://www.photoprism.app/oss/faq/#what-functionality-is-generally-available), release [regular updates](https://docs.photoprism.app/release-notes/), and remain independent! -Our members [enjoy additional features](https://www.photoprism.app/kb/personal), including access to [interactive world maps](https://try.photoprism.app/library/places), and can join our private chat room to [connect with our team](https://www.photoprism.app/about/team). We currently have the following membership options: +Our members [enjoy additional features](https://www.photoprism.app/kb/personal/), including access to [interactive world maps](https://try.photoprism.app/library/places), and can join our private chat room to [connect with our team](https://www.photoprism.app/about/team/). We currently have the following membership options: -- You can [sign up directly on our website](https://link.photoprism.app/membership) and pay with credit card or SEPA through Stripe, so you don't need to [link an external account](https://www.photoprism.app/kb/activation) and can easily upgrade or downgrade at any time +- You can [sign up directly on our website](https://link.photoprism.app/membership) and pay with credit card or SEPA through Stripe, so you don't need to [link an external account](https://www.photoprism.app/kb/activation/) and can easily upgrade or downgrade at any time - Alternatively, [Patreon](https://link.photoprism.app/patreon) also supports PayPal, additional currencies, and lets you choose between monthly and annual billing for all tiers -If you currently support us through [GitHub Sponsors](https://link.photoprism.app/sponsor), you can also [register on our website](https://my.photoprism.app/register) and use the *Activate GitHub Sponsors Membership* button to link your account. For details on this and how to [link your Patreon account](https://www.patreon.com/pledges), see our [Activation Guide](https://www.photoprism.app/kb/activation). +If you currently support us through [GitHub Sponsors](https://link.photoprism.app/sponsor), you can also [register on our website](https://my.photoprism.app/register) and use the *Activate GitHub Sponsors Membership* button to link your account. For details on this and how to [link your Patreon account](https://www.patreon.com/pledges), see our [Activation Guide](https://www.photoprism.app/kb/activation/). -You are [welcome to contact us](https://www.photoprism.app/contact) for change requests, membership questions, and business partnerships. +You are [welcome to contact us](https://www.photoprism.app/contact/) for change requests, membership questions, and business partnerships. -[View Membership FAQ ›](https://www.photoprism.app/kb/membership) [Sign Up ›](https://link.photoprism.app/membership) +[View Membership FAQ ›](https://www.photoprism.app/membership/faq/) [Sign Up ›](https://link.photoprism.app/membership) ### Why Your Support Matters ### @@ -83,7 +81,7 @@ Our [Project Roadmap](https://link.photoprism.app/roadmap) shows what tasks are Be aware that we have a zero-bug policy and do our best to help users when they need support or have other questions. This comes at a price though, as we can't give exact release dates for new features. Our team receives many more requests than can be implemented, so we want to emphasize that we are in no way obligated to implement the features, enhancements, or other changes you request. We do, however, appreciate your feedback and carefully consider all requests. -**Because sustained funding is key to quickly releasing new features, we encourage you to support our mission by [signing up for a personal membership](https://link.photoprism.app/membership) or [purchasing a commercial license](https://www.photoprism.app/teams#compare).** +**Because sustained funding is key to quickly releasing new features, we encourage you to support our mission by [signing up for a personal membership](https://link.photoprism.app/membership) or [purchasing a commercial license](https://www.photoprism.app/teams/#compare).** [Become a Member ›](https://link.photoprism.app/membership) @@ -91,18 +89,18 @@ Be aware that we have a zero-bug policy and do our best to help users when they We kindly ask you not to report bugs via GitHub Issues **unless you are certain to have found a fully reproducible and previously unreported issue** that must be fixed directly in the app. Thank you for your careful consideration! -- When browsing issues, please note that **our team and all issue subscribers receive an email notification** from GitHub whenever a new comment is added, so these should only be used for sharing important information and not for [discussions, questions](https://github.com/photoprism/photoprism/discussions), or [expressing personal opinions](https://www.photoprism.app/code-of-conduct) -- In order for us to investigate [new bug reports](https://www.photoprism.app/kb/reporting-bugs), they must include **a complete list of steps to reproduce the problem**, the software versions used and information about the environment in which the problem occurred, such as [browser type, browser version, browser plug-ins](https://docs.photoprism.app/getting-started/troubleshooting/browsers/), operating system, [storage type](https://docs.photoprism.app/getting-started/troubleshooting/performance/#storage), [processor type](https://docs.photoprism.app/getting-started/troubleshooting/performance/#server-cpu), and [memory size](https://docs.photoprism.app/getting-started/troubleshooting/performance/#memory) -- [Contact us](https://www.photoprism.app/contact) or [a community member](https://link.photoprism.app/discussions) if you need help, it could be a local configuration problem, or a misunderstanding in how the software works +- When browsing issues, please note that **our team and all issue subscribers receive an email notification** from GitHub whenever a new comment is added, so these should only be used for sharing important information and not for [discussions, questions](https://github.com/photoprism/photoprism/discussions), or [expressing personal opinions](https://www.photoprism.app/code-of-conduct/) +- In order for us to investigate [new bug reports](https://www.photoprism.app/kb/reporting-bugs/), they must include **a complete list of steps to reproduce the problem**, the software versions used and information about the environment in which the problem occurred, such as [browser type, browser version, browser plug-ins](https://docs.photoprism.app/getting-started/troubleshooting/browsers/), operating system, [storage type](https://docs.photoprism.app/getting-started/troubleshooting/performance/#storage), [processor type](https://docs.photoprism.app/getting-started/troubleshooting/performance/#server-cpu), and [memory size](https://docs.photoprism.app/getting-started/troubleshooting/performance/#memory) +- [Contact us](https://www.photoprism.app/contact/) or [a community member](https://link.photoprism.app/discussions) if you need help, it could be a local configuration problem, or a misunderstanding in how the software works - This gives us the opportunity to [improve our documentation](https://docs.photoprism.app/getting-started/troubleshooting/) and provide best-in-class support instead of dealing with unclear/duplicate bug reports or triggering a flood of notifications by replying to comments ## Connect with the Community ## -Follow us on [Mastodon](https://floss.social/@photoprism), [Bluesky](https://bsky.app/profile/photoprism.app), or join the [Community Chat](https://link.photoprism.app/chat) to get regular updates, connect with other users, and discuss your ideas. Our [Code of Conduct](https://www.photoprism.app/code-of-conduct) explains the "dos and don’ts" when interacting with other community members. +Follow us on [Mastodon](https://floss.social/@photoprism), [Bluesky](https://bsky.app/profile/photoprism.app), or join the [Community Chat](https://link.photoprism.app/chat) to get regular updates, connect with other users, and discuss your ideas. Our [Code of Conduct](https://www.photoprism.app/code-of-conduct/) explains the "dos and don’ts" when interacting with other community members. -As a [contributor](CONTRIBUTING.md), you are also welcome to [contact us directly](https://www.photoprism.app/contact) if you have something on your mind that you don't want to discuss publicly. Please note, however, that due to the high volume of emails we receive, our team may be unable to get back to you immediately. We do our best to respond within five business days or less. +As a [contributor](CONTRIBUTING.md), you are also welcome to [contact us directly](https://www.photoprism.app/contact/) if you have something on your mind that you don't want to discuss publicly. Please note, however, that due to the high volume of emails we receive, our team may be unable to get back to you immediately. We do our best to respond within five business days or less. ## Every Contribution Makes a Difference ## @@ -110,4 +108,4 @@ We welcome [contributions](CONTRIBUTING.md) of any kind, including blog posts, t ---- -*PhotoPrism® is a [registered trademark](https://www.photoprism.app/trademark). By using the software and services we provide, you agree to our [Terms of Service](https://www.photoprism.app/terms), [Privacy Policy](https://www.photoprism.app/privacy), and [Code of Conduct](https://www.photoprism.app/code-of-conduct). Docs are [available](https://link.photoprism.app/github-docs) under the [CC BY-NC-SA 4.0 License](https://creativecommons.org/licenses/by-nc-sa/4.0/); [additional terms](https://github.com/photoprism/photoprism/blob/develop/assets/README.md) may apply.* +*PhotoPrism® is a [registered trademark](https://www.photoprism.app/trademark/). By using the software and services we provide, you agree to our [Terms of Service](https://www.photoprism.app/terms/), [Privacy Policy](https://www.photoprism.app/privacy/), and [Code of Conduct](https://www.photoprism.app/code-of-conduct/). Docs are [available](https://link.photoprism.app/github-docs) under the [CC BY-NC-SA 4.0 License](https://creativecommons.org/licenses/by-nc-sa/4.0/); [additional terms](https://github.com/photoprism/photoprism/blob/develop/assets/README.md) may apply.* diff --git a/SPONSORS.md b/SPONSORS.md index 9b0be5d56..3ecb03344 100644 --- a/SPONSORS.md +++ b/SPONSORS.md @@ -1,10 +1,10 @@ # Thank You to All Current and Past Sponsors 💎 # -Your [continued support](https://link.photoprism.app/membership) helps us [provide more features to the public](https://www.photoprism.app/oss/faq#what-functionality-is-generally-available), release [regular updates](https://docs.photoprism.app/release-notes/), and remain independent! 💜 +Your [continued support](https://link.photoprism.app/membership) helps us [provide more features to the public](https://www.photoprism.app/oss/faq/#what-functionality-is-generally-available), release [regular updates](https://docs.photoprism.app/release-notes/), and remain independent! 💜 -You are [welcome to contact us](https://www.photoprism.app/contact) for change requests, membership questions, and business partnerships. +You are [welcome to contact us](https://www.photoprism.app/contact/) for change requests, membership questions, and business partnerships. -[View Membership FAQ ›](https://www.photoprism.app/kb/membership) [Contact Us ›](https://www.photoprism.app/contact) +[View Membership FAQ ›](https://www.photoprism.app/membership/faq/) [Contact Us ›](https://www.photoprism.app/contact/) ## Platinum Sponsors ## diff --git a/assets/locales/README.md b/assets/locales/README.md index f360d1f90..b15651e5a 100644 --- a/assets/locales/README.md +++ b/assets/locales/README.md @@ -15,6 +15,9 @@ It's source code can be obtained on [GitHub](https://github.com/vslavik/poedit). Only asynchronous notifications and certain API responses need translation to provide a consistent user experience. +Asynchronous notifications and user-facing API error responses are additionally rendered by the web +frontend in each user's current UI language (using the message identifier); the `default.po` translation +here serves as a fallback and for non-browser consumers such as the CLI. Technical log messages should be in English to avoid ambiguities and (even slightly) wrong translations. `default.po` files in subdirectories contain localized messages for each @@ -29,7 +32,7 @@ the language. Now you can start translating. When done, create a new directory (using the locale as name) and save your translation there as `default.po`. The POT file `/assets/locales/messages.pot` will be automatically updated when -running `go generate` in `/internal/i18n` or `make generate` in the main project directory. +running `go generate` in `/pkg/i18n` or `make generate` in the main project directory. Note that this will only work when you have gettext installed on your system. We recommend using our latest development image as described in the Developer Guide. diff --git a/assets/locales/af/default.po b/assets/locales/af/default.po index 83bb81025..fda442d49 100644 --- a/assets/locales/af/default.po +++ b/assets/locales/af/default.po @@ -2,412 +2,427 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: DeepL \n" "Language-Team: none\n" "Language: af\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Iets het verkeerd geloop, probeer weer" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Kan dit nie doen nie" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Veranderinge kon nie gestoor word nie" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Kan nie verwyder word nie" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s bestaan reeds" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Nie gevind" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Lêer nie gevind nie" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Lêer te groot" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Ongesteun" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Ongesteunde tipe" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Ongesteunde formaat" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Oorspronklike omslag is leeg" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Seleksie nie gevind nie" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Entiteit nie gevind nie" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Rekening nie gevind nie" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Verbruiker nie gevind nie" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Merker nie gevind nie" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Kamera nie gevind nie" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Lens nie gevind nie" + +#: messages.go:131 msgid "Album not found" msgstr "Album nie gevind nie" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Onderwerp nie gevind nie" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Persoon nie gevind nie" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Gesig nie gevind nie" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Nie beskikbaar in publieke modus nie" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Nie beskikbaar in leesalleen modus nie" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Teken asseblief in op jou rekening" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Toegang geweier" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Betaling vereis" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Oplegging mag aanstoot gee" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Oplegging misluk" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Geen items gekies nie" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Kon nie lêer skep nie. Gaan asseblief toestemmings na" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Kon nie vouer skep nie. Gaan asseblief toestemmings na" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Kon nie konnekteer nie, probeer asseblief weer" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Tik verifikasiekode" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Ongeldige verifikasiekode, probeer asseblief weer" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Ongeldige wagwoord, probeer asseblief weer" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Eienskap gedeaktiveer" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Geen merker geselekteer" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Geen albums geselekteer nie" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Geen lêers beskikbaar vir aflaai nie" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Kon nie zip-lêer skep nie" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Ongeldige magtiging" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Ongeldige skakel" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Ongeldige naam" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Besig, probeer asseblief later weer" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Die opwek tydperk is %s, maar moet 1 uur of minder wees" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Jou rekening kon nie gekoppel word nie" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Te veel versoeke" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Onvoldoende berging" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Kwota oorskry" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Registrasie gedeaktiveer" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Geverifieerde e-pos vereis" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Veranderinge suksesvol gestoor" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Album geskep" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Album gestoor" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Album %s uitgevee" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Albuminhoud gekloon" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Lêer verwyder uit stapel" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Lêer uitgevee" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Seleksie bygevoeg na %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Een inskrywing bygevoeg na %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d inskrywings by %s gevoeg" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Een inskrywing verwyder uit %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d inskrywings verwyder uit %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Rekening geskep" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Rekening gestoor" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Rekening uitgevee" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Stellings gestoor" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Wagwoord verander" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Invoer voltooi in %d s" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Invoer gekanselleer" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "inhoudsopgawe voltooi in %d s" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Indekseer van oorspronklikes …" -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Indekseer lêers in %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indeksering gekanselleer" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "%d lêers en %d foto's verwyder" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Skuif lêers van %s af" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Kopieer lêers van %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Merkers uitgevee" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Merkers gestoor" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Onderwerp gestoor" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Onderwerp uitgevee" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Persoon gestoor" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Persoon uitgevee" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Lêer opgelaai" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d lêers opgelaai in %d s" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Verwerk oplegging..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Oplegging geprosesseer" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Seleksie goedgekeur" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Seleksie geargiveer" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Seleksie herstel" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Seleksie gemerk as privaat" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Albums uitgevee" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip geskep in %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Permanent uitgevee" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s geherstel" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Suksesvol geverifieer" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Suksesvol geaktiveer" diff --git a/assets/locales/ar/default.po b/assets/locales/ar/default.po index 2af0ed4eb..a940e0c4b 100644 --- a/assets/locales/ar/default.po +++ b/assets/locales/ar/default.po @@ -2,9 +2,10 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" "Language: ar\n" "MIME-Version: 1.0\n" @@ -12,402 +13,418 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "حدث خطأ ما، حاول مرة أخرى" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "غير قادر على فعل ذلك" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "لا يمكن حفظ التغييرات" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "لا يمكن حذفه" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s موجود بالفعل" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "لم يتم العثور" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "لم يتم العثور على الملف" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "الملف كبير جدًا" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "غير مدعوم" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "نوع غير معتمد" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "صيغة غير مدعومة" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "مجلد النسخ الأصلية فارغ" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "الاختيار غير موجود" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "الكيان غير موجود" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "الحساب غير موجود" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "المستخدم غير موجود" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "التصنيف غير موجود" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "لم يتم العثور على الكاميرا" + +#: messages.go:130 +msgid "Lens not found" +msgstr "لم يتم العثور على العدسة" + +#: messages.go:131 msgid "Album not found" msgstr "الألبوم غير موجود" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "الموضوع غير موجود" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "لم يتم العثور على الشخص" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "الوجه غير موجود" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "غير متاح في الوضع العام" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "غير متوفر في وضع القراءة فقط" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "يرجى تسجيل الدخول إلى حسابك" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "طلب الاذن مرفوض" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "الدفع مطلوب" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "المحتوى المرفوع قد يكون مسيئا" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "فشل التحميل" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "لم يتم اختيار المحتوى" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "فشل إنشاء الملف ، يرجى التحقق من الصلاحيات" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "لم يتم إنشاء المجلد ، يرجى التحقق من الصلاحيات" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "تعذر الاتصال ، يرجى المحاولة مرة أخرى" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "أدخل رمز التحقق" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "رمز التحقق غير صالح، يرجى المحاولة مرة أخرى" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "كلمة السر غير مطابقة، يرجى المحاولة مرة أخرى" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "الخاصية غير مفعلة" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "لم يتم تحديد المعرفات" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "لم يتم تحديد ألبومات" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "لا توجد ملفات متاحة للتنزيل" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "فشل في إنشاء ملف مضغوط" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "بيانات الاعتماد غير صالحة" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "رابط غير صالح" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "اسم غير صحيح" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "مشغول، يرجى المحاولة مرة أخرى في وقت لاحق" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "فترة التنبيه هي %s ، لكن يجب أن تكون ساعة واحدة أو أقل" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "لا يمكن ربط حسابك" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "طلبات كثيرة جدا" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "مساحة تخزين غير كافية" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "تم تجاوز المساحة المخصصة" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "تم تعطيل التسجيل" + +#: messages.go:164 +msgid "Verified email required" +msgstr "البريد الإلكتروني الموثق مطلوب" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "تم حفظ التغييرات بنجاح" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "تم إنشاء الألبوم" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "تم حفظ الألبوم" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "تم حذف الألبوم %s" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "تم نسخ محتويات الألبوم" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "تمت إزالة الملف من المكدس" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "تم حذف الملف" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "تمت إضافة التحديد إلى %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "تمت إضافة إدخال واحد إلى %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "تمت إضافة %d مدخلات إلى %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "تمت إزالة إدخال واحد من %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "تمت إزالة %d مدخلات من %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "تم إنشاء الحساب" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "تم حفظ الحساب" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "تم حذف الحساب" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "تم حفظ الإعدادات" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "تم تغيير كلمة السر" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "اكتمل الاستيراد في %d ثانية" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "تم إلغاء الاستيراد" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "اكتملت الفهرسة في %d ثانية" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "تتم فهرسة الصور الأصلية ..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "فهرسة الملفات في %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "تم إلغاء الفهرسة" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "تمت إزالة %d ملفات و %d صورة" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "نقل الملفات من %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "نسخ ملفات من %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "تم حذف التصنيفات" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "تم حفظ التصنيف" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "تم حفظ الموضوع" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "تم حذف الموضوع" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "حفظ الشخص" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "تم حذف الشخص" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "تم تحميل الملف" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "تم تحميل %d ملف في %d ثانية" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "جارٍ معالجة التحميل ..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "تمت معالجة التحميل" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "تمت الموافقة على الاختيار" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "تمت أرشفة الاختيار" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "تم استعادة المحتوى المحدد" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "تم تحديد الاختيار على أنه خاص" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "تم حذف الألبومات" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "تم إنشاء الملف المضغوط خلال %d ثوانٍ" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "تم الحذف بشكل نهائي" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "تمت استعادة %s" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "تم التحقق بنجاح" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "تم التفعيل بنجاح" diff --git a/assets/locales/be/default.po b/assets/locales/be/default.po index 4d4819a81..1bad6b397 100644 --- a/assets/locales/be/default.po +++ b/assets/locales/be/default.po @@ -2,10 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: DeepL \n" "Language-Team: none\n" "Language: be\n" "MIME-Version: 1.0\n" @@ -13,402 +12,418 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Нешта пайшло не так, паўтарыце спробу" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Немагчыма зрабіць гэта" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Не ўдалося захаваць змены" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Немагчыма выдаліць" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s ужо існуе" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Не знойдзена" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Файл не знойдзены" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Файл занадта вялікі" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Не падтрымліваецца" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Тып не падтрымліваецца" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Фармат не падтрымліваецца" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Тэчка арыгіналаў пустая" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Выбар не знойдзены" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Аб'ект не знойдзены" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Уліковы запіс не знойдзены" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Карыстальнік не знойдзены" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Тэг не знойдзены" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Камера не знойдзена" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Аб'ектыў не знойдзены" + +#: messages.go:131 msgid "Album not found" msgstr "Альбом не знойдзены" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Тэма не знойдзена" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Чалавек не знойдзены" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Твар не знойдзены" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Недаступна ў публічным рэжыме" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Недаступна ў рэжыме толькі для чытання" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Калі ласка, увайдзіце ў свой уліковы запіс" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "У доступе адмоўлена" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Патрабуецца аплата" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Запампоўка можа быць абразлівай" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Памылка загрузкі" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Элементы не выбраны" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Не ўдалося стварыць файл, праверце дазволы" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Не атрымалася стварыць папку, праверце дазволы" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Немагчыма падключыцца, паспрабуйце яшчэ раз" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Увядзіце праверачны код" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Няправільны код спраўджання, паўтарыце спробу" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Няправільны пароль, паспрабуйце яшчэ раз" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Функцыя адключана" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Меткі не выбраны" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Альбомы не выбраны" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Няма даступных файлаў для спампоўкі" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Не ўдалося стварыць zip-файл" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Няправільныя ўліковыя даныя" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Няправільная спасылка" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Няправільнае імя" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Заняты, паўтарыце спробу пазней" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Інтэрвал абуджэння складае %s, але павінен быць не больш за 1 гадзіну" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Ваш уліковы запіс не можа быць падключаны" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Занадта шмат запытаў" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Недастаткова месца для захоўвання" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Квота перавышана" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Рэгістрацыя адключана" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Патрабуецца правераны адрас электроннай пошты" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Змены паспяхова захаваны" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Альбом створаны" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Альбом захаваны" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Альбом %s выдалены" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Змест альбома кланаваны" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Файл выдалены са стэка" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Файл выдалены" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Выбар дададзены ў %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Адзін запіс дададзены ў %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d запісы дададзены ў %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Адзін запіс выдалены з %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "Запісы %d выдалены з %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Уліковы запіс створаны" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Уліковы запіс захаваны" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Уліковы запіс выдалены" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Налады захаваны" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Пароль зменены" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Імпарт завершаны праз %d с" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Імпарт адменены" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Індэксацыя завершана ў %d с" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Індэксаванне арыгіналаў..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Індэксацыя файлаў у %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Індэксацыя адменена" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Выдалена %d файлаў і %d фота" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Перамяшчэнне файлаў з %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Капіраванне файлаў з %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Меткі выдалены" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Цэтлік захаваны" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Тэма захавана" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Тэма выдалена" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Чалавек выратаваны" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Асоба выдалена" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Файл запампаваны" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d файлы, загружаныя ў %d с" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Апрацоўка запампоўкі..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Загрузка апрацавана" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Выбар ухвалены" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Выбранае заархівавана" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Выбар адноўлены" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Выбар пазначаны як прыватны" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Альбомы выдалены" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip створаны ў %d с" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Выдалены назаўсёды" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s быў адноўлены" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Паспяхова праверана" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Паспяхова актывавана" diff --git a/assets/locales/bg/default.po b/assets/locales/bg/default.po index 366a5ceb1..1feaaf157 100644 --- a/assets/locales/bg/default.po +++ b/assets/locales/bg/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" "Last-Translator: DeepL \n" "Language-Team: none\n" "Language: bg\n" @@ -11,402 +11,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Нещо се е объркало, опитайте отново" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Не можете да го направите" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Промените не могат да бъдат запазени" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Не може да бъде изтрит" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s вече съществува" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Не е намерен" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Файлът не е намерен" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Твърде голям файл" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Не се поддържа" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Неподдържан тип" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Неподдържан формат" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Папката с оригинали е празна" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Изборът не е намерен" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Субектът не е намерен" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Акаунтът не е намерен" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Потребителят не е намерен" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Етикетът не е намерен" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Камерата не е открита" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Обективът не е открит" + +#: messages.go:131 msgid "Album not found" msgstr "Албумът не е намерен" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Темата не е намерена" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Лицето не е намерено" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Лицето не е намерено" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Не е наличен в публичен режим" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Не е наличен в режим само за четене" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Моля, влезте в профила си" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Достъп отказан" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Изисква се плащане" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Качването може да е обидно" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Файловете не успяха да се качат" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Няма избрани елементи" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Неуспешно създаване на файл, моля, проверете разрешенията" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Неуспешно създаване на папка, моля, проверете разрешенията" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Не може да се свърже, опитайте отново" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Въведете код за верификация" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Невалиден код за потвърждение, моля опитайте отново" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Невалидна парола, моля, опитайте отново" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Функцията е деактивирана" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Няма избрани етикети" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Няма избрани албуми" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Няма налични файлове за изтегляне" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Неуспешно създаване на zip файл" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Невалидни креденции" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Невалидна връзка" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Невалидно име" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Заето, моля, опитайте отново по-късно" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Интервалът на събуждане е %s, но трябва да е 1 час или по-малко" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Вашият акаунт не може да бъде свързан" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Твърде много заявки" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Недостатъчно място за съхранение" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Превишаване на квотата" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Регистрацията е деактивирана" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Необходим е потвърден имейл адрес" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Промените са успешно записани" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Създаден албум" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Запазен албум" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Албум %s изтрит" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Съдържанието на албума беше клонирано" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Премахване на файла от стека" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Изтрит файл" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Добавяне на селекция към %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Добавяне на един запис към %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d добавени записи към %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Отстранен е един запис от %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d премахнати записи от %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Създаден акаунт" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Акаунтът запазен" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Изтрит акаунт" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Запазени настройки" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Паролата е променена" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Импортът е завършен за %d s" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Вносът е отменен" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Индексирането е завършено за %d сек" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Индексиране на оригинали..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Индексиране на файлове в %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Отменено индексиране" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Премахнати са %d файлове и %d снимки" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Преместване на файлове от %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Копиране на файлове от %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Изтрити етикети" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Запазен етикет" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Тема: запазени" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Изтрит предмет" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Запазено лице" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Изтрито лице" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Качен файл" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d файлове, качени за %d сек" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Обработка на качването..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Качването е обработено" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Одобрена селекция" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Архивирана селекция" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Възстановена селекция" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Селекция, отбелязана като частна" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Изтрити албуми" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip създаден за %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Постоянно изтрити" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s е възстановена" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Успешно потвърдено" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Успешно активиран" diff --git a/assets/locales/ca/default.po b/assets/locales/ca/default.po index 34a15fa66..16bec0e66 100644 --- a/assets/locales/ca/default.po +++ b/assets/locales/ca/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" "Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" @@ -12,402 +12,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "S'ha produït un error, torna-ho a provar" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Incapaç de fer-ho" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "No s'han pogut desar els canvis" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "No s'ha pogut suprimir" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s El nom ja existeix" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "No trobat" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "No s'ha trobat el fitxer" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Fitxer massa gran" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Sense suport" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Tipus no compatible" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Format no compatible" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "La carpeta d'originals està buida" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "No s'ha trobat la selecció" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "No s'ha trobat l'entitat" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Compte no trobat" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Usuari no trobat" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "No s'ha trobat l'etiqueta" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "No s'ha trobat la càmera" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Lent no trobada" + +#: messages.go:131 msgid "Album not found" msgstr "No s'ha trobat l'àlbum" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "No s'ha trobat el tema" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Persona no trobada" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "No s'ha trobat la cara" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "No disponible en mode públic" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "No disponible en mode només de lectura" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Si us plau, inicieu sessió al vostre compte" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Permís denegat" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Pagament requerit" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "La càrrega pot ser ofensiva" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "La càrrega ha fallat" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "No s'ha seleccionat cap element" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "No s'ha pogut crear el fitxer, comproveu els permisos" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "No s'ha pogut crear la carpeta, comproveu els permisos" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "No s'ha pogut connectar, torna-ho a provar" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Introduïu el codi de verificació" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Codi de verificació no vàlid, torneu-ho a provar" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "La contrasenya no és vàlida, torneu-ho a provar" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Funció desactivada" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "No s'ha seleccionat cap etiqueta" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "No s'ha seleccionat cap àlbum" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "No hi ha fitxers disponibles per a la baixada" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "No s'ha pogut crear el fitxer zip" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Credencials incorrectes" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Enllaç no vàlid" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Nom no vàlid" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Ocupat, torna-ho a provar més tard" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "L'interval d'activació és %s, però ha de ser d'1 h o menys" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "No s'ha pogut connectar el vostre compte" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Massa peticions" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Emmagatzematge insuficient" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "S'ha superat la quota" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Registre desactivat" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Cal un correu electrònic verificat" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Els canvis s'han desat correctament" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Àlbum creat" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Àlbum desat" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "S'ha suprimit l'àlbum %s" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Contingut de l'àlbum clonat" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "S'ha eliminat el fitxer de la pila" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "S'ha suprimit el fitxer" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "S'ha afegit una selecció a %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "S'ha afegit una entrada a %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d entrades afegides a %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "S'ha eliminat una entrada de %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "S'han eliminat %d entrades de %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Compte creat" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Compte desat" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Compte suprimit" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Configuració desada" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "S’ha canviat la contrasenya" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Importació completada en %d s" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Importació cancel·lada" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indexació completada en %d s" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "S'estan indexant els originals..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Indexant fitxers a %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "S'ha cancel·lat la indexació" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "S'han eliminat %d fitxers i %d fotos" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "S'estan movent fitxers de %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "S'estan copiant fitxers de %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "S'han suprimit les etiquetes" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "S'ha desat l'etiqueta" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Assumpte desat" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "S'ha suprimit el tema" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Persona salvada" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "S'ha suprimit la persona" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Fitxer penjat" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d fitxers penjats en %d s" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "S'està processant la càrrega..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "S'ha processat la càrrega" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Selecció aprovada" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Selecció arxivada" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "S'ha restaurat la selecció" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "La selecció s'ha marcat com a privada" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Àlbums suprimits" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip creat en %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Esborrat permanentment" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s s'ha restaurat" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Verificat correctament" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "S'ha activat correctament" diff --git a/assets/locales/cs/default.po b/assets/locales/cs/default.po index 0fc1800ba..474f4718d 100644 --- a/assets/locales/cs/default.po +++ b/assets/locales/cs/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" "Last-Translator: DeepL \n" "Language-Team: Czech \n" @@ -12,402 +12,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Něco se pokazilo, zkuste to znovu" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Nelze to udělat" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Změny nemohly být uloženy" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Nemohlo být vymazáno" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s již existuje" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Nenalezeno" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Soubor nenalezen" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Příliš velký soubor" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Nepodporováno" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Nepodporovaný typ" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Nepodporovaný formát" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Složka Originály je prázdná" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Výběr nenalezen" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Subjekt nebyl nalezen" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Účet nenalezen" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Uživatel nenalezen" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Štítek nenalezen" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Fotoaparát nebyl nalezen" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Objektiv nebyl nalezen" + +#: messages.go:131 msgid "Album not found" msgstr "Album nenalezeno" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Předmět nebyl nalezen" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Osoba nebyla nalezena" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Obličej nebyl nalezen" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Není k dispozici ve veřejném módu" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Není k dispozici v režimu pouze pro čtení" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Přihlaste se ke svému účtu" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Přístup zamítnut" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Požadovaná platba" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Nahrané soubory by mohly být urážlivé" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Nahrávání selhalo" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Nebyly vybrány žádné položky" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Vytváření souboru selhalo, zkontrolujte prosím oprávnění" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Vytváření složky selhalo, zkontrolujte prosím oprávnění" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Nemohlo být připojeno, zkuste to prosím znovu" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Vložte ověřovací kód" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Neplatný ověřovací kód, zkuste to prosím znovu" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Neplatné heslo, zkuste to prosím znovu" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Funkce deaktivovaná" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Nebyly vybrány žádné štítky" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Nebyla vybrána žádná alba" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Žádné soubory ke stažení k dispozici" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Nebylo možné vytvořit soubor ZIP" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Neplatné údaje" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Neplatný odkaz" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Neplatný jméno" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Zaneprázdněn, zkuste to prosím později" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Interval buzení je %s, ale musí být 1h nebo kratší" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Váš účet se nepodařilo připojit" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Příliš mnoho požadavků" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Nedostatečné skladování" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Překročení kvóty" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Registrace je deaktivována" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Je nutné zadat ověřenou e-mailovou adresu" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Změny byly úspěšně uloženy" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Album vytvořeno" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Album uloženo" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Album %s vymazáno" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Obsah alba naklonován" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Soubor odstraněn ze stohu" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Soubor vymazán" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Výběr přidán do %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Jeden záznam přidán do %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d záznamů přidáno do %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Jeden záznam odstraněn z %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d záznamů odstraněno z %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Účet vytvořen" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Účet uložen" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Účet vymazán" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Nastavení uloženo" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Heslo změněno" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Import dokončen za %d s" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Import zrušen" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indexování dokončeno za %d s" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Indexování originálů..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Indexování souborů v %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indexování zrušeno" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Odstraněno %d souborů a %d fotografií" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Přesouvání souborů z %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Kopírování souborů z %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Štítky vymazány" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Štítek uložen" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Předmět uložen" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Předmět smazán" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Uložená osoba" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Vymazaná osoba" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Soubor odeslán" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d souborů nahráno za %d s" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Zpracování nahrávání..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Nahrávání bylo zpracováno" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Výběr potvrzen" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Výběr archivován" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Výběr obnoven" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Výběr označen jako Soukromý" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Alba vymazána" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "ZIP vytvořen za %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Trvale smazáno" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s bylo obnoveno" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Úspěšně ověřeno" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Úspěšně aktivováno" diff --git a/assets/locales/da/default.po b/assets/locales/da/default.po index 6b48e0861..d89dda9b9 100644 --- a/assets/locales/da/default.po +++ b/assets/locales/da/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" "Last-Translator: DeepL \n" "Language-Team: Danish \n" @@ -12,402 +12,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Der gik noget galt, prøv igen" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Det kan ikke lade sig gøre" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Ændringer kunne ikke gemmes" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Kunne ikke slettes" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s findes allerede" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Ikke fundet" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Fil ikke fundet" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Filen er for stor" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Ikke understøttet" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Ikke-understøttet type" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Ikke understøttet format" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Mappen Originaler er tom" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Valg ikke fundet" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Enhed ikke fundet" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Konto ikke fundet" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Bruger ikke fundet" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Etiket ikke fundet" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Kameraet blev ikke fundet" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Objektiv ikke fundet" + +#: messages.go:131 msgid "Album not found" msgstr "Album ikke fundet" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Emne ikke fundet" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Person ikke fundet" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Ansigt ikke fundet" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Ikke tilgængelig i offentlig tilstand" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Ikke tilgængelig i skrivebeskyttet tilstand" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Log ind på din konto" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Tilladelse nægtet" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Betaling påkrævet" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Upload kan være stødende" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Upload mislykkedes" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Ingen emner valgt" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Oprettelse af fil mislykkedes, tjek venligst tilladelser" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Oprettelse af mappe mislykkedes, tjek venligst tilladelser" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Kunne ikke oprette forbindelse, prøv venligst igen" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Indtast verifikations kode" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Ugyldig bekræftelseskode. Prøv venligst igen" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Ugyldig adgangskode, prøv venligst igen" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Funktion deaktiveret" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Ingen etiketter valgt" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Ingen album valgt" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Ingen filer til rådighed til download" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Det lykkedes ikke at oprette zip-fil" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Ugyldige legitimationsoplysninger" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Ugyldigt link" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Ugyldigt navn" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Optaget, prøv venligst igen senere" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Vækningsintervallet er %s, men skal være 1 time eller mindre" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Der kunne ikke oprettes forbindelse til din konto" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "For mange anmodninger" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Utilstrækkelig opbevaring" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Kvote overskredet" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Registrering er deaktiveret" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Der kræves en bekræftet e-mailadresse" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Ændringer gemt med succes" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Album oprettet" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Album gemt" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Album %s slettet" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Albumindhold klonet" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Fil fjernet fra stakken" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Fil slettet" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Valg tilføjet til %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "En post tilføjet til %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d poster tilføjet til %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "En post fjernet fra %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d poster fjernet fra %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Konto oprettet" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Gemte konto" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Konto slettet" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Indstillinger gemt" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Adgangskode ændret" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Import afsluttet efter %d s" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Import annulleret" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indeksering afsluttet efter %d s" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Indeksering af originaler..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Indeksering af filer i %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indeksering annulleret" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Fjernede %d filer og %d fotos" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Flytter filer fra %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Kopierer filer fra %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Etiketter slettet" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Etikette gemt" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Emne gemt" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Emne slettet" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Person gemt" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Person slettet" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Fil uploadet" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d filer uploadet på %d s" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Behandling af upload..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Upload er blevet behandlet" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Udvælgelse godkendt" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Udvælgelse arkiveret" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Udvalgte gendannet" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Udvalgte er markeret som privat" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Albums slettet" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip filen blev lavet på %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Permanent slettet" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s er blevet genoprettet" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Verifikation lykkedes" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Aktivering lykkedes" diff --git a/assets/locales/de/default.po b/assets/locales/de/default.po index 6a06c236d..6d1001d46 100644 --- a/assets/locales/de/default.po +++ b/assets/locales/de/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" "Last-Translator: DeepL \n" "Language-Team: German \n" @@ -12,403 +12,419 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" "X-Poedit-Basepath: .\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Etwas ist schief gelaufen, versuche es noch einmal" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Dies ist nicht möglich" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Fehler beim Speichern der Daten" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Konnte nicht gelöscht werden" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s existiert bereits" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Nicht gefunden" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Datei konnte nicht gefunden werden" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Datei zu groß" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Wird nicht unterstützt" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Typ wird nicht unterstützt" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Nicht unterstütztes Format" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Originals-Verzeichnis ist leer" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Auswahl nicht gefunden" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Keine Daten gefunden" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Unbekannter Account" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Nutzer nicht gefunden" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Kategorie nicht gefunden" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Kamera nicht gefunden" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Objektiv nicht gefunden" + +#: messages.go:131 msgid "Album not found" msgstr "Album nicht gefunden" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Unbekanntes Motiv" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Unbekannte Person" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Unbekanntes Gesicht" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Im öffentlichen Modus nicht verfügbar" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Im Nur-Lese-Modus nicht verfügbar" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Bitte melde dich an" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Erlaubnis verweigert" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Zahlung erforderlich" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Inhalt könnte anstößig sein und wurde abgelehnt" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Upload fehlgeschlagen" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Nichts ausgewählt" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Datei konnte nicht erstellt werden" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Ordner konnte nicht erstellt werden" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Verbindung fehlgeschlagen" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Verifizierungscode eingeben" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Ungültiger Verifizierungscode, bitte erneut versuchen" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Ungültiges Passwort" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Funktion deaktiviert" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Keine Kategorien ausgewählt" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Keine Alben ausgewählt" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Keine Dateien zum Download verfügbar" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Zip-Datei konnte nicht erstellt werden" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Ungültige Zugangsdaten" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Ungültiger Link" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Ungültiger Name" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Beschäftigt, bitte später erneut versuchen" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Worker-Intervall ist %s, muss aber 1h oder weniger betragen" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Das Konto konnte nicht verbunden werden" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Zu viele Anfragen" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Zu wenig Speicherplatz" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Maximale Anzahl erreicht" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Registrierung deaktiviert" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Eine verifizierte E-Mail-Adresse ist erforderlich" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Änderungen erfolgreich gespeichert" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Album erstellt" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Album gespeichert" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Album %s gelöscht" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Album-Einträge kopiert" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Datei aus Stapel entfernt" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Datei gelöscht" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Auswahl zu %s hinzugefügt" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Ein Eintrag zu %s hinzugefügt" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d Einträge zu %s hinzugefügt" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Ein Eintrag aus %s entfernt" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d Einträge aus %s entfernt" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Konto hinzugefügt" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Konto gespeichert" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Konto gelöscht" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Einstellungen gespeichert" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Passwort geändert" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Import in %d s abgeschlossen" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Import abgebrochen" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indexierung in %d s abgeschlossen" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Indexiere Dateien…" -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Indexiere Dateien in %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indexierung abgebrochen" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "%d Dateien und %d Bilder wurden entfernt" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Verschiebe Dateien von %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Kopiere Dateien von %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Kategorien gelöscht" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Kategorie gespeichert" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Motiv gespeichert" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Motiv gelöscht" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Person gespeichert" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Person gelöscht" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Datei hochgeladen" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d Dateien hochgeladen in %d s" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Verarbeitung des Uploads..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Der Upload wurde verarbeitet" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Auswahl übernommen" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Auswahl archiviert" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Auswahl wiederhergestellt" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Auswahl als privat markiert" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Alben gelöscht" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip-Datei erstellt in %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Endgültig gelöscht" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s wurde wiederhergestellt" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Erfolgreich verifiziert" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Erfolgreich aktiviert" diff --git a/assets/locales/el/default.po b/assets/locales/el/default.po index 97356b0f2..a4abcbc15 100644 --- a/assets/locales/el/default.po +++ b/assets/locales/el/default.po @@ -2,411 +2,427 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-11-19 10:23+0000\n" -"Last-Translator: dtsolakis \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: DeepL \n" "Language-Team: none\n" "Language: el\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Κάτι πήγε στραβά, δοκιμάστε ξανά" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Αυτό δεν είναι εφικτό" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Οι αλλαγές δεν ήταν δυνατό να αποθηκευτούν" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Δεν ήταν εφικτή η διαγραφή" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s υπάρχει ήδη" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Δεν βρέθηκε" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Το αρχείο δεν βρέθηκε" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Πολύ μεγάλο αρχείο" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Δεν υποστηρίζεται" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Μη υποστηριζόμενος τύπος" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Μη υποστηριζόμενος μορφότυπος" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Ο φάκελος πρωτότυπων είναι άδειος" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Η επιλογή δεν βρέθηκε" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Η οντότητα δεν βρέθηκε" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Ο λογαριασμός δεν βρέθηκε" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Ο χρήστης δεν βρέθηκε" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Η ετικέτα δεν βρέθηκε" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Δεν εντοπίστηκε η κάμερα" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Δεν βρέθηκε ο φακός" + +#: messages.go:131 msgid "Album not found" msgstr "Το άλμπουμ δεν βρέθηκε" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Το θέμα δεν βρέθηκε" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Το άτομο δεν βρέθηκε" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Το πρόσωπο δεν βρέθηκε" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Μη διαθέσιμο κατά τη δημόσια λειτουργία" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Μη διαθέσιμο στην κατάσταση \"μόνο ανάγνωση\"" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Συνδεθείτε στο λογαριασμό σας" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Δέν δόθηκε άδεια" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Απαιτείται πληρωμή" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Το ανέβασμα μπορεί να είναι προσβλητικό" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Αποτυχία ανεβάσματος" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Δεν έχουν επιλεγεί στοιχεία" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Απέτυχε η δημιουργία αρχείου, ελέγξτε τα δικαιώματα" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Απέτυχε η δημιουργία φακέλου, ελέγξτε τα δικαιώματα" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Δεν ήταν δυνατή η σύνδεση, δοκιμάστε ξανά" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Εισάγετε τον κωδικό επαλήθευσης" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Μη έγκυρος κωδικός επαλήθευσης, δοκιμάστε ξανά" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Μη έγκυρος κωδικός πρόσβασης, δοκιμάστε ξανά" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Απενεργοποιημένη λειτουργία" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Δεν έχουν επιλεγεί ετικέτες" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Δεν έχουν επιλεγεί άλμπουμ" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Δεν υπάρχουν διαθέσιμα αρχεία για λήψη" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Απέτυχε η δημιουργία αρχείου zip" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Μη έγκυρα διαπιστευτήρια" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Μη έγκυρος σύνδεσμος" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Μη έγκυρο όνομα" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Το σύστημα είναι απασχολημένο, προσπαθήστε ξανά αργότερα" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Το διάστημα αφύπνισης είναι %s, αλλά πρέπει να είναι 1 ώρα ή λιγότερο" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Ο λογαριασμός σας δεν ήταν δυνατό να συνδεθεί" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Πάρα πολλά αιτήματα" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Ανεπαρκής χώρος" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Υπέρβαση ορίου" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Η εγγραφή έχει απενεργοποιηθεί" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Απαιτείται επαληθευμένη διεύθυνση ηλεκτρονικού ταχυδρομείου" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Οι αλλαγές αποθηκεύτηκαν επιτυχώς" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Το άλμπουμ δημιουργήθηκε" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Το άλμπουμ αποθηκεύθηκε" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Το άλμπουμ %s διαγράφηκε" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Τα περιεχόμενα του άλμπουμ αντιγράφηκαν" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Αφαίρεση αρχείου από τη στοίβα" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Το αρχείο διαγράφηκε" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Η επιλογή προστέθηκε στο %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Μία εγγραφή προστέθηκε στο %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d καταχωρήσεις προστέθηκαν στο %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Μία καταχώρηση αφαιρέθηκε από %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d καταχωρήσεις αφαιρέθηκαν από %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Ο λογαριασμός δημιουργήθηκε" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Ο λογαριασμός αποθηκεύτηκε" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Ο λογαριασμός διαγράφηκε" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Οι ρυθμίσεις αποθηκεύτηκαν" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Ο κωδικός πρόσβασης άλλαξε" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Η εισαγωγή ολοκληρώθηκε σε %d s" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Η εισαγωγή ακυρώθηκε" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Η ευρετηρίαση ολοκληρώθηκε σε %d s" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Δημιουργία ευρετηρίου για τα πρωτότυπα..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Δημιουργία ευρετηρίου αρχείων σε %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Η δημιουργία ευρετηρίου ακυρώθηκε" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Αφαίρεση %d αρχείων και %d φωτογραφιών" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Μετακίνηση αρχείων από %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Αντιγραφή αρχείων από %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Οι ετικέτες διαγράφηκαν" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Η ετικέτα αποθηκεύτηκε" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Το θέμα αποθηκεύθηκε" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Το θέμα διαγράφηκε" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Το άτομο αποθηκεύτηκε" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Το άτομο διαγράφηκε" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Το αρχείο διαγράφηκε" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d αρχεία ανεβάστηκαν σε %d s" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Επεξεργασία ανεβάσματος..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Το ανέβασμα έχει ολοκληρωθεί" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Η επιλογή εγκρίθηκε" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Η επιλογή αρχειοθετήθηκε" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Η επιλογή αποκαταστάθηκε" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Η επιλογή μαρκαρίστηκε ως ιδιωτική" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Διαγραμμένα άλμπουμ" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Το αρχείο zip δημιουργήθηκε σε %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Διαγράφηκε μόνιμα" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s έχει αποκατασταθεί" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Επιτυχής επαλήθευση" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Επιτυχής ενεργοποίηση" diff --git a/assets/locales/en/default.po b/assets/locales/en/default.po index 781824619..c4d5983de 100644 --- a/assets/locales/en/default.po +++ b/assets/locales/en/default.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" "PO-Revision-Date: 2022-10-31 16:44+0100\n" "Last-Translator: Michael Mayer \n" "Language-Team: \n" @@ -13,399 +13,415 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 2.3\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "" -#: messages.go:121 -msgid "Album not found" -msgstr "" - -#: messages.go:122 -msgid "Subject not found" -msgstr "" - -#: messages.go:123 -msgid "Person not found" -msgstr "" - -#: messages.go:124 -msgid "Face not found" -msgstr "" - -#: messages.go:125 -msgid "Not available in public mode" -msgstr "" - -#: messages.go:126 -msgid "Not available in read-only mode" -msgstr "" - -#: messages.go:127 -msgid "Please log in to your account" -msgstr "" - -#: messages.go:128 -msgid "Permission denied" -msgstr "" - #: messages.go:129 -msgid "Payment required" +msgid "Camera not found" msgstr "" #: messages.go:130 -msgid "Upload might be offensive" +msgid "Lens not found" msgstr "" #: messages.go:131 -msgid "Upload failed" +msgid "Album not found" msgstr "" #: messages.go:132 -msgid "No items selected" +msgid "Subject not found" msgstr "" #: messages.go:133 -msgid "Failed creating file, please check permissions" +msgid "Person not found" msgstr "" #: messages.go:134 -msgid "Failed creating folder, please check permissions" +msgid "Face not found" msgstr "" #: messages.go:135 -msgid "Could not connect, please try again" +msgid "Not available in public mode" msgstr "" #: messages.go:136 -msgid "Enter verification code" +msgid "Not available in read-only mode" msgstr "" #: messages.go:137 -msgid "Invalid verification code, please try again" +msgid "Please log in to your account" msgstr "" #: messages.go:138 -msgid "Invalid password, please try again" +msgid "Permission denied" msgstr "" #: messages.go:139 -msgid "Feature disabled" +msgid "Payment required" msgstr "" #: messages.go:140 -msgid "No labels selected" +msgid "Upload might be offensive" msgstr "" #: messages.go:141 -msgid "No albums selected" +msgid "Upload failed" msgstr "" #: messages.go:142 -msgid "No files available for download" +msgid "No items selected" msgstr "" #: messages.go:143 -msgid "Failed to create zip file" +msgid "Failed creating file, please check permissions" msgstr "" #: messages.go:144 -msgid "Invalid credentials" +msgid "Failed creating folder, please check permissions" msgstr "" #: messages.go:145 -msgid "Invalid link" +msgid "Could not connect, please try again" msgstr "" #: messages.go:146 -msgid "Invalid name" +msgid "Enter verification code" msgstr "" #: messages.go:147 -msgid "Busy, please try again later" +msgid "Invalid verification code, please try again" msgstr "" #: messages.go:148 -#, c-format -msgid "The wakeup interval is %s, but must be 1h or less" +msgid "Invalid password, please try again" msgstr "" #: messages.go:149 -msgid "Your account could not be connected" +msgid "Feature disabled" msgstr "" #: messages.go:150 -msgid "Too many requests" +msgid "No labels selected" msgstr "" #: messages.go:151 -msgid "Insufficient storage" +msgid "No albums selected" msgstr "" #: messages.go:152 -msgid "Quota exceeded" +msgid "No files available for download" +msgstr "" + +#: messages.go:153 +msgid "Failed to create zip file" +msgstr "" + +#: messages.go:154 +msgid "Invalid credentials" msgstr "" #: messages.go:155 -msgid "Changes successfully saved" +msgid "Invalid link" msgstr "" #: messages.go:156 -msgid "Album created" +msgid "Invalid name" msgstr "" #: messages.go:157 -msgid "Album saved" +msgid "Busy, please try again later" msgstr "" #: messages.go:158 #, c-format -msgid "Album %s deleted" +msgid "The wakeup interval is %s, but must be 1h or less" msgstr "" #: messages.go:159 -msgid "Album contents cloned" +msgid "Your account could not be connected" msgstr "" #: messages.go:160 -msgid "File removed from stack" +msgid "Too many requests" msgstr "" #: messages.go:161 -msgid "File deleted" +msgid "Insufficient storage" msgstr "" #: messages.go:162 -#, c-format -msgid "Selection added to %s" +msgid "Quota exceeded" msgstr "" #: messages.go:163 -#, c-format -msgid "One entry added to %s" +msgid "Registration disabled" msgstr "" #: messages.go:164 -#, c-format -msgid "%d entries added to %s" -msgstr "" - -#: messages.go:165 -#, c-format -msgid "One entry removed from %s" -msgstr "" - -#: messages.go:166 -#, c-format -msgid "%d entries removed from %s" +msgid "Verified email required" msgstr "" #: messages.go:167 -msgid "Account created" +msgid "Changes successfully saved" msgstr "" #: messages.go:168 -msgid "Account saved" +msgid "Album created" msgstr "" #: messages.go:169 -msgid "Account deleted" +msgid "Album saved" msgstr "" #: messages.go:170 -msgid "Settings saved" +#, c-format +msgid "Album %s deleted" msgstr "" #: messages.go:171 -msgid "Password changed" +msgid "Album contents cloned" msgstr "" #: messages.go:172 -#, c-format -msgid "Import completed in %d s" +msgid "File removed from stack" msgstr "" #: messages.go:173 -msgid "Import canceled" +msgid "File deleted" msgstr "" #: messages.go:174 #, c-format -msgid "Indexing completed in %d s" +msgid "Selection added to %s" msgstr "" #: messages.go:175 -msgid "Indexing originals..." +#, c-format +msgid "One entry added to %s" msgstr "" #: messages.go:176 #, c-format -msgid "Indexing files in %s" +msgid "%d entries added to %s" msgstr "" #: messages.go:177 -msgid "Indexing canceled" +#, c-format +msgid "One entry removed from %s" msgstr "" #: messages.go:178 #, c-format -msgid "Removed %d files and %d photos" +msgid "%d entries removed from %s" msgstr "" #: messages.go:179 -#, c-format -msgid "Moving files from %s" +msgid "Account created" msgstr "" #: messages.go:180 -#, c-format -msgid "Copying files from %s" +msgid "Account saved" msgstr "" #: messages.go:181 -msgid "Labels deleted" +msgid "Account deleted" msgstr "" #: messages.go:182 -msgid "Label saved" +msgid "Settings saved" msgstr "" #: messages.go:183 -msgid "Subject saved" +msgid "Password changed" msgstr "" #: messages.go:184 -msgid "Subject deleted" +#, c-format +msgid "Import completed in %d s" msgstr "" #: messages.go:185 -msgid "Person saved" +msgid "Import canceled" msgstr "" #: messages.go:186 -msgid "Person deleted" +#, c-format +msgid "Indexing completed in %d s" msgstr "" #: messages.go:187 -msgid "File uploaded" +msgid "Indexing originals..." msgstr "" #: messages.go:188 #, c-format -msgid "%d files uploaded in %d s" +msgid "Indexing files in %s" msgstr "" #: messages.go:189 -msgid "Processing upload..." +msgid "Indexing canceled" msgstr "" #: messages.go:190 -msgid "Upload has been processed" +#, c-format +msgid "Removed %d files and %d photos" msgstr "" #: messages.go:191 -msgid "Selection approved" +#, c-format +msgid "Moving files from %s" msgstr "" #: messages.go:192 -msgid "Selection archived" +#, c-format +msgid "Copying files from %s" msgstr "" #: messages.go:193 -msgid "Selection restored" +msgid "Labels deleted" msgstr "" #: messages.go:194 -msgid "Selection marked as private" +msgid "Label saved" msgstr "" #: messages.go:195 -msgid "Albums deleted" +msgid "Subject saved" msgstr "" #: messages.go:196 +msgid "Subject deleted" +msgstr "" + +#: messages.go:197 +msgid "Person saved" +msgstr "" + +#: messages.go:198 +msgid "Person deleted" +msgstr "" + +#: messages.go:199 +msgid "File uploaded" +msgstr "" + +#: messages.go:200 +#, c-format +msgid "%d files uploaded in %d s" +msgstr "" + +#: messages.go:201 +msgid "Processing upload..." +msgstr "" + +#: messages.go:202 +msgid "Upload has been processed" +msgstr "" + +#: messages.go:203 +msgid "Selection approved" +msgstr "" + +#: messages.go:204 +msgid "Selection archived" +msgstr "" + +#: messages.go:205 +msgid "Selection restored" +msgstr "" + +#: messages.go:206 +msgid "Selection marked as private" +msgstr "" + +#: messages.go:207 +msgid "Albums deleted" +msgstr "" + +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "" diff --git a/assets/locales/es/default.po b/assets/locales/es/default.po index b2efd0c1a..9b329bd5a 100644 --- a/assets/locales/es/default.po +++ b/assets/locales/es/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" "Last-Translator: DeepL \n" "Language-Team: Spanish \n" @@ -12,402 +12,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Algo ha ido mal, inténtalo de nuevo" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Incapaz de hacerlo" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "No se pudieron guardar los cambios" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "No se pudo borrar" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s ya existe" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "No encontrado" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "No se encuentra el archivo" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Archivo demasiado grande" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "No compatible" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Tipo no admitido" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Formato no admitido" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "La carpeta de originales está vacía" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Selección no encontrada" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Entidad no encontrada" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Cuenta no encontrada" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Usuario no encontrado" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Etiqueta no encontrada" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "No se encuentra la cámara" + +#: messages.go:130 +msgid "Lens not found" +msgstr "No se ha encontrado la lente" + +#: messages.go:131 msgid "Album not found" msgstr "Álbum no encontrado" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Asunto no encontrado" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Persona no encontrada" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Cara no encontrada" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "No disponible en modo público" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "No está disponible en modo de sólo lectura" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Por favor inicie sesión" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Permiso denegado" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Pago requerido" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "El archivo subido puede ser ofensivo" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Carga fallida" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Ningún elemento seleccionado" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Fallo al crear el archivo, por favor, compruebe los permisos" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Fallo al crear la carpeta, por favor, compruebe los permisos" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "No se pudo conectar, por favor vuelva a intentarlo" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Ingrese el código de verificación" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Código de verificación no válido, inténtalo de nuevo" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Contraseña inválida, por favor vuelva a intentarlo" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Característica desactivada" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Ninguna etiqueta seleccionada" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Ningún álbum seleccionado" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Ningún archivo disponible para descargar" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Fallo al crear el archivo zip" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Credenciales no válidas" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Enlace inválido" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Nombre inválido" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Ocupado, por favor vuelva a intentarlo más tarde" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "El intervalo de activación es %s, pero debe ser 1h o menos" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Su cuenta no pudo ser conectada" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Demasiadas peticiones" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Almacenamiento insuficiente" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Cuota superada" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "El registro está desactivado" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Se requiere una dirección de correo electrónico verificada" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Cambios guardados con éxito" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Álbum creado" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Álbum guardado" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Álbum %s borrado" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Contenidos del álbum clonados" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Archivo eliminado de la pila" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Archivo eliminado" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Selección añadida a %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Una entrada añadida a %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d entradas añadidas a %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Una entrada eliminada de %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d entradas eliminadas de %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Cuenta creada" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Cuenta guardada" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Cuenta borrada" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Ajustes guardados" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Contraseña cambiada" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Importación completada en %d" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Importación cancelada" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indexación completada en %d" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Indexando originales..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Indexando archivos en %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indexación cancelada" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Eliminados %d archivos y %d fotos" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Moviendo achivos desde %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Copiando archivos desde %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Etiquetas borradas" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Etiqueta guardada" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Asunto guardado" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Sujeto eliminado" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Persona salvada" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Persona eliminada" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Archivo cargado" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d archivos subidos en %d" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Procesando la carga..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "La carga ha sido procesada" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Selección aprobada" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Selección archivada" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Selección restaurada" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Selección marcada como privada" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Álbumes borrados" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip creado en %d" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Eliminado permanentemente" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s ha sido restaurado" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Verificado con éxito" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Activado exitosamente" diff --git a/assets/locales/et/default.po b/assets/locales/et/default.po index ee7e0d32e..8f298ff7d 100644 --- a/assets/locales/et/default.po +++ b/assets/locales/et/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" "Last-Translator: DeepL \n" "Language-Team: none\n" "Language: et\n" @@ -11,402 +11,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Midagi läks valesti, proovige uuesti" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Seda ei ole võimalik teha" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Muudatuste salvestamine ebaõnnestus" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Kustutamine ebaõnnestus" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s on juba olemas" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Ei leitud" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Faili ei leitud" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Fail on liiga suur" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Toetamata" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Toetamata tüüp" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Mittetoetatud formaat" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Originaalide kaust on tühi" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Valikut ei leitud" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Olemit ei leitud" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Kontot ei leitud" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Kasutajat ei leitud" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Silti ei leitud" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Kaamerat ei leitud" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Objektiivi ei leitud" + +#: messages.go:131 msgid "Album not found" msgstr "Albumit ei leitud" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Teemat ei leitud" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Isikut ei leitud" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Nägu ei leitud" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Pole avalikus režiimis saadaval" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Pole kirjutuskaitstud režiimis saadaval" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Palun logi oma kontole sisse" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Õigused puuduvad" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Nõutav makse" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Fail võib olla solvav" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Üleslaadimine ebaõnnestus" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Midagi pole valitud" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Faili loomine ebaõnnestus, kontrolli õiguseid" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Kausta loomine ebaõnnestus, kontrolli õiguseid" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Ühendumine ebaõnnestus, palun proovi uuesti" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Sisesta kontrollkood" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Vale kinnituskood, proovige uuesti" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Vale parool, palun proovi uuesti" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Funktsioon välja lülitatud" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Ühtegi silti pole valitud" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Ühtegi albumit pole valitud" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Ühtegi faili ei ole allalaadimiseks saadaval" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "ZIP-faili loomine ebaõnnestus" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Kehtetud ligipääsuandmed" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Vigane link" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Vigane nimi" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Hõivatud, palun proovi hiljem uuesti" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Ärkamisintervall on %s, kuid peab olema 1 tund või vähem" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Konto ühendamine ebaõnnestus" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Liiga palju taotlusi" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Ebapiisav ladustamine" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Kvoot ületatud" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Registreerimine on keelatud" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Nõutav on kinnitatud e-posti aadress" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Muudatused edukalt salvestatud" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Album lisatud" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Album salvestatud" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Album %s kustutatud" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Albumi sisu kloonitud" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Fail virnast eemaldatud" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Fail kustutatud" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Valik lisatud albumisse %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Üks kirje lisatud albumisse %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d kirjet lisatud albumisse %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Üks kirje eemaldatud albumist %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d kirjet eemaldatud albumist %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Konto loodud" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Konto salvestatud" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Konto kustutatud" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Seaded salvestatud" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Parool muudetud" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Import tehtud %d sekundiga" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Import tühistatud" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indekseerimine lõpetatud %d sekundiga" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Originaalide indekseerimine..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Failide indekseerimine: %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indekseerimine tühistatud" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Eemaldatud %d faili ja %d fotot" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Failide liigutamine asukohast %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Failide kopeerimine asukohast %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Sildid kustutatud" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Silt salvestatud" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Teema salvestatud" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Teema kustutatud" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Isik salvestatud" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Isik kustutatud" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "File üles laaditud" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d faili üles laaditud %d sekundiga" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Üleslaaditud faili töötlemine..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Üleslaaditud fail on töödeldud" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Valik heaks kiidetud" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Valik arhiveeritud" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Valik taastatud" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Valik privaatseks märgitud" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Albumid kustutatud" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "ZIP-fail loodud %d sekundiga" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Lõplikult kustutatud" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s on taastatud" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Edukalt kinnitatud" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Edukalt aktiveeritud" diff --git a/assets/locales/eu/default.po b/assets/locales/eu/default.po index c9b4aadd7..c9e2a8bb0 100644 --- a/assets/locales/eu/default.po +++ b/assets/locales/eu/default.po @@ -2,412 +2,427 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: DeepL \n" "Language-Team: none\n" "Language: eu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Arazoren bat izan da. Saiatu berriro" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Hori egin ezinik" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Ezin izan dira aldaketak gorde" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Ezin izan da ezabatu" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s dagoeneko existitzen da" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Ez da aurkitu" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Fitxategia ez da aurkitu" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Fitxategi handiegia" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Onartu gabe" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Onartu gabeko mota" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Onartu gabeko formatua" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Jatorrizkoen karpeta hutsik dago" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Ez da hautapena aurkitu" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Ez da aurkitu entitatea" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Ez da kontua aurkitu" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Ez da erabiltzailea aurkitu" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Ez da etiketa aurkitu" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Kamera ez da aurkitu" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Lentila ez da aurkitu" + +#: messages.go:131 msgid "Album not found" msgstr "Ez da aurkitu albuma" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Ez da aurkitu gaia" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Pertsona ez da aurkitu" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Aurpegia ez da aurkitu" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Ez dago eskuragarri modu publikoan" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Ez dago erabilgarri irakurtzeko soilik moduan" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Mesedez, hasi saioa zure kontuan" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Baimena ukatu egin da" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Ordainketa beharrezkoa da" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Kargatzea iraingarria izan daiteke" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Ezin izan da kargatu" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Ez da elementurik hautatu" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Ezin izan da fitxategia sortzean. Egiaztatu baimenak" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Ezin izan da karpeta sortzean. Egiaztatu baimenak" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Ezin izan da konektatu. Saiatu berriro" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Sartu egiaztapen-kodea" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Egiaztapen-kode baliogabea. Saiatu berriro" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Pasahitz baliogabea, saiatu berriro" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Eginbidea desgaituta dago" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Ez da etiketarik hautatu" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Ez dago albumik hautatu" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Ez dago fitxategirik deskargatzeko erabilgarri" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Ezin izan da zip fitxategia sortu" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Kredentzialak baliogabeak" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Esteka baliogabea" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Izen baliogabea" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Lanpetuta, saiatu berriro geroago" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Esnatzeko tartea %s da, baina ordu 1 edo gutxiagokoa izan behar du" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Ezin izan da zure kontua konektatu" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Eskaera gehiegi" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Biltegiratze nahikoa ez" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Kuota gainditu da" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Erregistroa desgaituta dago" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Egiaztatutako posta elektronikoa beharrezkoa da" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Aldaketak ongi gorde dira" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Sortu da albuma" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Albuma gorde da" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "%s albuma ezabatu da" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Albumen edukia klonatu da" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Fitxategia pilatik kendu da" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Fitxategia ezabatu da" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Aukeraketa gehitu da %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Sarrera bat gehitu da %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d sarrerak gehitu dira %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Sarrera bat kendu da %s-tik" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d sarrerak kendu dira %s-tik" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Kontua sortu da" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Kontua gorde da" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Kontua ezabatu da" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Ezarpenak gorde dira" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Pasahitza aldatu da" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Inportazioa %d s-an amaitu da" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Inportazioa bertan behera utzi da" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indexatzea %d s" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Jatorrizkoak indexatzen..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Fitxategiak indexatzen %s-n" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indexazioa bertan behera utzi da" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "%d fitxategiak eta %d argazkiak kendu dira" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Fitxategiak mugitzen %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "%s fitxategiak kopiatzen" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Etiketak ezabatu dira" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Etiketa gorde da" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Gaia gorde da" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Gaia ezabatu da" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Pertsona gordeta" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Pertsona ezabatu da" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Kargatu da fitxategia" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d fitxategiak %d s-etan kargatu dira" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Kargaketa prozesatzen..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Kargatzea prozesatu da" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Hautaketa onartu da" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Hautaketa artxibatuta dago" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Hautaketa leheneratu da" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Hautapena pribatu gisa markatu da" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Albumak ezabatu dira" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip sortu zen %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Betiko ezabatu da" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s leheneratu da" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Behar bezala egiaztatu da" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Behar bezala aktibatu da" diff --git a/assets/locales/fa/default.po b/assets/locales/fa/default.po index 20f8e299a..a8244c596 100644 --- a/assets/locales/fa/default.po +++ b/assets/locales/fa/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" "Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" @@ -12,402 +12,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n==0 || n==1);\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "یه چیزی اشتباه شد دوباره تلاش کن" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "قادر به انجام آن نیست" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "تغییرات را نمی توان ذخیره کرد" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "نمی توان حذف کرد" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s از قبل وجود دارد" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "پیدا نشد" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "فایل پیدا نشد" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "فایل خیلی بزرگ است" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "پشتیبانی نمی شود" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "نوع پشتیبانی نشده" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "قالب پشتیبانی نشده" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "پوشه اصلی خالی است" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "انتخاب پیدا نشد" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "موجودیت پیدا نشد" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "حساب کاربری پیدا نشد" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "کاربر پیدا نشد" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "برچسب پیدا نشد" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "دوربین پیدا نشد" + +#: messages.go:130 +msgid "Lens not found" +msgstr "لنز یافت نشد" + +#: messages.go:131 msgid "Album not found" msgstr "آلبوم پیدا نشد" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "موضوع پیدا نشد" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "فرد پیدا نشد" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "صورت پیدا نشد" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "در حالت عمومی در دسترس نیست" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "در حالت فقط خواندنی در دسترس نیست" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "لطفا وارد شوید و دوباره امتحان کنید" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "فرد حذف شد" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "پرداخت لازم است" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "آپلود ممکن است توهین آمیز باشد" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "آپلود انجام نشد" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "هیچ موردی انتخاب نشده است" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "فایل ایجاد نشد، لطفا مجوزها را بررسی کنید" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "پوشه ایجاد نشد، لطفا مجوزها را بررسی کنید" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "اتصال برقرار نشد، لطفاً دوباره امتحان کنید" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "کد تایید را وارد کنید" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "کد تأیید نامعتبر است، لطفاً دوباره امتحان کنید" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "رمز عبور نامعتبر است، لطفا دوباره امتحان کنید" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "ویژگی غیرفعال است" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "هیچ برچسبی انتخاب نشده است" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "هیچ آلبومی انتخاب نشده است" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "هیچ فایلی برای دانلود موجود نیست" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "فایل فشرده ایجاد نشد" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "گواهی نامه نامعتبر" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "لینک نامعتبر" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "نام نامعتبر" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "مشغول است، لطفاً بعداً دوباره امتحان کنید" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "فاصله بیداری %s است، اما باید 1 ساعت یا کمتر باشد" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "حساب شما متصل نشد" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "درخواست های خیلی زیاد" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "ذخیره سازی ناکافی" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "از سهمیه فراتر رفت" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "ثبت نام غیرفعال شد" + +#: messages.go:164 +msgid "Verified email required" +msgstr "ایمیل تایید شده الزامی است" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "تغییرات با موفقیت ذخیره شد" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "آلبوم ایجاد شد" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "آلبوم ذخیره شد" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "آلبوم %s حذف شد" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "محتویات آلبوم کلون شد" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "فایل از پشته حذف شد" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "فایل حذف شد" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "مورد انتخابی به %s اضافه شد" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "یک مورد به %s اضافه شد" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d مورد به %s اضافه شد" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "یک مورد از %s حذف شد" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d مورد از %s حذف شد" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "حساب کاربری ایجاد شد" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "حساب کاربری ذخیره شد" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "حساب کاربری حذف شد" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "تنظیمات ذخیره شد" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "رمزعبور تغییر کرد" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "وارد کردن در %d ثانیه تکمیل شد" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "وارد کردن لغو شد" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "نمایه سازی در %d ثانیه تکمیل شد" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "نمایه سازی نسخه های اصلی ..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "نمایه سازی فایل ها در %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "نمایه سازی لغو شد" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "%d فایل و %d عکس حذف شد" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "انتقال فایل ها از %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "کپی کردن فایل ها از %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "برچسب ها حذف شدند" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "برچسب ذخیره شد" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "موضوع ذخیره شد" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "موضوع حذف شد" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "فرد ذخیره شد" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "فرد حذف شد" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "فایل حذف شد" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d فایل در %d ثانیه آپلود شد" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "در حال پردازش آپلود..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" -msgstr "%s بازیابی شده است" +msgstr "بارگذاری پردازش شده است" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "مورد انتخابی تایید شد" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "مورد انتخابی بایگانی شد" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "مورد انتخابی بازیابی شد" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "مورد انتخابی به‌عنوان خصوصی علامت‌گذاری شد" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "آلبوم حذف شد" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "فایل فشرده در %d ثانیه ایجاد شد" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "برای همیشه حذف شد" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s بازیابی شده است" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "با موفقیت تأیید شد" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "با موفقیت فعال شد" diff --git a/assets/locales/fi/default.po b/assets/locales/fi/default.po index e3f4ee7e4..e682727ac 100644 --- a/assets/locales/fi/default.po +++ b/assets/locales/fi/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" "Last-Translator: DeepL \n" "Language-Team: none\n" "Language: fi\n" @@ -11,402 +11,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Jokin meni pieleen, yritä uudelleen" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Se ei onnistu" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Muutoksia ei voitu tallentaa" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Ei voitu poistaa" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s on jo olemassa" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Ei löytynyt" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Tiedostoa ei löydy" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Tiedosto liian suuri" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Ei tuettu" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Tyyppiä ei tueta" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Ei tuettu muoto" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Originaalit-kansio on tyhjä" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Valintaa ei löydy" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Entiteettiä ei löydy" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Tiliä ei löydy" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Käyttäjää ei löydy" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Tarraa ei löydy" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Kameraa ei löydy" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Objektiivia ei löydy" + +#: messages.go:131 msgid "Album not found" msgstr "Albumia ei löydy" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Aihetta ei löydy" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Henkilöä ei löydy" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Kasvoja ei löydy" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Ei käytettävissä julkisessa tilassa" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Ei käytettävissä vain luku-tilassa" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Kirjaudu sisään tilillesi" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Lupa evätty" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Vaadittu maksu" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Upload saattaa olla loukkaava" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Lataus epäonnistui" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Kohdetta ei ole valittu" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Tiedoston luominen epäonnistui, tarkista käyttöoikeudet" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Kansion luominen epäonnistui, tarkista käyttöoikeudet" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Yhteyttä ei saatu muodostettua, yritä uudelleen" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "syötä vahvistus koodi" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Virheellinen vahvistuskoodi, yritä uudelleen" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Väärä salasana, yritä uudelleen" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Ominaisuus poistettu käytöstä" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Ei valittuja tarroja" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Ei valittuja albumeita" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Tiedostoja ei ole ladattavissa" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Zip-tiedoston luominen epäonnistui" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Virheelliset valtakirjat" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Virheellinen linkki" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Virheellinen nimi" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Varattu, yritä myöhemmin uudelleen" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Heräämisväli on %s, mutta sen on oltava enintään 1h" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Tiliäsi ei voitu yhdistää" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Liian monta pyyntöä" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Riittämätön varastointi" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Kiintiö ylitetty" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Rekisteröityminen on poistettu käytöstä" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Vaaditaan vahvistettu sähköpostiosoite" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Muutokset tallennettu onnistuneesti" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Albumi luotu" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Albumi tallennettu" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Albumi %s poistettu" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Albumin sisältö kloonattu" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Tiedosto poistettu pinosta" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Tiedosto poistettu" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Valinta lisätty %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Yksi merkintä lisätty kohtaan %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d merkintöjä lisätty %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Yksi merkintä poistettu kohdasta %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d merkinnät poistettu %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Tili luotu" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Tallennettu tili" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Tili poistettu" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Asetukset tallennettu" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Salasana vaihdettu" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Tuonti valmis %d s" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Tuonti peruutettu" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indeksointi valmis %d s" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Alkuperäiskappaleiden indeksointi..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Tiedostojen indeksointi osoitteessa %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indeksointi peruutettu" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Poistettiin %d tiedostoa ja %d valokuvaa" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Tiedostojen siirtäminen %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Tiedostojen kopiointi %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Tunnisteet poistettu" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Tarra tallennettu" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Aihe tallennettu" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Aihe poistettu" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Tallennettu henkilö" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Henkilö poistettu" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Ladattu tiedosto" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d tiedostoa ladattu %d s aikana" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Käsittelen latausta..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Lataus on käsitelty" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Valinta hyväksytty" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Valinta arkistoitu" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Valinta palautettu" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Valinta merkitty yksityiseksi" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Albumit poistettu" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip luotu %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Poistettu pysyvästi" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s on palautettu" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Vahvistettu onnistuneesti" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Aktivointi onnistui" diff --git a/assets/locales/fr/default.po b/assets/locales/fr/default.po index 12cea6c83..3476325ad 100644 --- a/assets/locales/fr/default.po +++ b/assets/locales/fr/default.po @@ -2,9 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-28 15:07+0000\n" +"Last-Translator: jean-louis67 \n" "Language-Team: French \n" "Language: fr\n" @@ -12,402 +12,422 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Quelque chose s'est mal passé, réessayez" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" -msgstr "Impossible de faire cela" +msgstr "Impossible d'effectuer cela" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Les modifications n'ont pas pu être sauvegardées" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "N'a pas pu être supprimé" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s existe déjà" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Non trouvé" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Fichier non trouvé" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Fichier trop volumineux" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Non pris en charge" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Type non pris en charge" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Format non supporté" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Le dossier des originaux est vide" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Sélection non trouvée" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Entité non trouvée" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Compte non trouvé" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Utilisateur non trouvé" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Étiquette non trouvée" -#: messages.go:121 -msgid "Album not found" -msgstr "Album introuvable" +#: messages.go:129 +msgid "Camera not found" +msgstr "Caméra non trouvée" -#: messages.go:122 +#: messages.go:130 +msgid "Lens not found" +msgstr "Objectif non trouvé" + +#: messages.go:131 +msgid "Album not found" +msgstr "Album non trouvé" + +#: messages.go:132 msgid "Subject not found" msgstr "Sujet non trouvé" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Personne non trouvée" -#: messages.go:124 +#: messages.go:134 +#, fuzzy msgid "Face not found" msgstr "Visage non trouvé" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Non disponible en mode public" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Non disponible en mode lecture seule" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" -msgstr "Veuillez vous connecter avec votre compte" +msgstr "Veuillez vous connecter à votre compte" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" -msgstr "Permission refusée" +msgstr "Autorisation refusée" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Paiement requis" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" -msgstr "Le contenu chargé peut être choquant" +msgstr "Le contenu chargé pourrait être de nature offensante" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Échec du chargement" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Aucun élément sélectionné" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "La création du fichier a échoué, veuillez vérifier les permissions" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Échec de la création du dossier, veuillez vérifier les permissions" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Échec lors de la connexion, veuillez réessayer" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Entrer le code de vérification" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" -msgstr "Code de vérification invalide, veuillez réessayer" +msgstr "Code de vérification incorrect, veuillez réessayer" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" -msgstr "Mot de passe invalide, veuillez réessayer" +msgstr "Mot de passe incorrect, veuillez réessayer" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Fonctionnalité désactivée" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Aucune étiquette sélectionnée" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Aucun album sélectionné" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" -msgstr "Aucun fichier disponible au téléchargement" +msgstr "Aucun fichier à télécharger" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Échec de la création du fichier zip" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" -msgstr "Les informations d'identification sont invalides" +msgstr "Les informations d'identification ne sont pas valables" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" -msgstr "Lien invalide" +msgstr "Lien incorrect" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" -msgstr "Nom invalide" +msgstr "Nom incorrect" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Occupé, veuillez réessayer plus tard" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" -msgstr "L'intervalle de réveil est %s, mais doit être inférieur ou égal à 1h" +msgstr "" +"L'intervalle entre les tâches est de %s, mais il doit être inférieur ou égal " +"à 1 h" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Votre compte n'a pas pu être connecté" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Trop de demandes" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Espace de stockage insuffisant" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Quota dépassé" -#: messages.go:155 +#: messages.go:163 +#, fuzzy +msgid "Registration disabled" +msgstr "Inscription désactivée" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Adresse de courriel vérifiée requise" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Les modifications ont bien été enregistrées" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Album créé" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Album sauvegardé" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Album %s supprimé" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Le contenu de l'album a été copié" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" -msgstr "Le fichier a été retiré du groupe" +msgstr "Le fichier a été retiré de la pile" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Fichier supprimé" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Sélection ajoutée à %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Une entrée a été ajoutée à %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d entrées ont été ajoutées à %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" -msgstr "Une entrée a été supprimée de %s" +msgstr "Une entrée a été supprimée dans %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d entrées ont été supprimées de %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Compte créé" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Compte sauvegardé" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Compte supprimé" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Paramètres sauvegardés" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Mot de passe modifié" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Importation terminée en %d s" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Importation annulée" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indexation terminée en %d s" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Indexage des originaux…" -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" -msgstr "Indexation des fichiers de %s" +msgstr "Indexation des fichiers en %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indexation annulée" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Suppression de %d fichiers et %d photos" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Déplacement de fichiers depuis %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Copie de fichiers depuis %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Étiquettes supprimées" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" -msgstr "Étiquettes sauvegardées" +msgstr "Étiquette sauvegardée" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Sujet sauvegardé" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Sujet supprimé" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Personne sauvegardée" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Personne supprimée" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" -msgstr "Fichier téléchargé" +msgstr "Fichier chargé" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d fichiers chargés en %d s" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." -msgstr "Traitement du téléchargement..." +msgstr "Chargement en cours…" -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" -msgstr "Le téléchargement a été traité" +msgstr "Le chargement a été effectué" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Sélection approuvée" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Sélection archivée" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Sélection restaurée" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Sélection marquée comme privée" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Albums supprimés" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Archive zip créée en %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Supprimé définitivement" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s a été restauré" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Vérifié avec succès" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Activation réussie" diff --git a/assets/locales/ga/default.po b/assets/locales/ga/default.po index d0f6de88d..89438350d 100644 --- a/assets/locales/ga/default.po +++ b/assets/locales/ga/default.po @@ -7,10 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: DeepL \n" "Language-Team: none\n" "Language: ga\n" "MIME-Version: 1.0\n" @@ -18,402 +17,418 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : (n>2 && n<7) ? 2 :" "(n>6 && n<11) ? 3 : 4;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Chuaigh rud éigin mícheart, bain triail eile as" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Ní féidir é sin a dhéanamh" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Níorbh fhéidir na hathruithe a shábháil" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Níorbh fhéidir a scriosadh" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s ann cheana" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Ní bhfuarthas" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Comhad gan aimsiú" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Comhad ró-mhór" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Gan tacaíocht" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Cineál nach dtacaítear leis" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Formáid nach dtacaítear léi" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Tá fillteán bunghnéithe folamh" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Níor aimsíodh an rogha" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Aonán gan aimsiú" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Cuntas gan aimsiú" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Úsáideoir gan aimsiú" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Níor aimsíodh an lipéad" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Níor aimsíodh an ceamara" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Níor aimsíodh an lionsa" + +#: messages.go:131 msgid "Album not found" msgstr "Albam gan aimsiú" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Ní bhfuarthas an t-ábhar" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Ní bhfuarthas an duine" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Aghaidh gan aimsiú" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Níl sé ar fáil i mód poiblí" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Níl sé ar fáil i mód inléite amháin" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Logáil isteach i do chuntas le do thoil" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Cead diúltaithe" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Íocaíocht ag teastáil" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "D'fhéadfadh uaslódáil a bheith maslach" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Theip ar an uaslódáil" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Níl aon mhír roghnaithe" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Theip ar chruthú an chomhaid, seiceáil na ceadanna" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Theip ar chruthú fillteán, seiceáil na ceadanna" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Níorbh fhéidir ceangal a dhéanamh, bain triail eile as" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Cuir isteach cód fíorúcháin" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Cód fíoraithe neamhbhailí, bain triail eile as" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Pasfhocal neamhbhailí, bain triail eile as" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Gné díchumasaithe" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Níor roghnaíodh aon lipéid" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Níor roghnaíodh aon albam" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Níl aon chomhaid ar fáil le híoslódáil" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Theip ar chruthú an chomhaid zip" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Dintiúir neamhbhailí" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Nasc neamhbhailí" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Ainm neamhbhailí" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Gnóthach, bain triail eile as ar ball" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Is é %s an t-eatramh múscail, ach caithfidh sé a bheith 1h nó níos lú" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Níorbh fhéidir do chuntas a nascadh" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "An iomarca iarratas" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Stóráil neamhleor" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Sáraíodh an cuóta" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Clárú díchumasaithe" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Ríomhphost fíoraithe ag teastáil" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Sábháladh na hathruithe" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Albam cruthaithe" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Sábháilte albam" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Albam %s scriosta" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Clónáilte ábhar albam" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Baineadh an comhad den chruach" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Scriosadh an comhad" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Cuireadh an rogha le %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Cuireadh iontráil amháin le %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d iontráil curtha le %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Baineadh iontráil amháin de %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d iontráil bainte de %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Cuntas cruthaithe" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Cuntas sábháilte" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Scriosadh an cuntas" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Socruithe sábháilte" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Athraíodh an pasfhocal" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Iompórtáil críochnaithe i %d s" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Cealaíodh an iompórtáil" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Innéacsú curtha i gcrích in %d s" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Buntéacs á innéacsú..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Comhaid á innéacsú in %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Innéacsú cealaithe" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Baineadh %d comhaid agus %d grianghraif" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Comhaid á mbogadh ó %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Comhaid á gcóipeáil ó %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Scriosadh na lipéid" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Lipéad sábháilte" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Ábhar sábháilte" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Scriosadh an t-ábhar" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Sábháladh an duine" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Scriosadh an duine" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Comhad uaslódáilte" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d comhaid uaslódáilte i %d s" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Uaslódáil á phróiseáil..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Próiseáladh an t-uaslódáil" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Faomhadh an roghnúcháin" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Roghnaithe sa chartlann" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Athchóiríodh an roghnúchán" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Roghnú marcáilte mar phríobháideach" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Albaim scriosta" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip cruthaithe i %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Scriosta go buan" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s athchóirithe" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "D'éirigh leis a fhíorú" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Cuireadh i ngníomh go rathúil" diff --git a/assets/locales/he/default.po b/assets/locales/he/default.po index 1603d53d7..79846fb27 100644 --- a/assets/locales/he/default.po +++ b/assets/locales/he/default.po @@ -2,10 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: DeepL \n" "Language-Team: Hebrew \n" "Language: he\n" @@ -14,402 +13,418 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && " "n % 10 == 0) ? 2 : 3));\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" -msgstr "קרתה תקלה נסה שוב" +msgstr "משהו השתבש נא לנסות שוב" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" -msgstr "לא מסוגל לעשות את זה" +msgstr "לא ניתן לבצע זאת" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "לא ניתן לשמור שינויים" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "לא ניתן למחיקה" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s כבר קיים" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "לא נמצא" -#: messages.go:110 +#: messages.go:118 msgid "File not found" -msgstr "הקובץ לא נמצא" +msgstr "קובץ לא נמצא" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "קובץ גדול מדי" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" -msgstr "אינו נתמך" +msgstr "לא נתמך" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "סוג לא נתמך" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" -msgstr "פורמט לא נתמך" +msgstr "תסדיר לא נתמך" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" -msgstr "תיקיית המקור ריקה" +msgstr "תיקיית מקור ריקה" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "הבחירה לא נמצאה" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "הישות לא נמצאה" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "החשבון לא נמצא" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "המשתמש לא נמצא" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "התווית לא נמצאה" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "לא נמצאה מצלמה" + +#: messages.go:130 +msgid "Lens not found" +msgstr "לא נמצא עדשה" + +#: messages.go:131 msgid "Album not found" msgstr "האלבום לא נמצא" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "הנושא לא נמצא" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "אדם לא נמצא" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "הפנים לא נמצאו" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "לא זמין במצב ציבורי" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "לא זמין במצב קריאה בלבד" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "אנא היכנס לחשבון שלך" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "גישה נדחתה" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "נדרש תשלום" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "ההעלאה עשויה להיות פוגענית" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" -msgstr "העלאה נכשלה" +msgstr "העלאה כשלה" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "לא נבחרו פריטים" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "יצירת הקובץ נכשלה, אנא בדוק את ההרשאות" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "יצירת התיקיה נכשלה, אנא בדוק את ההרשאות" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "לא ניתן היה להתחבר, נסה שוב" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "הכנס קוד אימות" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "קוד אימות לא חוקי, אנא נסה שוב" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "סיסמה לא תקינה, נסה שוב" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "התכונה מושבתת" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "לא נבחרו תוויות" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "לא נבחרו אלבומים" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "אין קבצים זמינים להורדה" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "יצירת קובץ ה-zip נכשלה" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "אישורים לא תקינים" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "קישור לא תקין" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "מספר לא תקף" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "עסוק, אנא נסה שוב מאוחר יותר" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "מרווח ההשכמה הוא %s, אך חייב להיות שעה אחת או פחות" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "לא ניתן היה לחבר את החשבון שלך" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "יותר מדי בקשות" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "אחסון לא מספיק" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "חריגה מהמכסה" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "ההרשמה אינה פעילה" + +#: messages.go:164 +msgid "Verified email required" +msgstr "נדרש כתובת דוא\"ל מאומתת" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "השינויים נשמרו בהצלחה" -#: messages.go:156 +#: messages.go:168 msgid "Album created" -msgstr "האלבום נוצר" +msgstr "אלבום נוצר" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "האלבום נשמר" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "האלבום %s נמחק" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "תוכן האלבום שוכפל" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "הקובץ הוסר מהאיחוד" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "הקובץ נמחק" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "הבחירה נוספה ל-%s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "רשומה אחת נוספה ל-%s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d רשומות נוספו ל-%s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "רשומה אחת הוסרה מ-%s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d רשומות הוסרו מ-%s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" -msgstr "החשבון נוצר" +msgstr "חשבון נוצר" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "החשבון נשמר" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" -msgstr "החשבון נמחק" +msgstr "חשבון נמחק" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "ההגדרות נשמרו" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "סיסמא שונתה" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "הייבוא הושלם ב-%d שניות" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "הייבוא בוטל" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "האינדוקס הושלם ב-%d שניות" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "מאנדקס קבצי מקור..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "מאנדקס קבצים תוך %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "יצירת האינדקס בוטלה" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "הוסרו %d קבצים ו-%d תמונות" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "מעביר קבצים מ-%s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "מעתיק קבצים מ-%s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "תוויות נמחקו" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "התווית נשמרה" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "הנושא נשמר" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "הנושא נמחק" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "אדם נשמר" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "אדם נמחק" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "הקובץ הועלה" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d קבצים הועלו תוך %d שניות" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "מעבד העלאה..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "ההעלאה עובדה" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "הבחירה אושרה" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "הבחירה הועברה לארכיון" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "הבחירה שוחזרה" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "הבחירה סומנה כפרטית" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "אלבומים נמחקו" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" -msgstr "ה-ZIP נוצר תוך %d שניות" +msgstr "קובץ Zip נוצר תוך %d שניות" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "נמחק לצמיתות" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s שוחזר" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "אומת בהצלחה" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "הופעל בהצלחה" diff --git a/assets/locales/hi/default.po b/assets/locales/hi/default.po index 0d14ff1bf..cd32b24e6 100644 --- a/assets/locales/hi/default.po +++ b/assets/locales/hi/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" "Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Hindi \n" "Language-Team: none\n" @@ -13,402 +13,418 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Nešto nije u redu, pokušajte ponovno" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Nesposoban to učiniti" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Promjene se nisu mogle spremiti" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Nije moguće izbrisati" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s već postoji" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Nije pronađeno" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Datoteka nije pronađena" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Datoteka je prevelika" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Nepodržano" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Nepodržana vrsta" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Nepodržani format" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Originalna mapa je prazna" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Odabir nije pronađen" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Entitet nije pronađen" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "račun nije pronađen" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Korisnik nije pronađen" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Oznaka nije pronađena" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Kamera nije pronađena" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Leća nije pronađena" + +#: messages.go:131 msgid "Album not found" msgstr "Album nije pronađen" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Predmet nije pronađen" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Osoba nije pronađena" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Lice nije pronađeno" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Nije dostupno u javnom načinu" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "nije dostupno u načinu samo za čitanje" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Molimo prijavite se i pokušajte ponovno" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Osoba je izbrisana" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Potrebno je plaćanje" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Prijenos bi mogao biti uvredljiv" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Prijenos nije uspio" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Nema odabranih stavki" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Izrada datoteke nije uspjela, provjerite dopuštenja" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Izrada mape nije uspjela, provjerite dopuštenja" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Povezivanje nije uspjelo, pokušajte ponovno" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Unesite kontrolni kod" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Nevažeći kontrolni kod, pokušajte ponovno" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Nevažeća lozinka, pokušajte ponovo" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Značajka je onemogućena" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Nije odabrana nijedna oznaka" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Nije odabran nijedan album" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Nema dostupnih datoteka za preuzimanje" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Izrada zip datoteke nije uspjela" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Nevažeće vjerodajnice" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Nevažeća veza" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Nevažeći naziv" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Zauzeto, pokušajte ponovo kasnije" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Interval buđenja je %s, ali mora biti 1 sat ili manje" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Vaš račun nije bilo moguće povezati" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Previše zahtjeva" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Nedovoljno prostora za pohranu" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Kvota premašena" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Registracija onemogućena" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Potrebna je potvrđena e-pošta" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Promjene su uspješno spremljene" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Album stvoren" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Album je spremljen" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Album %s je izbrisan" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Sadržaj albuma je kloniran" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Datoteka je uklonjena iz hrpe" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Datoteka je izbrisana" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Odabir je dodan u %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Jedan unos dodan u %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d unosi dodani u %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Jedan unos uklonjen iz %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d unosi uklonjeni iz %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Račun kreiran" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Račun spremljen" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Račun je izbrisan" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Postavke spremljene" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Lozinka je promijenjena" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Uvoz dovršen za %d s" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Uvoz je otkazan" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indeksiranje dovršeno za %d s" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Indeksiranje originala..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Indeksiranje datoteka u %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indeksiranje je otkazano" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Uklonjene %d datoteke i %d fotografije" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Premještanje datoteka iz %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Kopiranje datoteka s %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Oznake su izbrisane" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Oznaka je spremljena" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Predmet je spremljen" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Predmet je izbrisan" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Osoba je spremljena" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Osoba je izbrisana" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Datoteka je izbrisana" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d datoteke prenesene u %d s" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Obrada prijenosa..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Prijenos bi mogao biti uvredljiv" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Odabir odobren" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Odabir je arhiviran" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Odabir je vraćen" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Odabir je označen kao privatan" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Albumi su izbrisani" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip stvoren u %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Trajno izbrisano" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" -msgstr "Odabir je vraćen" +msgstr "%s je vraćen" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Uspješno potvrđeno" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Uspješno aktiviran" diff --git a/assets/locales/hu/default.po b/assets/locales/hu/default.po index 3e64ef7e4..776f39004 100644 --- a/assets/locales/hu/default.po +++ b/assets/locales/hu/default.po @@ -2,9 +2,10 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Hungarian \n" "Language: hu\n" @@ -12,402 +13,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Valami rosszul ment, próbálja újra" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Erre képtelen" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Módosításokat nem sikerült menteni" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Nem sikerült törölni" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s már létezik" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Nem található" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Fájl nem található" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Túl nagy fájl" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Nem támogatott" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Nem támogatott típus" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Nem támogatott formátum" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Az Originals mappa üres" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Kiválasztás nem található" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Entitás nem található" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Fiók nem található" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Felhasználó nem található" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Címke nem található" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "A kamera nem található" + +#: messages.go:130 +msgid "Lens not found" +msgstr "A lencse nem található" + +#: messages.go:131 msgid "Album not found" msgstr "Album nem található" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Tárgy nem található" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Személy nem található" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Arc nem található" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Nyilvános módban nem elérhető" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Nem elérhető olvasói módban" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Kérjük, jelentkezzen be fiókjába" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Engedély megtagadva" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Fizetés szükséges" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "A feltöltött fájl sértő lehet" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Feltöltés sikertelen" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Nincsenek kiválasztva elemek" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Sikertelen fájl létrehozás. Kérjük, ellenőrizze a jogosultságokat" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Sikertelen mappa létrehozás. Kérjük, ellenőrizze a jogosultságokat" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Nem sikerült csatlakozni, próbálja újra" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Adja meg a megerősítő kódot" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Érvénytelen ellenőrző kód. Kérjük, próbálja újra" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Érvénytelen jelszó, próbálkozzon újra" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Funkció letiltva" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Nincsenek kiválasztva címkék" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Nincsenek kiválasztott albumok" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Nincsenek letölthető fájlok" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Nem sikerült létrehozni a zip fájlt" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Érvénytelen belépési adatok" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Érvénytelen hivatkozás" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Érvénytelen név" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Túl magas terhelés, próbálkozzon újra később" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Az ébresztési intervallum a %s, de legfeljebb 1 óra lehet." -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "A fiókját nem lehetett csatlakoztatni" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Túl sok kérés" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Elégtelen tárolás" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "A kvóta túllépése" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Regisztráció letiltva" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Ellenőrzött e-mail cím szükséges" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Módosítások sikeresen mentve" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Album létrehozva" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Album mentve" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "%s album törölve" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Album tartalma klónozva" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Fájl eltávolítva a halomból" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Fájl törölve" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Választék hozzáadva a következőhöz: %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Egy bejegyzés hozzáadva a következőhöz: %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d bejegyzés hozzáadva a következőhöz: %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Egy bejegyzés eltávolítva innen: %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d bejegyzés eltávolítva innen: %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Fiók létrehozva" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Fiók mentve" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Fiók törölve" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Beállítások elmentve" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Jelszó megváltoztatva" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Importálás %d másodperc alatt befejeződött" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Importálás megszakítva" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indexelés %d másodperc alatt befejeződött" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Eredeti dokumentumok indexelése..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Fájlok indexelése itt: %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indexelés megszakítva" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "%d fájl és %d fénykép eltávolítva" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Fájlok áthelyezése innen: %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Fájlok másolása innen: %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Címkék törölve" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Címkék mentve" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Tárgy mentve" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Tárgy törölve" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Személy mentve" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Személy törölve" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Fájl feltöltve" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d fájl feltöltve %d másodperc alatt" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Feltöltött fájlok feldolgozása..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Feltöltött fájlok feldolgozva" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "A kijelölés jóváhagyva" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "A kijelölés archiválva" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "A kijelölés visszaállítva" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "A kijelölés privátként megjelölve" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Albumok törölve" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "A tömörített fájl létrejött %d másodperc alatt" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Véglegesen törölve" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s visszaállítva" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Sikeresen ellenőrizve" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Sikeres aktiválás" diff --git a/assets/locales/id/default.po b/assets/locales/id/default.po index c2c67e9a8..125cb85df 100644 --- a/assets/locales/id/default.po +++ b/assets/locales/id/default.po @@ -2,9 +2,10 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Indonesian \n" "Language: id\n" @@ -12,402 +13,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Ada yang salah, coba lagi" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Tidak dapat melakukan itu" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Perubahan tidak dapat disimpan" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Tidak dapat dihapus" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s sudah ada" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Tidak ditemukan" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Berkas tidak ditemukan" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Berkas terlalu besar" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Tidak didukung" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Jenis tidak didukung" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Format yang tidak didukung" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Folder asli kosong" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Pilihan tidak ditemukan" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Entitas tidak ditemukan" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Akun tidak ditemukan" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Pengguna tidak ditemukan" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Label tidak ditemukan" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Kamera tidak ditemukan" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Lensa tidak ditemukan" + +#: messages.go:131 msgid "Album not found" msgstr "Album tidak ditemukan" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Subjek tidak ditemukan" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Orang tidak ditemukan" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Wajah tidak ditemukan" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Tidak tersedia dalam mode publik" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Tidak tersedia dalam mode hanya-baca" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Silakan masuk ke akun Anda" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Izin ditolak" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Diperlukan pembayaran" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Unggahan mungkin menyinggung" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Unggahan gagal" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Tidak ada item yang dipilih" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Gagal membuat file, silakan periksa izin" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Gagal membuat folder, harap periksa izin" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Tidak dapat terhubung, silakan coba lagi" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Masukkan kode verifikasi" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Kode verifikasi tidak valid, silakan coba lagi" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Kata sandi salah, silakan coba lagi" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Fitur dinonaktifkan" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Tidak ada label yang dipilih" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Tidak ada album yang dipilih" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Tidak ada file yang tersedia untuk diunduh" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Gagal membuat file zip" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Kredensial tidak valid" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Tautan tidak valid" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Nama tidak valid" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Sibuk, silakan coba lagi nanti" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Interval wakeup adalah %s, tetapi harus 1 jam atau kurang" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Akun Anda tidak dapat terhubung" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Terlalu banyak permintaan" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Penyimpanan yang tidak memadai" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Kuota terlampaui" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Pendaftaran dinonaktifkan" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Email terverifikasi diperlukan." + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Perubahan berhasil disimpan" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Album dibuat" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Album disimpan" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Album %s dihapus" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Konten album dikloning" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "File dihapus dari tumpukan" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Berkas dihapus" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Pilihan ditambahkan ke %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Satu entri ditambahkan ke %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d entri ditambahkan ke %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Satu entri dihapus dari %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d entri dihapus dari %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Akun dibuat" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Akun disimpan" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Akun dihapus" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Pengaturan disimpan" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Kata sandi diubah" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Impor selesai dalam %d detik" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Impor dibatalkan" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Pengindeksan selesai dalam %d detik" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Mengindeks dokumen asli..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Mengindeks file dalam %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Pengindeksan dibatalkan" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Menghapus %d file dan %d foto" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Memindahkan file dari %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Menyalin file dari %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Label dihapus" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Label disimpan" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Subjek disimpan" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Subjek dihapus" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Orang disimpan" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Orang dihapus" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "File diunggah" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d file diupload di %d detik" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Memproses unggahan..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Unggahan telah diproses" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Pilihan disetujui" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Pilihan diarsipkan" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Pilihan dipulihkan" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Pilihan ditandai sebagai pribadi" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Koleksi album dihapus" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip dibuat dalam %d detik" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Dihapus permanen" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s telah dipulihkan" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Berhasil diverifikasi" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Berhasil diaktifkan" diff --git a/assets/locales/it/default.po b/assets/locales/it/default.po index 2830904c1..88d901080 100644 --- a/assets/locales/it/default.po +++ b/assets/locales/it/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" "Last-Translator: DeepL \n" "Language-Team: Italian \n" @@ -12,402 +12,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Qualcosa è andato storto, riprova" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Impossibile farlo" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Le modifiche non possono essere salvate" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Impossibile eliminare" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s esiste già" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Non trovato" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "File non trovato" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "File troppo grande" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Non supportato" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Formato non supportato" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Formato non supportato" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "La cartella degli originali è vuota" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Selezione non trovata" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Entità non trovata" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Account non trovato" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Utente non trovato" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Etichetta non trovata" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Fotocamera non trovata" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Obiettivo non trovato" + +#: messages.go:131 msgid "Album not found" msgstr "Album non trovato" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Soggetto non trovato" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Persona non trovata" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Faccia non trovata" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Non disponibile in modalità pubblica" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Non disponibile in modalità di sola lettura" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Accedere al proprio account" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Permesso negato" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Pagamento obbligatorio" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "L'upload potrebbe essere offensivo" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Upload fallito" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Nessun elemento selezionato" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Impossibile creare il file, si prega di controllare i permessi" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Impossibile creare la cartella, si prega di controllare i permessi" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Impossibile connettersi, si prega di riprovare" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Inserisci codice di verifca" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Codice di verifica errato, prova di nuovo" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Password non valida, si prega di riprovare" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Funzionalità disabilitata" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Nessuna etichetta selezionata" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Nessun album selezionato" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Nessun file è disponibile per il download" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Impossibile creare il file zip" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Credenziali non valide" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Link non valido" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Nome non valido" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Occupato, si prega di riprovare più tardi" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "L'intervallo di risveglio è %s, ma deve essere pari o inferiore a 1h" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Non è stato possibile collegare l'account" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Troppe richieste" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Stoccaggio insufficiente" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Quota superata" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Registrazione disabilitata" + +#: messages.go:164 +msgid "Verified email required" +msgstr "È necessario un indirizzo e-mail verificato" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Modifiche salvate con successo" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Album creato" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Album salvato" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Album %s eliminato" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "I contenuti dell'album sono stati duplicati" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "File rimosso dallo stack" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "File eliminato" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Selezione aggiunta a %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Un elemento aggiunto a %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d elementi aggiunti a %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Un elemento rimosso da %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d elementi rimossi da %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Account creato" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Account salvato" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Account eliminato" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Impostazioni salvate" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Password cambiata" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Importazione completata in %d secondi" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Importazione cancellata" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indicizzazione completata in %d secondi" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Indicizzando gli originali..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Indicizzazione dei file in %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indicizzazione cancellata" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Rimossi %d file e %d foto" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Spostamento dei file da %s in corso" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Copia dei file da %s in corso" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Etichette eliminate" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Etichetta salvata" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Soggetto salvato" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Soggetto cancellato" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Persona salvata" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Persona cancellata" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "File caricato" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d file caricati in %d secondi" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Elaborazione del caricamento..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Il caricamento è stato elaborato" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Selezione approvata" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Selezione archiviata" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Selezione ripristinata" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Selezione impostata come privata" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Album eliminati" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip creato in %d secondi" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Eliminato permanentemente" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s è stato ripristinato" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Verifica avvenuta con successo" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Attivazione avvenuta con successo" diff --git a/assets/locales/ja/default.po b/assets/locales/ja/default.po index a0705c223..c30334c9e 100644 --- a/assets/locales/ja/default.po +++ b/assets/locales/ja/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" "Last-Translator: DeepL \n" "Language-Team: Japanese \n" @@ -12,402 +12,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "何かが間違っています。もう一度やり直してください" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "その操作はできません" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "変更を保存できませんでした" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "削除できませんでした" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s は既に存在します" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "見つかりませんでした" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "ファイルが見つかりませんでした" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "ファイルが大きすぎます" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "サポートされていません" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "サポートされていない形式です" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "非対応のフォーマットです" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Originals フォルダーは空です" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "選択した項目は存在しません" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "エンティティが見つかりません" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "アカウントが存在しません" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "ユーザーが存在しません" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "ラベルが存在しません" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "カメラが見つかりません" + +#: messages.go:130 +msgid "Lens not found" +msgstr "レンズが見つからない" + +#: messages.go:131 msgid "Album not found" msgstr "アルバムが存在しません" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "件名が見つかりません" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "人が見つかりません" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "顔を検出できませんでした" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "公開モードでは利用できません" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "読み込み専用モードでは利用できません" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "アカウントにログインしてください" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "アクセスが拒否されました" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "要支払い" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "アップロードされた項目に過激なものが含まれている可能性があります" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "アップロードに失敗しました" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "項目が選択されていません" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "ファイルの作成に失敗しました。権限を確認してください" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "フォルダの作成に失敗しました。権限を確認してください" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "接続できませんでした。もう一度お試しください" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "認証コードを入力してください" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "認証コードが無効です。もう一度お試しください" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "不正なパスワードです。もう一度お試しください" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "機能が無効になりました" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "ラベルが選択されていません" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "アルバムが選択されていません" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "ダウンロードできるファイルはありません" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "zip ファイルの作成に失敗しました" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "正しくない認証情報です" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "正しくないリンクです" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "無効な名前です" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "他の処理中です。後で再試行してください" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "ウェイクアップ間隔は %s ですが、1時間以内で指定する必要があります" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "アカウントに接続できませんでした" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "リクエストが多すぎます" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "ストレージが不足しています" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "ノルマ超過" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "登録が無効になっている" + +#: messages.go:164 +msgid "Verified email required" +msgstr "確認済みのメールアドレスが必要だ" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "変更が正常に保存されました" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "アルバムが作成されました" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "アルバムが保存されました" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "アルバム %s が削除されました" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "アルバムの内容が複製されました" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "スタックからファイルが削除されました" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "ファイルが削除されました" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "選択した項目が %s に追加されました" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "1 件の項目が %s に追加されました" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d 件の項目が %s に追加されました" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "1 件の項目が %s から削除されました" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d 件の項目が %s から削除されました" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "アカウントが作成されました" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "アカウントが保存されました" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "アカウントが削除されました" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "設定が保存されました" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "パスワードが変更されました" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "インポートが %d 秒で完了しました" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "インポートが取り消されました" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "インデックスが %d 秒で完了しました" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "originals をインデックスしています..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "%s 内のファイルをインデックスしています" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "インデックスが取り消されました" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "%d 件のファイルと %d 件の写真が削除されました" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "%s からファイルを移動しています" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "%s からファイルをコピーしています" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "ラベルが削除されました" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "ラベルが保存されました" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "保存対象" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "件名を削除しました" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "保存された人" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "人を削除しました" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "ファイルがアップロードされました" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d 件のファイルを %d 秒でアップロードしました" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "アップロードの処理..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "アップロードが完了しました" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "選択した項目が承認されました" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "選択した項目がアーカイブされました" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "選択した項目が復元されました" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "選択した項目がプライベートに設定されました" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "アルバムが削除されました" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "%d 秒で zip ファイルを作成しました" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "完全に削除されました" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s が復元されました" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "検証に成功しました" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "正常に有効化されました" diff --git a/assets/locales/ko/default.po b/assets/locales/ko/default.po index d9549d987..f9b005989 100644 --- a/assets/locales/ko/default.po +++ b/assets/locales/ko/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" "Last-Translator: DeepL \n" "Language-Team: Korean \n" @@ -12,402 +12,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "문제가 발생했습니다. 다시 시도하세요." -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "그렇게 할 수 없습니다." -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "변경 사항을 저장할 수 없음" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "삭제할 수 없음" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s가 이미 존재함" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "찾을 수 없음" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "파일을 찾을 수 없음" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "파일이 너무 큽니다" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "지원되지 않음" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "지원되지 않는 유형" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "지원되지 않는 형식" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "원본 폴더가 비어 있습니다" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "선택 항목을 찾을 수 없음" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "항목을 찾을 수 없음" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "계정을 찾을 수 없음" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "사용자를 찾을 수 없음" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "라벨을 찾을 수 없음" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "카메라를 찾을 수 없습니다" + +#: messages.go:130 +msgid "Lens not found" +msgstr "렌즈를 찾을 수 없습니다" + +#: messages.go:131 msgid "Album not found" msgstr "앨범을 찾을 수 없음" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "제목을 찾을 수 없음" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "사람을 찾을 수 없음" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "얼굴을 찾을 수 없음" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "공개 모드에서는 사용할 수 없음" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "읽기 전용 모드에서는 사용할 수 없음" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "귀하의 계정에 로그인하십시오" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "권한이 없음" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "결제 필요" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "업로드가 불쾌할 수 있습니다" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "업로드 실패" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "선택된 항목이 없습니다" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "파일 생성에 실패했습니다. 권한을 확인하세요" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "폴더를 만들지 못했습니다. 권한을 확인하세요" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "연결할 수 없습니다. 다시 시도해 주세요" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "인증코드를 입력하세요" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "잘못된 인증 코드입니다. 다시 시도해 주세요." -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "비밀번호가 잘못되었습니다. 다시 시도해 주세요" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "기능 비활성화됨" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "선택한 라벨이 없습니다" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "앨범이 선택되지 않았습니다" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "다운로드할 수 있는 파일이 없습니다" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "zip 파일 생성 실패" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "잘못된 자격 증명" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "유효하지 않은 링크입니다" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "잘못된 이름" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "바쁘니 나중에 다시 시도해 주세요" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "깨우기 간격은 %s이지만 1시간 이하여야 합니다" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "계정을 연결할 수 없습니다" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "너무 많은 요청" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "저장 공간 부족" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "할당량 초과" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "등록이 비활성화되었습니다." + +#: messages.go:164 +msgid "Verified email required" +msgstr "인증된 이메일 주소가 필요합니다" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "변경사항이 성공적으로 저장되었습니다" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "앨범 생성됨" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "앨범 저장됨" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "앨범 %s이(가) 삭제됨" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "복제된 앨범 콘텐츠" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "스택에서 제거된 파일" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "파일이 삭제됨" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "선택 항목이 %s에 추가됨" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "%s에 항목 1개 추가됨" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d 항목이 %s에 추가됨" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "%s에서 항목 1개 삭제됨" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d 항목이 %s에서 제거됨" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "계정 생성됨" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "계정이 저장됨" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "계정 삭제됨" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "설정 저장됨" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "비밀번호 변경됨" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "%d초 후에 가져오기 완료" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "가져오기 취소됨" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "%d초 후에 인덱싱 완료" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "원본 색인 생성 중..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "%s에서 파일 색인 생성" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "인덱싱 취소됨" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "파일 %d개와 사진 %d개를 삭제했습니다" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "%s에서 파일 이동" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "%s에서 파일 복사" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "라벨 삭제됨" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "라벨이 저장되었습니다" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "주제가 저장됨" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "제목 삭제됨" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "사람이 저장됨" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "삭제된 사람" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "업로드된 파일 1개" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d개의 파일이 %d초에 업로드됨" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "업로드 처리 중..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "업로드가 처리되었습니다" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "선택 항목 승인됨" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "선택 항목 보관됨" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "선택 항목 복원됨" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "비공개로 표시된 선택" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "앨범 삭제됨" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "%d초에 생성된 우편번호" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "영구 삭제됨" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s이(가) 복원되었습니다" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "성공적으로 확인되었습니다" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "성공적으로 활성화되었습니다" diff --git a/assets/locales/ku/default.po b/assets/locales/ku/default.po index afc08ba47..b9334a39e 100644 --- a/assets/locales/ku/default.po +++ b/assets/locales/ku/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" "Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Kurdish \n" "Language-Team: none\n" "Language: lt\n" @@ -13,402 +13,418 @@ msgstr "" "Plural-Forms: nplurals=3; plural=(n % 10 == 1 && (n % 100 < 11 || n % 100 > " "19)) ? 0 : ((n % 10 >= 2 && n % 10 <= 9 && (n % 100 < 11 || n % 100 > 19)) ? " "1 : 2);\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Kažkas nepavyko, bandykite dar kartą" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Nepavyksta to padaryti" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Pakeitimų nepavyko išsaugoti" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Negalima ištrinti" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s jau egzistuoja" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Nerasta" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Failo rasti nepavyko" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Per didelis failas" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Nepalaikoma" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Nepalaikomas tipas" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Nepalaikomas formatas" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Originalų aplankas tuščias" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Pasirinkimas nerastas" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Subjektas nerastas" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Paskyra nerasta" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Vartotojas nerastas" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Etiketė nerasta" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Kameros nerasta" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Objektyvas nerastas" + +#: messages.go:131 msgid "Album not found" msgstr "Albumas nerastas" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Tema nerasta" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Asmuo nerastas" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Veidas nerastas" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Negalima naudoti viešuoju režimu" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Negalima naudoti tik skaitymo režimu" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Prisijunkite prie savo paskyros" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Priėjimas neimanomas" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Reikalingas mokėjimas" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Įkėlimas gali būti įžeidžiantis" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Įkelti nepavyko" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Nėra pasirinktų elementų" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Nepavyko sukurti failo, patikrinkite leidimus" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Nepavyko sukurti aplanko, patikrinkite leidimus" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Nepavyko prisijungti, bandykite dar kartą" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Įveskite patvirtinimo kodą" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Neteisingas patvirtinimo kodas, bandykite dar kartą" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Netinkamas slaptažodis, bandykite dar kartą" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Funkcija išjungta" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Nėra pasirinktų etikečių" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Nėra pasirinktų albumų" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Nėra parsisiunčiamų failų" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Nepavyko sukurti zip failo" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Neteisingi įgaliojimai" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Netinkama nuoroda" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Netinkamas pavadinimas" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Užimta, bandykite vėliau" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Budinimo intervalas yra %s, bet turi būti ne ilgesnis kaip 1 val" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Nepavyko prisijungti prie jūsų paskyros" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Per daug prašymų" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Nepakankama saugykla" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Viršyta kvota" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Registracija išjungta" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Reikalingas patvirtintas el. pašto adresas" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Pakeitimai sėkmingai išsaugoti" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Sukurtas albumas" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Išsaugotas albumas" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Albumas %s pašalintas" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Klonuotas albumo turinys" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Failas pašalintas iš kamino" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Ištrintas failas" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Pasirinkimas pridėtas prie %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Vienas įrašas pridėtas prie %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d įrašai, įtraukti į %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Vienas įrašas pašalintas iš %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d įrašai pašalinti iš %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Sukurta paskyra" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Išsaugota paskyra" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Ištrinta paskyra" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Nustatymai išsaugoti" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Slaptažodis pakeistas" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Importas baigtas per %d s" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Importas atšauktas" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indeksavimas baigtas per %d s" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Originalų indeksavimas..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Failų indeksavimas %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indeksavimas atšauktas" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Pašalinti %d failai ir %d nuotraukos" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Failų perkėlimas iš %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Failų kopijavimas iš %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Ištrintos etiketės" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Išsaugota etiketė" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Tema - išsaugotas" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Išbrauktas objektas" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Išsaugotas asmuo" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Išbrauktas asmuo" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Įkeltas failas" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d failai įkelti per %d s" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Įkėlimo apdorojimas..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Įkėlimas apdorotas" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Patvirtinta atranka" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Atranka archyvuota" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Atkurta atranka" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Atranka pažymėta kaip privati" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Ištrinti albumai" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip sukurta %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Visam laikui ištrintas" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s buvo atkurta" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Sėkmingai patvirtinta" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Sėkmingai suaktyvinta" diff --git a/assets/locales/lv/default.po b/assets/locales/lv/default.po index d629e9d32..c50319237 100644 --- a/assets/locales/lv/default.po +++ b/assets/locales/lv/default.po @@ -7,9 +7,10 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2026-01-15 09:02+0000\n" -"Last-Translator: Janis Eglitis \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" "Language: lv\n" "MIME-Version: 1.0\n" @@ -17,401 +18,417 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n % 10 == 0 || n % 100 >= 11 && n % 100 <= " "19) ? 0 : ((n % 10 == 1 && n % 100 != 11) ? 1 : 2);\n" -"X-Generator: Weblate 5.15.1\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Kaut kas nogāja greizi, mēģiniet vēlreiz" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "To nevar izdarīt" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Izmaiņas nevarēja saglabāt" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Nevarēja izdzēst" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s jau pastāv" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Nav atrasts" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Fails nav atrasts" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Fails ir pārāk liels" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Neatbalstīts" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Neatbalstīts tips" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Neatbalstīts formāts" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Oriģinālu mape ir tukša" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Izvēle nav atrasta" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Vienība nav atrasta" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Konts nav atrasts" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Lietotājs nav atrasts" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Birka nav atrasta" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Kamera nav atrasta" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Objektīvs nav atrasts" + +#: messages.go:131 msgid "Album not found" msgstr "Albums nav atrasts" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Tēma nav atrasta" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Persona nav atrasta" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Seja nav atrasta" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Nav pieejams publiskajā režīmā" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Nav pieejams lasīšanas režīmā" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Lūdzu, piesakieties savā kontā" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Atļauja liegta" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Nepieciešams maksājums" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Augšupielāde varētu būt aizskaroša" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Augšupielāde neizdevās" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Nav izvēlēts neviens ieraksts" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Neizdevās izveidot failu, lūdzu, pārbaudiet atļaujas" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Neizdevās izveidot mapi, lūdzu, pārbaudiet atļaujas" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Nevarēja izveidot savienojumu, lūdzu, mēģiniet vēlreiz" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Ievadiet verifikācijas kodu" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Nederīgs verifikācijas kods, lūdzu, mēģiniet vēlreiz" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Nederīga parole, lūdzu, mēģiniet vēlreiz" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Funkcionalitāte ir izslēgta" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Nav atlasītas nevienas birkas" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Nav atlasīts neviens albums" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Nav lejupielādei pieejamu failu" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Neizdevās izveidot zip failu" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Nederīgs lietotājvārds vai parole" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Nederīga saite" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Nederīgs nosaukums" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Aizņemts, lūdzu, mēģiniet vēlreiz vēlāk" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Pamošanās intervāls ir %s, bet tam jābūt 1 h vai mazākam" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Jūsu kontu nevarēja savienot" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Pārāk daudz pieprasījumu" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Nepietiek brīvas vietas" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Kvota pārsniegta" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Reģistrācija atspējota" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Nepieciešama verificēta e-pasta adrese" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Izmaiņas veiksmīgi saglabātas" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Albums izveidots" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Albums saglabāts" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Albums %s ir dzēsts" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Albuma saturs ir dublēts" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Fails izņemts no saraksta" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Fails izdzēsts" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Atlasījums pievienots %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Viens ieraksts pievienots %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d ieraksti pievienoti %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Viens ieraksts noņemts no %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d ieraksti noņemti no %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Konts izveidots" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Konts saglabāts" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Konts ir dzēsts" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Iestatījumi saglabāti" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Parole nomainīta" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Importēšana pabeigta %d s laikā" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Importēšana atcelta" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indeksēšana pabeigta %d s laikā" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Notiek oriģinālu indeksēšana..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Notiek failu indeksēšana %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indeksēšana atcelta" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Noņemti %d faili un %d fotoattēli" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Failu pārvietošana no %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Failu kopēšana no %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Birkas ir dzēstas" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Birka saglabāta" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Tēma saglabāta" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Tēma dzēsta" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Persona saglabāta" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Persona dzēsta" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Fails augšupielādēts" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d faili augšupielādēti %d sekundēs" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Notiek augšupielādes apstrāde..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Augšupielāde ir apstrādāta" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Atlase apstiprināta" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Atlase arhivēta" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Atlase atjaunota" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Izvēle atzīmēta kā privāta" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Albumi ir dzēsti" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "ZIP fails izveidots %d sekundēs" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Neatgriezeniski dzēsts" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s ir atjaunots" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Veiksmīgi verificēts" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Veiksmīgi aktivizēts" diff --git a/assets/locales/messages.pot b/assets/locales/messages.pot index e5b61e355..d6e4d5e67 100644 --- a/assets/locales/messages.pot +++ b/assets/locales/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,399 +17,415 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "" -#: messages.go:121 -msgid "Album not found" -msgstr "" - -#: messages.go:122 -msgid "Subject not found" -msgstr "" - -#: messages.go:123 -msgid "Person not found" -msgstr "" - -#: messages.go:124 -msgid "Face not found" -msgstr "" - -#: messages.go:125 -msgid "Not available in public mode" -msgstr "" - -#: messages.go:126 -msgid "Not available in read-only mode" -msgstr "" - -#: messages.go:127 -msgid "Please log in to your account" -msgstr "" - -#: messages.go:128 -msgid "Permission denied" -msgstr "" - #: messages.go:129 -msgid "Payment required" +msgid "Camera not found" msgstr "" #: messages.go:130 -msgid "Upload might be offensive" +msgid "Lens not found" msgstr "" #: messages.go:131 -msgid "Upload failed" +msgid "Album not found" msgstr "" #: messages.go:132 -msgid "No items selected" +msgid "Subject not found" msgstr "" #: messages.go:133 -msgid "Failed creating file, please check permissions" +msgid "Person not found" msgstr "" #: messages.go:134 -msgid "Failed creating folder, please check permissions" +msgid "Face not found" msgstr "" #: messages.go:135 -msgid "Could not connect, please try again" +msgid "Not available in public mode" msgstr "" #: messages.go:136 -msgid "Enter verification code" +msgid "Not available in read-only mode" msgstr "" #: messages.go:137 -msgid "Invalid verification code, please try again" +msgid "Please log in to your account" msgstr "" #: messages.go:138 -msgid "Invalid password, please try again" +msgid "Permission denied" msgstr "" #: messages.go:139 -msgid "Feature disabled" +msgid "Payment required" msgstr "" #: messages.go:140 -msgid "No labels selected" +msgid "Upload might be offensive" msgstr "" #: messages.go:141 -msgid "No albums selected" +msgid "Upload failed" msgstr "" #: messages.go:142 -msgid "No files available for download" +msgid "No items selected" msgstr "" #: messages.go:143 -msgid "Failed to create zip file" +msgid "Failed creating file, please check permissions" msgstr "" #: messages.go:144 -msgid "Invalid credentials" +msgid "Failed creating folder, please check permissions" msgstr "" #: messages.go:145 -msgid "Invalid link" +msgid "Could not connect, please try again" msgstr "" #: messages.go:146 -msgid "Invalid name" +msgid "Enter verification code" msgstr "" #: messages.go:147 -msgid "Busy, please try again later" +msgid "Invalid verification code, please try again" msgstr "" #: messages.go:148 -#, c-format -msgid "The wakeup interval is %s, but must be 1h or less" +msgid "Invalid password, please try again" msgstr "" #: messages.go:149 -msgid "Your account could not be connected" +msgid "Feature disabled" msgstr "" #: messages.go:150 -msgid "Too many requests" +msgid "No labels selected" msgstr "" #: messages.go:151 -msgid "Insufficient storage" +msgid "No albums selected" msgstr "" #: messages.go:152 -msgid "Quota exceeded" +msgid "No files available for download" +msgstr "" + +#: messages.go:153 +msgid "Failed to create zip file" +msgstr "" + +#: messages.go:154 +msgid "Invalid credentials" msgstr "" #: messages.go:155 -msgid "Changes successfully saved" +msgid "Invalid link" msgstr "" #: messages.go:156 -msgid "Album created" +msgid "Invalid name" msgstr "" #: messages.go:157 -msgid "Album saved" +msgid "Busy, please try again later" msgstr "" #: messages.go:158 #, c-format -msgid "Album %s deleted" +msgid "The wakeup interval is %s, but must be 1h or less" msgstr "" #: messages.go:159 -msgid "Album contents cloned" +msgid "Your account could not be connected" msgstr "" #: messages.go:160 -msgid "File removed from stack" +msgid "Too many requests" msgstr "" #: messages.go:161 -msgid "File deleted" +msgid "Insufficient storage" msgstr "" #: messages.go:162 -#, c-format -msgid "Selection added to %s" +msgid "Quota exceeded" msgstr "" #: messages.go:163 -#, c-format -msgid "One entry added to %s" +msgid "Registration disabled" msgstr "" #: messages.go:164 -#, c-format -msgid "%d entries added to %s" -msgstr "" - -#: messages.go:165 -#, c-format -msgid "One entry removed from %s" -msgstr "" - -#: messages.go:166 -#, c-format -msgid "%d entries removed from %s" +msgid "Verified email required" msgstr "" #: messages.go:167 -msgid "Account created" +msgid "Changes successfully saved" msgstr "" #: messages.go:168 -msgid "Account saved" +msgid "Album created" msgstr "" #: messages.go:169 -msgid "Account deleted" +msgid "Album saved" msgstr "" #: messages.go:170 -msgid "Settings saved" +#, c-format +msgid "Album %s deleted" msgstr "" #: messages.go:171 -msgid "Password changed" +msgid "Album contents cloned" msgstr "" #: messages.go:172 -#, c-format -msgid "Import completed in %d s" +msgid "File removed from stack" msgstr "" #: messages.go:173 -msgid "Import canceled" +msgid "File deleted" msgstr "" #: messages.go:174 #, c-format -msgid "Indexing completed in %d s" +msgid "Selection added to %s" msgstr "" #: messages.go:175 -msgid "Indexing originals..." +#, c-format +msgid "One entry added to %s" msgstr "" #: messages.go:176 #, c-format -msgid "Indexing files in %s" +msgid "%d entries added to %s" msgstr "" #: messages.go:177 -msgid "Indexing canceled" +#, c-format +msgid "One entry removed from %s" msgstr "" #: messages.go:178 #, c-format -msgid "Removed %d files and %d photos" +msgid "%d entries removed from %s" msgstr "" #: messages.go:179 -#, c-format -msgid "Moving files from %s" +msgid "Account created" msgstr "" #: messages.go:180 -#, c-format -msgid "Copying files from %s" +msgid "Account saved" msgstr "" #: messages.go:181 -msgid "Labels deleted" +msgid "Account deleted" msgstr "" #: messages.go:182 -msgid "Label saved" +msgid "Settings saved" msgstr "" #: messages.go:183 -msgid "Subject saved" +msgid "Password changed" msgstr "" #: messages.go:184 -msgid "Subject deleted" +#, c-format +msgid "Import completed in %d s" msgstr "" #: messages.go:185 -msgid "Person saved" +msgid "Import canceled" msgstr "" #: messages.go:186 -msgid "Person deleted" +#, c-format +msgid "Indexing completed in %d s" msgstr "" #: messages.go:187 -msgid "File uploaded" +msgid "Indexing originals..." msgstr "" #: messages.go:188 #, c-format -msgid "%d files uploaded in %d s" +msgid "Indexing files in %s" msgstr "" #: messages.go:189 -msgid "Processing upload..." +msgid "Indexing canceled" msgstr "" #: messages.go:190 -msgid "Upload has been processed" +#, c-format +msgid "Removed %d files and %d photos" msgstr "" #: messages.go:191 -msgid "Selection approved" +#, c-format +msgid "Moving files from %s" msgstr "" #: messages.go:192 -msgid "Selection archived" +#, c-format +msgid "Copying files from %s" msgstr "" #: messages.go:193 -msgid "Selection restored" +msgid "Labels deleted" msgstr "" #: messages.go:194 -msgid "Selection marked as private" +msgid "Label saved" msgstr "" #: messages.go:195 -msgid "Albums deleted" +msgid "Subject saved" msgstr "" #: messages.go:196 +msgid "Subject deleted" +msgstr "" + +#: messages.go:197 +msgid "Person saved" +msgstr "" + +#: messages.go:198 +msgid "Person deleted" +msgstr "" + +#: messages.go:199 +msgid "File uploaded" +msgstr "" + +#: messages.go:200 +#, c-format +msgid "%d files uploaded in %d s" +msgstr "" + +#: messages.go:201 +msgid "Processing upload..." +msgstr "" + +#: messages.go:202 +msgid "Upload has been processed" +msgstr "" + +#: messages.go:203 +msgid "Selection approved" +msgstr "" + +#: messages.go:204 +msgid "Selection archived" +msgstr "" + +#: messages.go:205 +msgid "Selection restored" +msgstr "" + +#: messages.go:206 +msgid "Selection marked as private" +msgstr "" + +#: messages.go:207 +msgid "Albums deleted" +msgstr "" + +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "" diff --git a/assets/locales/ms/default.po b/assets/locales/ms/default.po index 3ce9fa2cb..fd02b78cb 100644 --- a/assets/locales/ms/default.po +++ b/assets/locales/ms/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" "Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" @@ -12,402 +12,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Kesilapan telah berlaku, cuba lagi" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Tidak mampu berbuat demikian" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Perubahan tidak dapat disimpan" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Tidak dapat dipadamkan" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s sudah wujud" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Tidak ditemui" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Fail tidak dijumpai" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Fail terlalu besar" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Tidak disokong" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Jenis tidak disokong" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Format yang tidak disokong" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Folder asal kosong" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Pilihan tidak ditemui" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Entiti tidak ditemui" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "akaun tidak dijumpai" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Pengguna tidak dijumpai" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Label tidak ditemui" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Kamera tidak ditemui" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Lensa tidak ditemui" + +#: messages.go:131 msgid "Album not found" msgstr "Album tidak ditemui" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Subjek tidak ditemui" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Orang tidak ditemui" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Wajah tidak ditemui" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Tidak tersedia dalam mod awam" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Tidak tersedia dalam mod baca sahaja" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Sila log masuk ke akaun anda" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Kebenaran ditolak" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Bayaran diperlukan" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Muat naik mungkin menyinggung perasaan" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Muat naik gagal" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Tiada item dipilih" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Gagal membuat fail, sila semak kebenaran" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Gagal membuat folder, sila semak kebenaran" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Tidak dapat menyambung, sila cuba lagi" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Masukkan kod pengesahan" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Kod pengesahan tidak sah, sila cuba lagi" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Kata laluan tidak sah, sila cuba lagi" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Ciri dilumpuhkan" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Tiada label dipilih" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Tiada album dipilih" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Tiada fail tersedia untuk dimuat turun" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Gagal membuat fail zip" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Bukti kelayakan tidak sah" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Pautan tidak sah" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Nama tidak sah" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Sibuk, sila cuba lagi nanti" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Selang bangun ialah %s, tetapi mestilah 1j atau kurang" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Akaun anda tidak dapat disambungkan" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Terlalu banyak permintaan" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Storan tidak mencukupi" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Kuota melebihi" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Pendaftaran dilumpuhkan" + +#: messages.go:164 +msgid "Verified email required" +msgstr "E-mel yang disahkan diperlukan" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Perubahan berjaya disimpan" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Album dibuat" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Album disimpan" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Album %s dipadamkan" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Kandungan album diklon" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Fail dialih keluar daripada timbunan" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Fail dipadamkan" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Pilihan ditambahkan pada %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Satu entri ditambahkan pada %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "Entri %d ditambahkan pada %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Satu entri dialih keluar daripada %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d entri dialih keluar daripada %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Akaun dibuat" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Akaun disimpan" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Akaun dipadamkan" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Tetapan Disimpan" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Kata laluan ditukar" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Import selesai dalam %d s" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Import dibatalkan" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Pengindeksan selesai dalam %d s" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Mengindeks asal..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Mengindeks fail dalam %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Pengindeksan dibatalkan" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Mengalih keluar fail %d dan foto %d." -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Memindahkan fail dari %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Menyalin fail daripada %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Label dipadamkan" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Label disimpan" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Subjek disimpan" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Subjek dipadamkan" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Orang yang diselamatkan" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Orang dipadamkan" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Fail dimuat naik" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "Fail %d dimuat naik dalam %d s" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Memproses muat naik..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Muat naik telah diproses" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Pemilihan diluluskan" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Pemilihan diarkibkan" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Pemilihan dipulihkan" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Pilihan ditandakan sebagai peribadi" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Album dipadamkan" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip dibuat dalam %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Dipadamkan secara kekal" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s telah dipulihkan" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Berjaya disahkan" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Berjaya diaktifkan" diff --git a/assets/locales/nb/default.po b/assets/locales/nb/default.po index 4163f3e9d..ffda6d942 100644 --- a/assets/locales/nb/default.po +++ b/assets/locales/nb/default.po @@ -2,9 +2,10 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Norwegian Bokmål \n" "Language: nb\n" @@ -12,402 +13,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Noe gikk galt, prøv igjen" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Ikke i stand til å gjøre det" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Kan ikke lagre endringer" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Kan ikke slettes" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s eksisterer allerede" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Ikke funnet" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Fil ikke funnet" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Filen er for stor" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Ustøttet" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Ikke støttet type" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Ikke støttet format" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Originaler-mappen er tom" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Finner ikke utvalg" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Enheten ble ikke funnet" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Konto ikke funnet" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Bruker ikke funnet" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Merkelapp ikke funnet" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Kameraet ble ikke funnet" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Objektivet ble ikke funnet" + +#: messages.go:131 msgid "Album not found" msgstr "Album ikke funnet" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Emnet ble ikke funnet" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Person ikke funnet" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Ansikt ikke funnet" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Ikke tilgjengelig i offentlig modus" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "ikke tilgjengelig i skrivebeskyttet modus" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Logg inn på kontoen din" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Ingen tilgang" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Betaling kreves" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Opplastingen kan være støtende" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Opplasting mislyktes" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Ingen elementer valgt" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Kunne ikke opprette fil, vennligst sjekk tillatelser" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Kunne ikke opprette mappe, vennligst sjekk tillatelser" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Kunne ikke koble til, vennligst prøv igjen" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Angi verifikasjonskode" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Ugyldig bekreftelseskode. Prøv igjen" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Ugyldig passord, vennligst prøv igjen" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Tjeneste deaktivert" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Ingen merkelapper valgt" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Ingen albumer valgt" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Ingen filer tilgjengelig for nedlasting" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Kunne ikke opprette zip-arkiv" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Ugyldige innloggingsdetaljer" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Ugyldig lenke" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Ugyldig navn" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Opptatt. Prøv igjen senere" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Oppvåkningsintervallet er %s, men må være 1 time eller mindre" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Kontoen din kunne ikke kobles til" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "For mange forespørsler" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Utilstrekkelig lagringsplass" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Kvote overskredet" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Registrering deaktivert" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Bekreftet e-post kreves" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Endringene ble lagret" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Album opprettet" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Album lagret" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Album %s slettet" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Albuminnhold duplisert" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Fil fjernet fra samling" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Fil slettet" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Utvalg lagt til %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "En oppføring lagt til %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d oppføringer lagt til %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "En oppføring fjernet fra %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d oppføringer fjernet fra %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Konto opprettet" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Konto lagret" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Konto slettet" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Innstillinger lagret" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Passord endret" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Import fullført på %d s" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Import avbrutt" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indeksering fullført på %d s" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Indekserer originaler…" -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Indekserer filer i %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indeksering avbrutt" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Fjernet %d filer og %d foto" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Flytter filer fra %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Kopierer filer fra %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Merkelapper slettet" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Merkelapper lagret" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Emnet er lagret" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Emnet er slettet" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Person reddet" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Person slettet" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Fil lastet opp" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d filer lastet opp på %d s" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Behandler opplasting..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Opplastingen er behandlet" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Utvalg godkjent" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Utvalg arkivert" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Utvalg gjenopprettet" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Utvalg markert som privat" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Album slettet" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip opprettet på %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Permanent slettet" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s har blitt gjenopprettet" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Vellykket verifisert" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Vellykket aktivert" diff --git a/assets/locales/nl/default.po b/assets/locales/nl/default.po index 505e5b8ca..ab630b315 100644 --- a/assets/locales/nl/default.po +++ b/assets/locales/nl/default.po @@ -2,9 +2,10 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Dutch \n" "Language: nl\n" @@ -12,402 +13,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Er ging iets mis, probeer het opnieuw" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Dat kan niet" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Wijzigingen kunnen niet worden opgeslagen" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Kan niet verwijderd worden" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s bestaat al" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Niet gevonden" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Bestand niet gevonden" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Bestand te groot" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Niet ondersteund" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Niet-ondersteund type" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Niet ondersteund formaat" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "De map Originelen is leeg" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Selectie niet gevonden" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Entiteit niet gevonden" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Account niet gevonden" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Gebruiker niet gevonden" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Label niet gevonden" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Camera niet gevonden" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Lens niet gevonden" + +#: messages.go:131 msgid "Album not found" msgstr "Album niet gevonden" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Onderwerp niet gevonden" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Persoon niet gevonden" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Gezicht niet gevonden" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Niet beschikbaar in publieke modus" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Niet beschikbaar in alleen-lezen modus" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Log in op je account" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Toegang geweigerd" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Betaling vereist" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Upload kan aanstootgevend zijn" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Uploaden mislukt" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Geen items geselecteerd" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Bestand aanmaken mislukt, controleer alstublieft de rechten" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Folder aanmaken mislukt, controleer alstublieft de rechten" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Kan niet verbinden, probeer alstublieft opnieuw" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Verificatiecode invoeren" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Ongeldige verificatiecode. Probeer het opnieuw" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Fout wachtwoord, probeer alstublieft opnieuw" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Functie uitgeschakeld" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Geen labels geselecteerd" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Geen albums geselecteerd" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Geen bestanden beschikbaar om te downloaden" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Maken van zip-bestand is mislukt" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Ongeldige inloggegevens" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Ongeldige link" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Ongeldige mapnaam" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Bezet, probeer het later nog eens" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Het wekinterval is %s, maar moet 1 uur of minder zijn" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Uw account kon niet worden aangesloten" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Te veel verzoeken" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Onvoldoende opslag" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Quota overschreden" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Registratie uitgeschakeld" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Geverifieerd e-mailadres vereist" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Wijzigingen succesvol opgeslagen" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Album aangemaakt" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Album opgeslagen" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Album %s verwijderd" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Albuminhoud gekopieerd" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Bestand uit stapel verwijderd" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Bestand verwijderd" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Selectie toegevoegd aan %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Eén item toegevoegd aan %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d items toegevoegd aan %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Eén item verwijderd uit %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d items verwijderd uit %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Account aangemaakt" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Account opgeslagen" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Account verwijderd" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Instellingen opgeslagen" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Wachtwoord gewijzigd" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Importeren voltooid in %d s" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Importeren geannuleerd" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indexeren voltooid in %d s" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Originelen indexeren…" -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Bestanden indexeren in %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indexeren geannuleerd" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "%d bestanden en %d foto’s verwijderd" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Bestanden verplaatsen uit %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Bestanden kopiëren uit %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Labels verwijderd" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Labels opgeslagen" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Onderwerp opgeslagen" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Onderwerp verwijderd" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Persoon gered" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Persoon verwijderd" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Bestand geüpload" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d bestanden geüpload in %d s" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Verwerking upload..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Upload is verwerkt" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Selectie goedgekeurd" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Selectie gearchiveerd" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Selectie hersteld" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Selectie gemarkeerd als privé" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Albums verwijderd" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip gemaakt in %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Permanent verwijderd" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s is hersteld" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Met succes geverifieerd" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Met succes geactiveerd" diff --git a/assets/locales/pl/default.po b/assets/locales/pl/default.po index 8df2c89ee..6f13d5eb2 100644 --- a/assets/locales/pl/default.po +++ b/assets/locales/pl/default.po @@ -2,9 +2,10 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Polish \n" "Language: pl\n" @@ -13,404 +14,420 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Coś poszło nie tak, spróbuj jeszcze raz" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Nie da się tego zrobić" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Nie można zapisać zmian" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Nie można usunąć" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s już istnieje" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Nie znaleziono" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Plik nie został znaleziony" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Plik jest zbyt duży" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Nieobsługiwane" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Nieobsługiwany typ" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Nieobsługiwany format" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Folder oryginałów jest pusty" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Nie znaleziono wyboru" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Nie znaleziono podmiotu" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Konto nie znalezione" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Użytkownik nie znaleziony" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Etykieta nie została odnaleziona" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Nie znaleziono kamery" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Nie znaleziono obiektywu" + +#: messages.go:131 msgid "Album not found" msgstr "Album nie został znaleziony" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Temat nie został znaleziony" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Osoba nie została znaleziona" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Twarz nie została znaleziona" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Niedostępne w trybie publicznym" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Niedostępne w trybie tylko do odczytu" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Proszę zalogować się na swoje konto" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Brak uprawnień" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Wymagana płatność" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Przesyłane dane mogą być obraźliwe" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Przesyłanie nie powiodło się" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Nie wybrano żadnych elementów" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Nie można utworzyć pliku, sprawdź uprawnienia" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Nie można utworzyć folderu, sprawdź uprawnienia" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Nie można się połączyć, spróbuj ponownie" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Wprowadź kod weryfikacyjny" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Nieprawidłowy kod weryfikacyjny. Spróbuj ponownie" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Nieprawidłowe hasło, spróbuj ponownie" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Funkcja wyłączona" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Nie wybrano etykiet" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Nie wybrano albumów" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Brak plików do pobrania" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Nie udało się utworzyć pliku zip" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Nieprawidłowe dane logowania" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Nieprawidłowy link" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Nieprawidłowa nazwa" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Zajęty, spróbuj ponownie później" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "" "Interwał wybudzenia %s jest nieprawidłowy, powinien być równy lub mniejszy " "niż 1 godzina" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Twoje konto nie może być podłączone" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Zbyt wiele żądań" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Niewystarczająca pamięć" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Przekroczony limit" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Rejestracja wyłączona" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Wymagany zweryfikowany adres e-mail" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Zmiany zostały pomyślnie zapisane" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Album został utworzony" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Album został zapisany" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Album %s został usunięty" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Album został sklonowany" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Plik został rozgrupowany" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Plik został usunięty" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Wybór dodany do %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Dodano jeden wpis do %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d wpisy dodane do %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Usunięto jeden wpis z %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d wpisy usunięte z %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Konto utworzone" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Konto zapisane" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Konto usunięte" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Ustawienia zapisane" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Hasło zostało zmienione" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Import zakończony w %d s" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Import został anulowany" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indeksowanie zakończone w %d s" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Indeksowanie oryginałów…" -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Indeksowanie plików w %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indeksowanie anulowane" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Usunięto %d plików i %d zdjęć" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Przenoszenie plików z %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Kopiowanie plików z %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Usunięto etykiety" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Etykieta zapisana" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Przedmiot zapisany" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Przedmiot usunięty" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Osoba zapisana" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Osoba usunięta" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Przesłany plik" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d plików przesłano w %d s" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Przetwarzanie uploadu..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Przesyłanie zostało przetworzone" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Wybór zatwierdzony" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Wybór zarchiwizowany" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Wybór został przywrócony" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Wybór oznaczony jako prywatny" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Albumy zostały usunięte" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip utworzony w %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Trwale usunięty" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s zostało przywrócone" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Pomyślnie zweryfikowano" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Pomyślnie aktywowano" diff --git a/assets/locales/pt/default.po b/assets/locales/pt/default.po index cfaf6f910..1420728b7 100644 --- a/assets/locales/pt/default.po +++ b/assets/locales/pt/default.po @@ -2,9 +2,10 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Portuguese \n" "Language: pt\n" @@ -12,402 +13,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Algo correu mal, tente novamente" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Incapaz de fazer isso" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "As mudanças não foram salvas" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Não foi possível excluir" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s já existe" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Não encontrado" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Arquivo não encontrado" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Arquivo muito grande" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Não compatível" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Tipo não suportado" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Formato sem suporte" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "A pasta dos originais está vazia" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Seleção não encontrada" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Entidade não encontrada" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Conta não encontrada" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Usuário não encontrado" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Etiqueta não encontrada" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Não foi encontrada nenhuma câmara" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Lente não encontrada" + +#: messages.go:131 msgid "Album not found" msgstr "Álbum não encontrado" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Assunto não encontrado" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Pessoa não encontrada" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Rosto não encontrado" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Indisponível em modo público" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Não disponível no modo somente leitura" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Faça o login em sua conta" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Permissão negada" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Pagamento obrigatório" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Envio pode ser ofensivo" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Envio falhou" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Sem itens selecionados" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Falha ao criar arquivo, por favor cheque as permissões" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Falha ao criar pasta, por favor cheque as permissões" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Não foi possível conectar, por favor tente novamente" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Digite o código de verificação" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Código de verificação inválido, tente novamente" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Senha inválida, por favor tente novamente" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Recurso Desativado" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Sem etiquetas selecionadas" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Sem álbuns selecionados" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Sem arquivos disponíveis para baixar" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Falha ao criar arquivo zip" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Credenciais inválidas" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Link inválido" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Nome inválido" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Em uso, por favor tente novamente mais tarde" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "O intervalo de despertar é %s, mas deve ser de 1h ou menos" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Sua conta não pôde ser conectada" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Demasiados pedidos" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Armazenamento insuficiente" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Quota excedida" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Cadastro desativado" + +#: messages.go:164 +msgid "Verified email required" +msgstr "É necessário um e-mail verificado." + +#: messages.go:167 msgid "Changes successfully saved" msgstr "As mudanças foram salvas com sucesso" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Álbum criado" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Álbum salvo" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Álbum %s excluído" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Conteúdo do álbum copiado" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Arquivo removido da pilha" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Arquivo excluído" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Seleção adicionada a %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Uma entrada adicionada a %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d entradas adicionadas a %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Uma entrada removida de %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d entradas removidas de %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Conta criada" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Conta salva" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Conta excluída" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Configurações salvas" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Senha alterada" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Importação completa em %d" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Importação cancelada" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indexação completa em %d" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Indexando originais..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Indexando arquivos em %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indexação cancelada" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Removidos %d arquivos e %d fotos" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Movendo arquivos de %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Copiando arquivos de %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Etiquetas excluídas" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Etiqueta salva" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Assunto salvo" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Assunto eliminado" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Pessoa salva" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Pessoa apagada" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Arquivo carregado" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d arquivos enviados em %d" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "A processar carregamento..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "O Upload foi processado" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Seleção aprovada" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Seleção arquivada" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Seleção restaurada" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Seleção marcada como privada" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Álbuns excluídos" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip criado em %d" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Permanentemente excluídas" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s foi restaurado" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Verificado com sucesso" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Ativado com sucesso" diff --git a/assets/locales/pt_BR/default.po b/assets/locales/pt_BR/default.po index 5138e6ae0..1b9c612e9 100644 --- a/assets/locales/pt_BR/default.po +++ b/assets/locales/pt_BR/default.po @@ -2,9 +2,10 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\n" @@ -12,402 +13,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Algo deu errado, tente novamente" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Incapaz de fazer isso" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "As mudanças não foram salvas" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Não foi possível excluir" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s já existe" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Não encontrado" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Arquivo não encontrado" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Arquivo muito grande" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Não compatível" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Tipo não suportado" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Formato sem suporte" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "A pasta dos originais está vazia" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Seleção não encontrada" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Entidade não encontrada" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Conta não encontrada" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Usuário não encontrado" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Etiqueta não encontrada" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Câmera não encontrada" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Lente não encontrada" + +#: messages.go:131 msgid "Album not found" msgstr "Álbum não encontrado" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Assunto não encontrado" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Pessoa não encontrada" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Rosto não encontrado" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Indisponível em modo público" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Não disponível no modo somente leitura" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Faça o login em sua conta" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Permissão negada" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Pagamento obrigatório" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Envio pode ser ofensivo" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Envio falhou" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Sem itens selecionados" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Falha ao criar arquivo, por favor cheque as permissões" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Falha ao criar pasta, por favor cheque as permissões" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Não foi possível conectar, por favor tente novamente" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Digite o código de verificação" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Código de verificação inválido, tente novamente" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Senha inválida, por favor tente novamente" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Recurso Desativado" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Sem etiquetas selecionadas" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Sem álbuns selecionados" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Sem arquivos disponíveis para baixar" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Falha ao criar arquivo zip" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Credenciais inválidas" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Link inválido" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Nome inválido" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Ocupado, por favor tente mais tarde" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "O intervalo de despertar é %s, mas deve ser de 1h ou menos" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Sua conta não pôde ser conectada" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Muitas solicitações" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Armazenamento insuficiente" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Cota excedida" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Cadastro desativado" + +#: messages.go:164 +msgid "Verified email required" +msgstr "É necessário um e-mail verificado." + +#: messages.go:167 msgid "Changes successfully saved" msgstr "As mudanças foram salvas com sucesso" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Álbum criado" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Álbum salvo" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Álbum %s excluído" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Conteúdo do álbum copiado" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Arquivo removido da pilha" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Arquivo excluído" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Seleção adicionada a %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Uma entrada adicionada a %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d entradas adicionadas a %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Uma entrada removida de %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d entradas removidas de %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Conta criada" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Conta salva" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Conta excluída" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Configurações salvas" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Senha alterada" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Importação completa em %d" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Importação cancelada" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indexação completa em %d" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Indexando originais..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Indexando arquivos em %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indexação cancelada" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Removidos %d arquivos e %d fotos" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Movendo arquivos de %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Copiando arquivos de %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Etiquetas excluídas" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Etiqueta salva" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Assunto salvo" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Assunto eliminado" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Pessoa salva" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Pessoa apagada" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Arquivo carregado" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d arquivos enviados em %d" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Processamento de upload..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "O Upload foi processado" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Seleção aprovada" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Seleção arquivada" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Seleção restaurada" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Seleção marcada como privada" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Álbuns excluídos" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip criado em %d" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Permanentemente excluídas" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s foi restaurado" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Verificado com sucesso" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Ativado com sucesso" diff --git a/assets/locales/ro/default.po b/assets/locales/ro/default.po index 2ede4f6fd..d39ebbe00 100644 --- a/assets/locales/ro/default.po +++ b/assets/locales/ro/default.po @@ -2,9 +2,10 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Romanian \n" "Language: ro\n" @@ -13,402 +14,418 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < " "20)) ? 1 : 2;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Ceva nu a mers bine, încercați din nou" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Nu se poate face asta" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Modificările nu au putut fi salvate" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Nu a putut fi șters" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s deja există" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Nu a fost găsit" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Fișier nedescoperit" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Fișier prea mare" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Neacceptat" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Tip neacceptat" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Format neacceptat" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Dosarul Originals este gol" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Selecția nu a fost găsită" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Entitatea nu a fost găsită" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Contul nu a fost găsit" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Utilizatorul nu a fost găsit" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Eticheta nu a fost găsită" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Nu s-a găsit camera" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Obiectivul nu a fost găsit" + +#: messages.go:131 msgid "Album not found" msgstr "Album nedescoperit" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Subiectul nu a fost găsit" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Persoana nu a fost găsită" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Fața nu a fost găsită" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Nu este disponibil în modul public" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Nu este disponibil în modul doar pentru citire" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Vă rugăm să vă conectați la contul dvs" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Permisiune refuzată" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Plata necesară" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Încărcarea poate fi ofensatoare" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Încărcarea a eșuat" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Niciun element selectat" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Nu a reușit să creeze fișierul, vă rugăm să verificați permisiunile" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Nu s-a reușit crearea dosarului, vă rugăm să verificați permisiunile" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Nu s-a putut conecta, vă rugăm să încercați din nou" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Introduceți codul de verificare" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Cod de verificare nevalid, încercați din nou" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Parolă invalidă, vă rugăm să încercați din nou" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Caracteristică dezactivată" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Nu sunt selectate etichete" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Nu sunt selectate albume" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Nu există fișiere disponibile pentru descărcare" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Nu a reușit să creeze fișierul zip" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Acreditări nevalabile" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Legătură invalidă" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Nume invalid" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Ocupat, vă rugăm să încercați din nou mai târziu" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Intervalul de trezire este %s, dar trebuie să fie de 1h sau mai puțin" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Contul dvs. nu a putut fi conectat" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Prea multe cereri" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Depozitare insuficientă" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Cota depășită" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Înregistrare dezactivată" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Adresă de e-mail verificată necesară" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Modificări salvate cu succes" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Album creat" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Album salvat" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Album %s șters" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Conținutul albumului a fost clonat" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Fișier eliminat din stivă" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Fișier șters" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Selecție adăugată la %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "O intrare adăugată la %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d intrări adăugate la %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "O intrare eliminată din %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d intrări eliminate din %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Cont creat" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Cont salvat" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Cont șters" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Setări salvate" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Parola a fost schimbată" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Import finalizat în %d s" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Importul a fost anulat" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indexare finalizată în %d s" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Indexarea originalelor..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Indexarea fișierelor în %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indexare anulată" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Sau eliminat %d fișiere și %d fotografii" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Mutarea fișierelor din %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Copierea fișierelor din %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Etichete șterse" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Etichetă salvată" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Subiect salvat" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Subiect eliminat" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Persoană salvată" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Persoană eliminată" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Fișier încărcat" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d fișiere încărcate în %d s" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Procesarea încărcării..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Încărcarea a fost procesată" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Selecție aprobată" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Selecție arhivată" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Selecție restabilită" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Selecție marcată ca fiind privată" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Albume șterse" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Fișierul Zip creat în %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Șterse definitiv" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s a fost restaurat" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Verificat cu succes" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Activat cu succes" diff --git a/assets/locales/ru/default.po b/assets/locales/ru/default.po index 41d933175..65da63537 100644 --- a/assets/locales/ru/default.po +++ b/assets/locales/ru/default.po @@ -2,9 +2,10 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Russian \n" "Language: ru\n" @@ -13,402 +14,418 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Что-то пошло не так, попробуйте еще раз" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Невозможно сделать это" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Изменения не будут сохранены" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Не будет удалено" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s уже существует" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Не найдено" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Файл не найден" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Слишком большой файл" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Не поддерживается" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Неподдерживаемый тип" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Неподдерживаемый формат" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Папка оригиналов пуста" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Выделение не найдено" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Сущность не найдена" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Учетная запись не найдена" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Пользователь не найден" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Метка не найдена" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Камера не найдена" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Объектив не найден" + +#: messages.go:131 msgid "Album not found" msgstr "Альбом не найден" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Объект не найден" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Человек не найден" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Лицо не найдено" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Не доступно в публичном режиме" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Недоступно в режиме только для чтения" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Пожалуйста, войдите в свой аккаунт" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Доступ запрещен" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Требуется оплата" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Загрузка может быть оскорбительной" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Загрузка не удалась" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Нет выделенных элементов" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Не удалось создать файл, проверьте права доступа" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Не удалось создать папку, проверьте права доступа" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Нет соединения, попробуйте еще раз" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "введите код подтверждения" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Неверный код подтверждения. Повторите попытку." -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Неверный пароль, пожалуйста попробуйте еще раз" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Данная возможность отключена" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Нет выделенных меток" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Нет выделенных альбомов" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Нет файлов, доступных для скачивания" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Не удалось создать zip-файл" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Неверные учетные данные" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Неверная ссылка" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Неприемлемое имя" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Занят, повторите попытку позже" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Интервал пробуждения составляет %s, но должен быть 1 час или меньше" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Ваш аккаунт не удалось подключить" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Слишком много запросов" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Недостаточно места для хранения" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Квота превышена" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Регистрация отключена" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Требуется подтверждение адреса электронной почты." + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Изменения сохранены" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Альбом создан" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "\\альбом сохранен" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Альбом %s удален" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Содержимое альбома скоприровано" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Файл удален из очереди" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Файл удалён" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Выделение добавлено к %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Один элемент добавлен к %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d элементов добавлено к %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Один элемент удален из %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d элементов удалено из %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Учетная запись создана" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Учетная запись сохранена" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Учетная запись удалена" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Настройки сохранены" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Пароль изменен" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Импортирование завершено за %d c" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Импортирование отменено" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Индексирование завершено за %d с" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Индексирование Оригиналов..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Индексирование файлов в %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Индексирование отменено" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Удаление %d файлов и %d фотографий" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Перемещение файлов из %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Копирование файлов из %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Метки удалены" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Метки сохранены" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Тема сохранена" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Тема удалена" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Человек спасен" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Лицо удалено" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Файл загружен" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d файлов загружено за %d с" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Обработка загрузки..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Загрузка была обработана" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Утвержденный выбор" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Выбранное помещено в архив" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Выбранное восстановлено" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Выбранное помечено как приватное" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Альбом удален" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip архив создан за %d с" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Постоянно удаляется" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s был восстановлен" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Успешно проверено" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Успешно активировано" diff --git a/assets/locales/sk/default.po b/assets/locales/sk/default.po index 5a5246fd2..250c13b5a 100644 --- a/assets/locales/sk/default.po +++ b/assets/locales/sk/default.po @@ -2,9 +2,10 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Slovak \n" "Language: sk\n" @@ -12,402 +13,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Niečo sa pokazilo, skúste to znova" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Nemožno to urobiť" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Zmeny sa neuložili" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Nepodarilo sa odstrániť" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s už existuje" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Nenájdené" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Súbor nenájdený" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Príliš veľký súbor" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Nepodporované" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Nepodporovaný typ" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Nepodporovaný formát" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Priečinok Originály je prázdny" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Výber nenájdený" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Subjekt nenájdený" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Účet nenájdený" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Užívateľ nenájdený" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Štítok nenájdený" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Fotoaparát nebol nájdený" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Objektív nebol nájdený" + +#: messages.go:131 msgid "Album not found" msgstr "Album nenájdený" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Predmet nenájdený" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Osoba nenájdená" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Tvár nenájdená" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Nedostupné vo verejnom móde" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "nedostupné v móde len pre čítanie" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Prosím prihláste sa a skúste znova" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Osoba odstránená" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Požadovaná platba" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Nahrané súbory môžu byť urážlivé" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Odovzdávanie zlyhalo" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Neboli vybraté žiadne položky" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Vytváranie súboru zlyhalo, prosím skontrolujte oprávnenia" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Vytváranie zložky zlyhalo, prosím skontrolujte oprávnenia" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Nebolo možné sa pripojiť, skúste to znova" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Zadajte overovací kód" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Neplatný overovací kód, skúste to znova" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Nesprávne heslo, skúste to znova" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Funkcia vypnutá" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Neboli vybraté žiadne štítky" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Neboli vybraté žiadne albumy" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Žiadne súbory na stiahnutie k dispozícií" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Nebolo možné vytvoriť súbor ZIP" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Neplatné údaje" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Neplatný odkaz" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Neplatné meno" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Systém zaneprázdnený, prosím skúste znovu neskôr" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Interval prebúdzania je %s, ale musí byť najviac 1 h" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Vaše konto sa nepodarilo pripojiť" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Príliš veľa požiadaviek" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Nedostatočné skladovanie" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Prekročenie kvóty" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Registrácia zakázaná" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Vyžaduje sa overený e-mail" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Zmeny úspešne uložené" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Album vytvorený" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Album uložený" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Album %s vymazaný" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Obsah albumu prekopírovaný" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Súbor odstránený zo stohu" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Súbor odstránený" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Výber pridaný do %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Jeden záznam pridaný do %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d záznamov pridaných do %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Jeden záznam odstránený z %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d záznamov odstránených z %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Účet vytvorený" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Účet uložený" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Účet odstránený" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Nastavenia uložené" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Heslo zmenené" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Import hotový za %d sekúnd" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Import zrušený" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indexovanie hotové za %d sekúnd" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Indexovanie originálov..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Indexovanie súborov v %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indexovanie zrušené" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Bolo odstránených %d súborov a %d fotiek" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Presúvanie súborov z %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Kopírovanie súborov z %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Štítky odstránené" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Štítok uložený" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Predmet uložený" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Predmet odstránený" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Osoba uložená" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Osoba odstránená" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Súbor odstránený" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d súborov nahraných za %d sekúnd" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Spracovanie nahrávania..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Nahrané súbory môžu byť urážlivé" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Označenie schválené" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Označenie archivované" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Označenie obnovené" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Označenie označené ako súkromné" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Albumy odstránené" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Súbor ZIP vytvorený za %d sekúnd" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Trvalo odstránené" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s bolo obnovené" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Úspešne overené" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Úspešne aktivované" diff --git a/assets/locales/sl/default.po b/assets/locales/sl/default.po index f333eec41..77a364e0e 100644 --- a/assets/locales/sl/default.po +++ b/assets/locales/sl/default.po @@ -2,9 +2,10 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" "Language: sl\n" "MIME-Version: 1.0\n" @@ -12,402 +13,418 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || " "n%100==4 ? 2 : 3;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Nekaj je šlo narobe, poskusite znova" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Tega ni mogoče storiti" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Sprememb ni bilo mogoče shraniti" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Ni bilo mogoče izbrisati" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s že obstaja" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Ga ni mogoče najti" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Datoteka ni najdena" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Prevelika datoteka" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Nepodprto" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Nepodprta vrsta" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Nepodprt format" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Mapa Originali je prazna" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Izbor ni najden" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Entiteta ni bila najdena" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Račun ni najden" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Uporabnik ne obstaja" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Oznaka ni bila najdena" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Kamera ni bila najdena" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Objektiv ni bil najden" + +#: messages.go:131 msgid "Album not found" msgstr "Album ni najden" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Zadeva ni bila najdena" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Oseba ni bila najdena" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Obraza ni mogoče najti" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Ni na voljo v javnem načinu" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Ni na voljo v načinu samo za branje" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Prijavite se v svoj račun" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Dovoljenje Zavrnjeno" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Zahtevano plačilo" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Nalaganje je lahko žaljivo" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Nalaganje neuspešno" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Ni izbranih elementov" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Neuspešno ustvarjanje datoteke, preverite dovoljenja" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Neuspešno ustvarjanje mape, preverite dovoljenja" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Ne morem vzpostaviti povezave, poskusite znova" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "vnesi potrditveno kodo" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Neveljavna koda za preverjanje, poskusite znova" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Nepravilno geslo, poskusite znova" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Funkcija je onemogočena" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Ni izbranih nalepk" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Ni izbranih albumov" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Za prenos ni na voljo nobenih datotek" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Ni uspelo ustvariti datoteke zip" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Neveljavne poverilnice" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Neveljavna povezava" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Neveljavno ime" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Zaseden, poskusite znova pozneje" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Interval prebujanja je %s, vendar mora biti 1h ali manj" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Vašega računa ni bilo mogoče povezati" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Preveč zahtev" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Nezadostno skladiščenje" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Kvota je presežena" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Registracija onemogočena" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Zahtevan je potrjen e-poštni naslov" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Spremembe so bile uspešno shranjene" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Ustvarjen album" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Shranjen album" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Album %s izbrisano" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Vsebina albuma klonirana" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Datoteka odstranjena iz sklada" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Izbrisana datoteka" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Izbor dodan v %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "En vnos dodan v %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d vnosi dodani v %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "En vnos odstranjen iz %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d vnosi odstranjeni iz %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Ustvarjen račun" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Shranjen račun" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Račun je izbrisan" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Nastavitve shranjene" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Geslo spremenjeno" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Uvoz se zaključi v %d s" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Uvoz preklican" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indeksiranje je končano v %d s" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Indeksiranje izvirnikov..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Indeksiranje datotek v %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indeksiranje preklicano" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Odstranjene %d datoteke in %d fotografije" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Premikanje datotek iz %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Kopiranje datotek iz %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Etikete izbrisane" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Shranjena nalepka" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Zadeva je shranjena" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Predmet izbrisanih" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Rešena oseba" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Izbrisana oseba" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Prenesena datoteka" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d datoteke, naložene v %d s" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Obdelava nalaganja..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Prenos je bil obdelan" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Odobren izbor" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Arhiviran izbor" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Obnovljen izbor" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Izbor označen kot zasebni" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Izbrisani albumi" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip, ustvarjen v %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Trajno izbrisano" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s je bil obnovljen" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Uspešno preverjeno" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Uspešno aktiviran" diff --git a/assets/locales/sv/default.po b/assets/locales/sv/default.po index 4073cf2d9..597497e1c 100644 --- a/assets/locales/sv/default.po +++ b/assets/locales/sv/default.po @@ -2,9 +2,10 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -12,402 +13,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Något gick fel, försök igen" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Det går inte att göra" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Ändringarna kunde inte sparas" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Kunde inte raderas" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s finns redan" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Hittades inte" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Filen kunde inte hittas" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Filen är för stor" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Stöds ej" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Denna typ stöds ej" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Format som inte stöds" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Mappen med originalen är tom" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Urvalet kunde inte hittas" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Entitet kunde inte hittas" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Kontot kunde inte hittas" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Användaren kunde inte hittas" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Etikett saknas" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Kameran hittades inte" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Linsen hittades inte" + +#: messages.go:131 msgid "Album not found" msgstr "Albumet finns inte" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Ämnet finns inte" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Personen kunde inte hittas" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Ansiktet kunde inte hittas" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Inte tillgängligt i offentligt läge" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Inte tillgänglig i skrivskyddsläge" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Logga in på ditt konto" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Åtkomst nekades" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Betalning krävs" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Uppladdning kan vara stötande" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Uppladdning misslyckades" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Inga objekt har valts" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Det gick inte att skapa en fil, kontrollera behörigheter" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Det gick inte att skapa en mapp, kontrollera behörigheter" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Kunde inte ansluta, försök igen" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Ange verifieringskod" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Ogiltig verifieringskod, försök igen" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Felaktigt lösenord, försök igen" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Funktionen är inaktiverad" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Inga etiketter har valts" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Inga album har valts" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Inga filer finns tillgängliga för nedladdning" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Misslyckades med att skapa en zip-fil" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Ogiltiga autentiseringsuppgifter" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Ogiltig länk" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Felaktigt namn" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Upptagen, försök igen senare" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Uppvakningsintervallet är %s, men måste vara 1 timme eller mindre" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Ditt konto kunde inte anslutas" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "För många förfrågningar" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Otillräcklig lagring" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Kvoten överskriden" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Registrering inaktiverad" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Verifierad e-postadress krävs" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Ändringarna har sparats" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Album skapat" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Album sparat" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Album %s raderat" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Innehållet i albumet kopieras" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Filen tas bort från stapeln" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Fil raderad" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Urval tillagt i %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "En post tillagd i %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d poster tillagda till %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "En post borttagen från %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d poster raderade från %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Kontot har skapats" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Kontot sparat" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Kontot raderat" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Inställningarna har sparats" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Lösenordet har ändrats" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Importen slutfördes på %d s" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Importen avbruten" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Indexering slutförd på %d s" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Indexering av original..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Indexering av filer i %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Indexering avbruten" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Tog bort %d filer och %d bilder" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Flyttar filer från %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Kopierar filer från %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Etiketter raderade" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Etikett sparad" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Ämne sparat" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Ämne raderat" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Person sparad" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Person raderad" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Uppladdad fil" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d filer uppladdade på %d s" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Behandling av uppladdning..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Uppladdningen har behandlats" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Urvalet är godkänt" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Urval arkiverat" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Urvalet har återställts" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Urval markerat som privat" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Album raderade" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip skapad på %d s" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Permanent borttagen" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s har återställts" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Verifierad" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Lyckades aktiverad" diff --git a/assets/locales/th/default.po b/assets/locales/th/default.po index 93d744fbe..500761ebe 100644 --- a/assets/locales/th/default.po +++ b/assets/locales/th/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" "Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" @@ -12,402 +12,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "เกิดข้อผิดพลาด โปรดลองอีกครั้ง" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "ไม่สามารถทำเช่นนั้นได้" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "ไม่สามารถบันทึกการเปลี่ยนแปลง" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "ไม่สามารถลบได้" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s มีอยู่แล้ว" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "ไม่พบ" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "ไม่พบไฟล์" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "ไฟล์ใหญ่เกินไป" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "ไม่รองรับ" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "ประเภทที่ไม่รองรับ" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "รูปแบบที่ไม่สนับสนุน" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "โฟลเดอร์ต้นฉบับว่างเปล่า" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "ไม่พบสิ่งที่เลือก" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "ไม่พบเอนทิตี" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "ไม่พบบัญชี" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "ไม่พบผู้ใช้" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "ไม่พบป้ายกำกับ" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "ไม่พบกล้อง" + +#: messages.go:130 +msgid "Lens not found" +msgstr "ไม่พบเลนส์" + +#: messages.go:131 msgid "Album not found" msgstr "ไม่พบอัลบั้ม" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "ไม่พบหัวเรื่อง" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "ไม่พบบุคคล" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "ไม่พบใบหน้า" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "ไม่พร้อมใช้งานในโหมดสาธารณะ" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "ไม่พร้อมใช้งานในโหมดอ่านอย่างเดียว" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "กรุณาเข้าสู่ระบบบัญชีของคุณ" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "ปฏิเสธการอนุญาต" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "ต้องชำระเงิน" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "การอัปโหลดอาจไม่เหมาะสม" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "การอัพโหลดล้มเหลว" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "ไม่มีรายการที่เลือก" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "สร้างไฟล์ไม่สำเร็จ โปรดตรวจสอบสิทธิ์" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "สร้างโฟลเดอร์ไม่สำเร็จ โปรดตรวจสอบสิทธิ์" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "ไม่สามารถเชื่อมต่อได้ โปรดลองอีกครั้ง" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "ระบุรหัสยืนยืน" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "รหัสยืนยันไม่ถูกต้อง โปรดลองอีกครั้ง" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "รหัสผ่านไม่ถูกต้อง โปรดลองอีกครั้ง" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "คุณลักษณะถูกปิดใช้งาน" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "ไม่ได้เลือกป้ายกำกับ" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "ไม่ได้เลือกอัลบั้ม" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "ไม่มีไฟล์สำหรับดาวน์โหลด" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "สร้างไฟล์ zip ไม่สำเร็จ" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "ข้อมูลประจำตัวที่ไม่ถูกต้อง" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "ลิงก์ไม่ถูกต้อง" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "ชื่อไม่ถูกต้อง" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "ไม่ว่าง โปรดลองอีกครั้งในภายหลัง" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "ช่วงเวลาปลุกคือ %s แต่ต้องเป็น 1 ชั่วโมงหรือน้อยกว่า" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "ไม่สามารถเชื่อมต่อบัญชีของคุณได้" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "คำขอมากเกินไป" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "พื้นที่เก็บข้อมูลไม่เพียงพอ" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "เกินโควตา" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "การลงทะเบียนถูกปิดใช้งาน" + +#: messages.go:164 +msgid "Verified email required" +msgstr "ต้องยืนยันอีเมล" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "บันทึกการเปลี่ยนแปลงเรียบร้อยแล้ว" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "สร้างอัลบั้มแล้ว" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "บันทึกอัลบั้มแล้ว" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "ลบอัลบั้ม %s แล้ว" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "โคลนเนื้อหาในอัลบั้ม" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "ไฟล์ถูกลบออกจากสแต็ค" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "ลบไฟล์แล้ว" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "เพิ่มการเลือกใน %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "เพิ่มหนึ่งรายการใน %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d รายการที่เพิ่มใน %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "ลบหนึ่งรายการจาก %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "รายการ %d ถูกลบออกจาก %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "สร้างบัญชีแล้ว" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "บันทึกบัญชีแล้ว" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "ลบบัญชีแล้ว" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "การตั้งค่าที่บันทึกไว้" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "เปลี่ยนรหัสผ่านแล้ว" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "การนำเข้าเสร็จสมบูรณ์ใน %d วินาที" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "ยกเลิกการนำเข้าแล้ว" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "การสร้างดัชนีเสร็จสิ้นใน %d วินาที" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "กำลังจัดทำดัชนีต้นฉบับ..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "การทำดัชนีไฟล์ใน %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "ยกเลิกการทำดัชนีแล้ว" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "ลบไฟล์ %d และภาพถ่าย %d" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "การย้ายไฟล์จาก %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "การคัดลอกไฟล์จาก %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "ลบป้ายกำกับแล้ว" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "บันทึกป้ายกำกับแล้ว" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "บันทึกหัวเรื่องแล้ว" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "ลบหัวเรื่องแล้ว" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "บุคคลที่บันทึกไว้" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "ลบบุคคลแล้ว" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "อัปโหลดไฟล์แล้ว" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "ไฟล์ %d ที่อัปโหลดใน %d วินาที" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "กำลังประมวลผลการอัปโหลด..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "อัปโหลดได้รับการดำเนินการ" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "การเลือกได้รับการอนุมัติ" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "เก็บถาวรการเลือกแล้ว" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "คืนค่าการเลือกแล้ว" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "การเลือกถูกทำเครื่องหมายเป็นส่วนตัว" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "ลบอัลบั้มแล้ว" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip สร้างใน %d วินาที" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "ลบอย่างถาวร" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s ได้รับการกู้คืนแล้ว" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "ตรวจสอบเรียบร้อยแล้ว" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "เปิดใช้งานสำเร็จแล้ว" diff --git a/assets/locales/tr/default.po b/assets/locales/tr/default.po index 47f4aa57e..4c7e03dc7 100644 --- a/assets/locales/tr/default.po +++ b/assets/locales/tr/default.po @@ -2,411 +2,428 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Bir şeyler ters gitti, tekrar deneyin" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Bunu yapmak mümkün değil" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Değişiklikler kaydedilemedi" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Silinemedi" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s zaten var" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Bulunamadı" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Dosya bulunamadı" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Dosya çok büyük" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Desteklenmiyor" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Desteklenmeyen tür" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Desteklenmeyen format" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Orijinaller klasörü boş" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Seçim bulunamadı" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Varlık bulunamadı" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Hesap bulunamadı" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Kullanıcı bulunamadı" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Etiket bulunamadı" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Kamera bulunamadı." + +#: messages.go:130 +msgid "Lens not found" +msgstr "Lens bulunamadı." + +#: messages.go:131 msgid "Album not found" msgstr "Albüm bulunamadı" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Özne bulunamadı" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Kişi bulunamadı" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Yüz bulunamadı" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Genel modda mevcut değil" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Salt okunur modda kullanılamaz" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Lütfen hesabınıza giriş yapın" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "İzin reddedildi" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Ödeme gerekli" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Yükleme rahatsız edici olabilir" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Yükleme başarısız" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Seçili öğe yok" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Dosya oluşturulamadı, lütfen izinleri kontrol edin" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Klasör oluşturulamadı, lütfen izinleri kontrol edin" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Bağlanılamadı, lütfen tekrar deneyin" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Doğrulama kodunu giriniz" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Geçersiz doğrulama kodu, lütfen tekrar deneyin" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Geçersiz şifre, lütfen tekrar deneyin" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Özellik devre dışı" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Seçili etiket yok" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Seçili albüm yok" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "İndirilebilecek dosya yok" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Zip dosyası oluşturulamadı" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Geçersiz kimlik bilgileri" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Geçersiz link" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Geçersiz isim" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Meşgul, lütfen daha sonra tekrar deneyin" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Uyandırma aralığı %s'dır, ancak 1 saat veya daha az olmalıdır" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Hesabınız bağlanamadı" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Çok fazla talep var" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Yetersiz depolama" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Kota aşıldı" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Kayıt devre dışı bırakıldı" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Doğrulanmış e-posta adresi gereklidir." + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Değişiklikler başarıyla kaydedildi" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Albüm oluşturuldu" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Albüm kaydedildi" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Albüm %s silindi" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Albüm içeriği klonlandı" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Dosya yığından kaldırıldı" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Silinmiş dosya" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Seçim %s'a eklendi" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Bir giriş %s'a eklendi" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d girişleri %s'e eklendi" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Bir giriş %s'dan kaldırıldı" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d girişleri %s'den kaldırıldı" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Hesap eklendi" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Hesap kaydedildi" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Hesap silindi" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Ayarlar kaydedildi" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Şifre Değiştirildi" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "İçe aktarma %d s içinde tamamlandı" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "İçe aktarma iptal edildi" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "İndeksleme %d s içinde tamamlandı" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Orijinalleri dizinliyor..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "%s dosya yüklendi" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "İndeksleme iptal edildi" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "%d dosya ve %d fotoğraf kaldırıldı" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Dosyaları %s'dan taşıma" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Dosyaları %s'dan kopyalama" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Etiketler silindi" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Etiket kaydedildi" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Konu kaydedildi" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Konu silindi" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Kurtarılan kişi" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Kişi silindi" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Dosya yüklendi" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d dosyalar %d s içinde yüklendi" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Yükleme işlemi..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Yükleme işlemi tamamlandı" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Seçim onaylandı" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Seçim arşivlendi" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Seçim geri yüklendi" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Özel olarak işaretlenmiş seçim" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Albümler silindi" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip %d s içinde oluşturuldu" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Kalıcı olarak silindi" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s geri yüklendi" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Başarıyla doğrulandı" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Başarıyla etkinleştirildi" diff --git a/assets/locales/uk/default.po b/assets/locales/uk/default.po index 71a75c2bf..f7f221440 100644 --- a/assets/locales/uk/default.po +++ b/assets/locales/uk/default.po @@ -2,9 +2,10 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" "Language: uk\n" "MIME-Version: 1.0\n" @@ -12,403 +13,419 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Щось пішло не так, спробуйте ще раз" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Неможливо це зробити" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Зміни не можливо зберегти" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Не можливо видалити" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s вже існує" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Не знайдено" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Файл не знайдено" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Файл занадто великий" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Не підтримується" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Непідтримуваний тип" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Непідтримуваний формат" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Папка з оригіналами порожня" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Вибір не знайдено" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Об'єкт не знайдено" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Обліковий запис не знайдено" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Користувача не знайдено" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Мітку не знайдено" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Камеру не знайдено" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Об'єктив не знайдено" + +#: messages.go:131 msgid "Album not found" msgstr "Альбом не знайдено" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Тема не знайдена" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Особистість не знайдена" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Обличчя не знайдено" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Недоступно в публічному режимі" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "не доступно в режимі \"тільки читання\"" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Будь ласка, увійдіть до свого облікового запису" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "В доступі відмовлено" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Потрібна оплата" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Завантаження може бути образливим" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Помилка вивантаження" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Нічого не вибрано" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Помилка створення файла, перевірте дозволи" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Не вдалося створити папку, перевірте права доступу" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Не можливо підключитися, спробуйте знову" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Введіть код верифікації" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Невірний код верифікації, спробуйте знову" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "Невірний пароль, спробуйте знову" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Функцію вимкнено" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Мітки не вибрано" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Альбоми не вибрано" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Немає доступних файлів для завантаження" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Не вдалося створити zip-файл" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Недійсні облікові дані" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Невірне посилання" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Невірне ім'я" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Зайнято, спробуйте пізніше" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "" "Інтервал пробудження становить %s, але має становити 1 годину або менше" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Ваш обліковий запис не вдалося підключити" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "Занадто багато запитів" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Недостатнє зберігання" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Перевищено квоту" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Реєстрацію вимкнено" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Потрібна підтверджена електронна адреса" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Зміни успішно збережено" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Альбом створено" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Альбом збережено" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Альбом %s видалено" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Вміст альбому клоновано" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Файл видалено з стеку" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Файл видалено" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Вибір додано до %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Один запис додано до %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d записів додано до %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Один запис видалено з %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d записів видалено з %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Обліковий запис створено" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Обліковий запис збережено" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Обліковий запис видалено" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Налаштування збережено" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "Пароль змінено" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Імпортування тривало %d с" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Імпортування скасовано" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Індексування тривало %d с" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Індексуємо оригінали..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Індексуємо файли в %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Індексування скасовано" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Видалено %d файлів та %d фотографій" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Переносимо файли з %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Копіюємо файли з %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Мітки видалено" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Мітку збережено" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Тема збережена" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Тема видалена" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Людина збережена" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Людина видалена" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "Файл завантажено" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "%d файлів вивантажено за %d с" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Обробка завантаження..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Завантаження оброблено" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Вибір затверджено" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Вибране заархівовано" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Вибране відновлено" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Вибіране позначено як приватне" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Альбом видалено" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip створено за %d с" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Остаточно видалено" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s було відновлено" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Верифікація успішна" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Активація успішна" diff --git a/assets/locales/vi/default.po b/assets/locales/vi/default.po index fed039aa6..57c96b623 100644 --- a/assets/locales/vi/default.po +++ b/assets/locales/vi/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" "Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" @@ -12,402 +12,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "Đã xảy ra lỗi, hãy thử lại" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "Không thể làm điều đó" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "Không thể lưu các thay đổi" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "Không thể xóa được" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s đã tồn tại" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "Không tìm thấy" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "Không tìm thấy tập tin" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "Tệp quá lớn" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "Không được hỗ trợ" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "Loại không được hỗ trợ" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "Định dạng không được hỗ trợ" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "Thư mục gốc trống" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "Không tìm thấy lựa chọn" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "Không tìm thấy thực thể" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "Tài khoản không được tìm thấy" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "Không tìm thấy người dùng" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "Không tìm thấy nhãn" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "Không tìm thấy máy ảnh" + +#: messages.go:130 +msgid "Lens not found" +msgstr "Không tìm thấy ống kính" + +#: messages.go:131 msgid "Album not found" msgstr "Không tìm thấy album" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "Không tìm thấy chủ đề" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "Không tìm thấy người" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "Không tìm thấy khuôn mặt" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "Không khả dụng ở chế độ công khai" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "Không khả dụng ở chế độ chỉ đọc" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "Xin hãy đăng nhập vào tài khoản của bạn" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "Quyền bị từ chối" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "Yêu cầu thanh toán" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "Tải lên có thể gây khó chịu" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "Tải lên không thành công" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "Không có mục nào được chọn" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "Không tạo được tệp, vui lòng kiểm tra quyền" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "Không tạo được thư mục, vui lòng kiểm tra quyền" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "Không thể kết nối, vui lòng thử lại" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "Nhập mã xác nhận" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "Mã xác minh không hợp lệ, vui lòng thử lại" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "mật mã không hợp lệ, vui lòng thử lại" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "Tính năng bị tắt" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "Không có nhãn nào được chọn" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "Không có album nào được chọn" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "Không có tập tin nào để tải xuống" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "Không tạo được tệp zip" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "Thông tin không hợp lệ" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "Liên kết không hợp lệ" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "Tên không hợp lệ" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "Đang bận, vui lòng thử lại sau" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Khoảng thời gian đánh thức là %s nhưng phải từ 1 giờ trở xuống" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "Tài khoản của bạn không thể kết nối được" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "quá nhiều yêu cầu" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "Không đủ dung lượng lưu trữ" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "Vượt quá hạn ngạch" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "Đăng ký bị vô hiệu hóa" + +#: messages.go:164 +msgid "Verified email required" +msgstr "Cần có email đã được xác minh." + +#: messages.go:167 msgid "Changes successfully saved" msgstr "Đã lưu thay đổi thành công" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "Đã tạo album" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "Đã lưu album" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "Album %s đã bị xóa" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "Nội dung album được sao chép" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "Đã xóa tệp khỏi ngăn xếp" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "Đã xóa tệp" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "Đã thêm lựa chọn vào %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "Đã thêm một mục vào %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "Các mục %d được thêm vào %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "Đã xóa một mục khỏi %s" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "Các mục %d đã bị xóa khỏi %s" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "Tài khoản đã được tạo" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "Đã lưu tài khoản" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "Tài khoản đã bị xóa" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "Đã lưu cài đặt" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "mật khẩu đã được thay đổi" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "Quá trình nhập hoàn tất sau %d giây" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "Đã hủy nhập" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "Việc lập chỉ mục hoàn tất sau %d giây" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "Lập chỉ mục bản gốc..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "Lập chỉ mục các tệp trong %s" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "Đã hủy lập chỉ mục" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "Đã xóa tệp %d và ảnh %d" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "Di chuyển tệp từ %s" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "Sao chép tập tin từ %s" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "Đã xóa nhãn" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "Đã lưu nhãn" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "Đã lưu chủ đề" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "Chủ đề đã bị xóa" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "Người đã được cứu" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "Người đã bị xóa" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "File đã được tải lên" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "Các tệp %d được tải lên trong %d giây" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "Đang xử lý tải lên..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "Tải lên đã được xử lý" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "Lựa chọn đã được phê duyệt" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "Đã lưu trữ lựa chọn" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "Đã khôi phục lựa chọn" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "Lựa chọn được đánh dấu là riêng tư" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "Album đã bị xóa" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip được tạo trong %d giây" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "Đã xóa vĩnh viễn" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s đã được khôi phục" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "Đã xác minh thành công" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "Đã kích hoạt thành công" diff --git a/assets/locales/zh/default.po b/assets/locales/zh/default.po index 9a90cece8..36c0aa6d4 100644 --- a/assets/locales/zh/default.po +++ b/assets/locales/zh/default.po @@ -2,9 +2,10 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Chinese (Simplified) \n" "Language: zh\n" @@ -12,402 +13,418 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.13.3\n" +"X-Generator: Weblate 2026.5\n" -#: messages.go:104 +#: messages.go:112 msgid "Something went wrong, try again" msgstr "出错了,再试一次" -#: messages.go:105 +#: messages.go:113 msgid "Unable to do that" msgstr "无法做到这一点" -#: messages.go:106 +#: messages.go:114 msgid "Changes could not be saved" msgstr "无法保存变更" -#: messages.go:107 +#: messages.go:115 msgid "Could not be deleted" msgstr "无法删除" -#: messages.go:108 +#: messages.go:116 #, c-format msgid "%s already exists" msgstr "%s 已存在" -#: messages.go:109 +#: messages.go:117 msgid "Not found" msgstr "未找到" -#: messages.go:110 +#: messages.go:118 msgid "File not found" msgstr "未找到文件" -#: messages.go:111 +#: messages.go:119 msgid "File too large" msgstr "文件过大" -#: messages.go:112 +#: messages.go:120 msgid "Unsupported" msgstr "不支持" -#: messages.go:113 +#: messages.go:121 msgid "Unsupported type" msgstr "不支持的类型" -#: messages.go:114 +#: messages.go:122 msgid "Unsupported format" msgstr "不支持的格式" -#: messages.go:115 +#: messages.go:123 msgid "Originals folder is empty" msgstr "原件文件夹是空的" -#: messages.go:116 +#: messages.go:124 msgid "Selection not found" msgstr "未找到所选内容" -#: messages.go:117 +#: messages.go:125 msgid "Entity not found" msgstr "未找到实体" -#: messages.go:118 +#: messages.go:126 msgid "Account not found" msgstr "未找到账户" -#: messages.go:119 +#: messages.go:127 msgid "User not found" msgstr "未找到用户" -#: messages.go:120 +#: messages.go:128 msgid "Label not found" msgstr "未找到标签" -#: messages.go:121 +#: messages.go:129 +msgid "Camera not found" +msgstr "未找到摄像头" + +#: messages.go:130 +msgid "Lens not found" +msgstr "未找到镜头" + +#: messages.go:131 msgid "Album not found" msgstr "未找到相册" -#: messages.go:122 +#: messages.go:132 msgid "Subject not found" msgstr "未找到主题" -#: messages.go:123 +#: messages.go:133 msgid "Person not found" msgstr "未找到人物" -#: messages.go:124 +#: messages.go:134 msgid "Face not found" msgstr "未找到面孔" -#: messages.go:125 +#: messages.go:135 msgid "Not available in public mode" msgstr "在公开模式下不可用" -#: messages.go:126 +#: messages.go:136 msgid "Not available in read-only mode" msgstr "在只读模式下不可用" -#: messages.go:127 +#: messages.go:137 msgid "Please log in to your account" msgstr "请登录你的账户" -#: messages.go:128 +#: messages.go:138 msgid "Permission denied" msgstr "没有权限" -#: messages.go:129 +#: messages.go:139 msgid "Payment required" msgstr "需要付款" -#: messages.go:130 +#: messages.go:140 msgid "Upload might be offensive" msgstr "上传内容可能具有冒犯性" -#: messages.go:131 +#: messages.go:141 msgid "Upload failed" msgstr "上传失败" -#: messages.go:132 +#: messages.go:142 msgid "No items selected" msgstr "未选择任何项目" -#: messages.go:133 +#: messages.go:143 msgid "Failed creating file, please check permissions" msgstr "创建文件失败,请检查权限" -#: messages.go:134 +#: messages.go:144 msgid "Failed creating folder, please check permissions" msgstr "创建目录失败,请检查权限" -#: messages.go:135 +#: messages.go:145 msgid "Could not connect, please try again" msgstr "无法连接,请重试" -#: messages.go:136 +#: messages.go:146 msgid "Enter verification code" msgstr "输入验证码" -#: messages.go:137 +#: messages.go:147 msgid "Invalid verification code, please try again" msgstr "验证码无效,请重试" -#: messages.go:138 +#: messages.go:148 msgid "Invalid password, please try again" msgstr "无效密码,请重试" -#: messages.go:139 +#: messages.go:149 msgid "Feature disabled" msgstr "功能已禁用" -#: messages.go:140 +#: messages.go:150 msgid "No labels selected" msgstr "未选择标签" -#: messages.go:141 +#: messages.go:151 msgid "No albums selected" msgstr "未选择相册" -#: messages.go:142 +#: messages.go:152 msgid "No files available for download" msgstr "没有可供下载的文件" -#: messages.go:143 +#: messages.go:153 msgid "Failed to create zip file" msgstr "创建压缩文件失败" -#: messages.go:144 +#: messages.go:154 msgid "Invalid credentials" msgstr "无效凭证" -#: messages.go:145 +#: messages.go:155 msgid "Invalid link" msgstr "无效链接" -#: messages.go:146 +#: messages.go:156 msgid "Invalid name" msgstr "无效名称" -#: messages.go:147 +#: messages.go:157 msgid "Busy, please try again later" msgstr "忙碌中,请稍后重试" -#: messages.go:148 +#: messages.go:158 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "唤醒间隔为 %s,但必须小于等于 1 小时" -#: messages.go:149 +#: messages.go:159 msgid "Your account could not be connected" msgstr "你的账户无法连接" -#: messages.go:150 +#: messages.go:160 msgid "Too many requests" msgstr "请求太多" -#: messages.go:151 +#: messages.go:161 msgid "Insufficient storage" msgstr "存储不足" -#: messages.go:152 +#: messages.go:162 msgid "Quota exceeded" msgstr "超出配额" -#: messages.go:155 +#: messages.go:163 +msgid "Registration disabled" +msgstr "注册已禁用" + +#: messages.go:164 +msgid "Verified email required" +msgstr "需要已验证的电子邮件地址" + +#: messages.go:167 msgid "Changes successfully saved" msgstr "更改成功保存" -#: messages.go:156 +#: messages.go:168 msgid "Album created" msgstr "相册已创建" -#: messages.go:157 +#: messages.go:169 msgid "Album saved" msgstr "相册已保存" -#: messages.go:158 +#: messages.go:170 #, c-format msgid "Album %s deleted" msgstr "相册 %s 已删除" -#: messages.go:159 +#: messages.go:171 msgid "Album contents cloned" msgstr "相册内容已复制" -#: messages.go:160 +#: messages.go:172 msgid "File removed from stack" msgstr "文件已从堆中移除" -#: messages.go:161 +#: messages.go:173 msgid "File deleted" msgstr "文件已删除" -#: messages.go:162 +#: messages.go:174 #, c-format msgid "Selection added to %s" msgstr "所选项目已加入 %s" -#: messages.go:163 +#: messages.go:175 #, c-format msgid "One entry added to %s" msgstr "条目已添加到 %s" -#: messages.go:164 +#: messages.go:176 #, c-format msgid "%d entries added to %s" msgstr "%d 个条目已添加到 %s" -#: messages.go:165 +#: messages.go:177 #, c-format msgid "One entry removed from %s" msgstr "条目已从 %s 移除" -#: messages.go:166 +#: messages.go:178 #, c-format msgid "%d entries removed from %s" msgstr "%d 个条目已从 %s 移除" -#: messages.go:167 +#: messages.go:179 msgid "Account created" msgstr "账户已创建" -#: messages.go:168 +#: messages.go:180 msgid "Account saved" msgstr "账户已保存" -#: messages.go:169 +#: messages.go:181 msgid "Account deleted" msgstr "账户已删除" -#: messages.go:170 +#: messages.go:182 msgid "Settings saved" msgstr "设置已保存" -#: messages.go:171 +#: messages.go:183 msgid "Password changed" msgstr "密码已更改" -#: messages.go:172 +#: messages.go:184 #, c-format msgid "Import completed in %d s" msgstr "导入成功,耗时 %d 秒" -#: messages.go:173 +#: messages.go:185 msgid "Import canceled" msgstr "导入已取消" -#: messages.go:174 +#: messages.go:186 #, c-format msgid "Indexing completed in %d s" msgstr "索引成功,耗时 %d 秒" -#: messages.go:175 +#: messages.go:187 msgid "Indexing originals..." msgstr "索引源文件..." -#: messages.go:176 +#: messages.go:188 #, c-format msgid "Indexing files in %s" msgstr "索引 %s 中的文件" -#: messages.go:177 +#: messages.go:189 msgid "Indexing canceled" msgstr "索引已取消" -#: messages.go:178 +#: messages.go:190 #, c-format msgid "Removed %d files and %d photos" msgstr "移除了 %d 个文件和 %d 张照片" -#: messages.go:179 +#: messages.go:191 #, c-format msgid "Moving files from %s" msgstr "正在从 %s 中移动文件" -#: messages.go:180 +#: messages.go:192 #, c-format msgid "Copying files from %s" msgstr "正在从 %s 中复制文件" -#: messages.go:181 +#: messages.go:193 msgid "Labels deleted" msgstr "标签已移除" -#: messages.go:182 +#: messages.go:194 msgid "Label saved" msgstr "标签已保存" -#: messages.go:183 +#: messages.go:195 msgid "Subject saved" msgstr "主题已保存" -#: messages.go:184 +#: messages.go:196 msgid "Subject deleted" msgstr "主题已删除" -#: messages.go:185 +#: messages.go:197 msgid "Person saved" msgstr "人物已保存" -#: messages.go:186 +#: messages.go:198 msgid "Person deleted" msgstr "人物已删除" -#: messages.go:187 +#: messages.go:199 msgid "File uploaded" msgstr "已上传文件" -#: messages.go:188 +#: messages.go:200 #, c-format msgid "%d files uploaded in %d s" msgstr "已上传 %d 个文件,耗时 %d 秒" -#: messages.go:189 +#: messages.go:201 msgid "Processing upload..." msgstr "处理上传..." -#: messages.go:190 +#: messages.go:202 msgid "Upload has been processed" msgstr "上传已被处理" -#: messages.go:191 +#: messages.go:203 msgid "Selection approved" msgstr "所选项已批准" -#: messages.go:192 +#: messages.go:204 msgid "Selection archived" msgstr "所选项已归档" -#: messages.go:193 +#: messages.go:205 msgid "Selection restored" msgstr "所选项已恢复" -#: messages.go:194 +#: messages.go:206 msgid "Selection marked as private" msgstr "所选项已设为私有" -#: messages.go:195 +#: messages.go:207 msgid "Albums deleted" msgstr "相册已删除" -#: messages.go:196 +#: messages.go:208 #, c-format msgid "Zip created in %d s" msgstr "Zip 文件创建成功,耗时 %d 秒" -#: messages.go:197 +#: messages.go:209 msgid "Permanently deleted" msgstr "已永久删除" -#: messages.go:198 +#: messages.go:210 #, c-format msgid "%s has been restored" msgstr "%s 已恢复" -#: messages.go:199 +#: messages.go:211 msgid "Successfully verified" msgstr "验证成功" -#: messages.go:200 +#: messages.go:212 msgid "Successfully activated" msgstr "已成功激活" diff --git a/assets/locales/zh_TW/default.po b/assets/locales/zh_TW/default.po index 41c199f89..407b28f6c 100644 --- a/assets/locales/zh_TW/default.po +++ b/assets/locales/zh_TW/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-17 17:32+0000\n" -"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"PO-Revision-Date: 2026-06-27 10:28+0000\n" "Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Chinese (Traditional) \ No newline at end of file + \ No newline at end of file diff --git a/assets/static/icons/app/maskable/192.png b/assets/static/icons/app/maskable/192.png new file mode 100644 index 000000000..1281bb4c8 Binary files /dev/null and b/assets/static/icons/app/maskable/192.png differ diff --git a/assets/static/icons/app/maskable/512.png b/assets/static/icons/app/maskable/512.png new file mode 100644 index 000000000..7b0736060 Binary files /dev/null and b/assets/static/icons/app/maskable/512.png differ diff --git a/assets/static/icons/bloom.svg b/assets/static/icons/bloom.svg new file mode 100644 index 000000000..aad1ded16 --- /dev/null +++ b/assets/static/icons/bloom.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/static/icons/bloom/100.png b/assets/static/icons/bloom/100.png new file mode 100644 index 000000000..af72bebf3 Binary files /dev/null and b/assets/static/icons/bloom/100.png differ diff --git a/assets/static/icons/bloom/1024.png b/assets/static/icons/bloom/1024.png new file mode 100644 index 000000000..272d536d7 Binary files /dev/null and b/assets/static/icons/bloom/1024.png differ diff --git a/assets/static/icons/bloom/114.png b/assets/static/icons/bloom/114.png new file mode 100644 index 000000000..cb723ecec Binary files /dev/null and b/assets/static/icons/bloom/114.png differ diff --git a/assets/static/icons/bloom/120.png b/assets/static/icons/bloom/120.png new file mode 100644 index 000000000..aa88c900d Binary files /dev/null and b/assets/static/icons/bloom/120.png differ diff --git a/assets/static/icons/bloom/128.png b/assets/static/icons/bloom/128.png new file mode 100644 index 000000000..f1111e059 Binary files /dev/null and b/assets/static/icons/bloom/128.png differ diff --git a/assets/static/icons/bloom/144.png b/assets/static/icons/bloom/144.png new file mode 100644 index 000000000..0705fccdc Binary files /dev/null and b/assets/static/icons/bloom/144.png differ diff --git a/assets/static/icons/bloom/152.png b/assets/static/icons/bloom/152.png new file mode 100644 index 000000000..258a09ce5 Binary files /dev/null and b/assets/static/icons/bloom/152.png differ diff --git a/assets/static/icons/bloom/16.png b/assets/static/icons/bloom/16.png new file mode 100644 index 000000000..4e219a818 Binary files /dev/null and b/assets/static/icons/bloom/16.png differ diff --git a/assets/static/icons/bloom/160.png b/assets/static/icons/bloom/160.png new file mode 100644 index 000000000..8215c8aab Binary files /dev/null and b/assets/static/icons/bloom/160.png differ diff --git a/assets/static/icons/bloom/167.png b/assets/static/icons/bloom/167.png new file mode 100644 index 000000000..2a3177487 Binary files /dev/null and b/assets/static/icons/bloom/167.png differ diff --git a/assets/static/icons/bloom/172.png b/assets/static/icons/bloom/172.png new file mode 100644 index 000000000..b7a0c2708 Binary files /dev/null and b/assets/static/icons/bloom/172.png differ diff --git a/assets/static/icons/bloom/175.png b/assets/static/icons/bloom/175.png new file mode 100644 index 000000000..26a67ed44 Binary files /dev/null and b/assets/static/icons/bloom/175.png differ diff --git a/assets/static/icons/bloom/180.png b/assets/static/icons/bloom/180.png new file mode 100644 index 000000000..d4b4dc5fe Binary files /dev/null and b/assets/static/icons/bloom/180.png differ diff --git a/assets/static/icons/bloom/192.png b/assets/static/icons/bloom/192.png new file mode 100644 index 000000000..a4bc107d2 Binary files /dev/null and b/assets/static/icons/bloom/192.png differ diff --git a/assets/static/icons/bloom/196.png b/assets/static/icons/bloom/196.png new file mode 100644 index 000000000..8b7e58e2f Binary files /dev/null and b/assets/static/icons/bloom/196.png differ diff --git a/assets/static/icons/bloom/20.png b/assets/static/icons/bloom/20.png new file mode 100644 index 000000000..ff33168b2 Binary files /dev/null and b/assets/static/icons/bloom/20.png differ diff --git a/assets/static/icons/bloom/200.png b/assets/static/icons/bloom/200.png new file mode 100644 index 000000000..cd8ae1cc6 Binary files /dev/null and b/assets/static/icons/bloom/200.png differ diff --git a/assets/static/icons/bloom/216.png b/assets/static/icons/bloom/216.png new file mode 100644 index 000000000..2be67e9bb Binary files /dev/null and b/assets/static/icons/bloom/216.png differ diff --git a/assets/static/icons/bloom/256.png b/assets/static/icons/bloom/256.png new file mode 100644 index 000000000..227045b03 Binary files /dev/null and b/assets/static/icons/bloom/256.png differ diff --git a/assets/static/icons/bloom/267.png b/assets/static/icons/bloom/267.png new file mode 100644 index 000000000..14e9cb5bb Binary files /dev/null and b/assets/static/icons/bloom/267.png differ diff --git a/assets/static/icons/bloom/29.png b/assets/static/icons/bloom/29.png new file mode 100644 index 000000000..27fb80774 Binary files /dev/null and b/assets/static/icons/bloom/29.png differ diff --git a/assets/static/icons/bloom/32.png b/assets/static/icons/bloom/32.png new file mode 100644 index 000000000..f5d139074 Binary files /dev/null and b/assets/static/icons/bloom/32.png differ diff --git a/assets/static/icons/bloom/40.png b/assets/static/icons/bloom/40.png new file mode 100644 index 000000000..6f184869c Binary files /dev/null and b/assets/static/icons/bloom/40.png differ diff --git a/assets/static/icons/bloom/400.png b/assets/static/icons/bloom/400.png new file mode 100644 index 000000000..8c2c9eb2e Binary files /dev/null and b/assets/static/icons/bloom/400.png differ diff --git a/assets/static/icons/bloom/48.png b/assets/static/icons/bloom/48.png new file mode 100644 index 000000000..f912b1bd5 Binary files /dev/null and b/assets/static/icons/bloom/48.png differ diff --git a/assets/static/icons/bloom/50.png b/assets/static/icons/bloom/50.png new file mode 100644 index 000000000..fb7588e63 Binary files /dev/null and b/assets/static/icons/bloom/50.png differ diff --git a/assets/static/icons/bloom/512.png b/assets/static/icons/bloom/512.png new file mode 100644 index 000000000..34ed75302 Binary files /dev/null and b/assets/static/icons/bloom/512.png differ diff --git a/assets/static/icons/bloom/55.png b/assets/static/icons/bloom/55.png new file mode 100644 index 000000000..e2f39e3c5 Binary files /dev/null and b/assets/static/icons/bloom/55.png differ diff --git a/assets/static/icons/bloom/56.png b/assets/static/icons/bloom/56.png new file mode 100644 index 000000000..2795dae4b Binary files /dev/null and b/assets/static/icons/bloom/56.png differ diff --git a/assets/static/icons/bloom/60.png b/assets/static/icons/bloom/60.png new file mode 100644 index 000000000..0a5c97ee3 Binary files /dev/null and b/assets/static/icons/bloom/60.png differ diff --git a/assets/static/icons/bloom/64.png b/assets/static/icons/bloom/64.png new file mode 100644 index 000000000..e5ac223f6 Binary files /dev/null and b/assets/static/icons/bloom/64.png differ diff --git a/assets/static/icons/bloom/72.png b/assets/static/icons/bloom/72.png new file mode 100644 index 000000000..55597e914 Binary files /dev/null and b/assets/static/icons/bloom/72.png differ diff --git a/assets/static/icons/bloom/76.png b/assets/static/icons/bloom/76.png new file mode 100644 index 000000000..40f5646b6 Binary files /dev/null and b/assets/static/icons/bloom/76.png differ diff --git a/assets/static/icons/bloom/80.png b/assets/static/icons/bloom/80.png new file mode 100644 index 000000000..8748add36 Binary files /dev/null and b/assets/static/icons/bloom/80.png differ diff --git a/assets/static/icons/bloom/maskable/192.png b/assets/static/icons/bloom/maskable/192.png new file mode 100644 index 000000000..8509e68b1 Binary files /dev/null and b/assets/static/icons/bloom/maskable/192.png differ diff --git a/assets/static/icons/bloom/maskable/512.png b/assets/static/icons/bloom/maskable/512.png new file mode 100644 index 000000000..0fa8807ba Binary files /dev/null and b/assets/static/icons/bloom/maskable/512.png differ diff --git a/assets/static/icons/bold.svg b/assets/static/icons/bold.svg index 2c60c5021..f7ebb83d0 100644 --- a/assets/static/icons/bold.svg +++ b/assets/static/icons/bold.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/static/icons/bold/maskable/192.png b/assets/static/icons/bold/maskable/192.png new file mode 100644 index 000000000..caccc9108 Binary files /dev/null and b/assets/static/icons/bold/maskable/192.png differ diff --git a/assets/static/icons/bold/maskable/512.png b/assets/static/icons/bold/maskable/512.png new file mode 100644 index 000000000..1bc801990 Binary files /dev/null and b/assets/static/icons/bold/maskable/512.png differ diff --git a/assets/static/icons/crisp.svg b/assets/static/icons/crisp.svg index 24d1adbe8..9d7133a1e 100644 --- a/assets/static/icons/crisp.svg +++ b/assets/static/icons/crisp.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/static/icons/crisp/maskable/192.png b/assets/static/icons/crisp/maskable/192.png new file mode 100644 index 000000000..0760a5cdd Binary files /dev/null and b/assets/static/icons/crisp/maskable/192.png differ diff --git a/assets/static/icons/crisp/maskable/512.png b/assets/static/icons/crisp/maskable/512.png new file mode 100644 index 000000000..32c5e59a8 Binary files /dev/null and b/assets/static/icons/crisp/maskable/512.png differ diff --git a/assets/static/icons/flower.svg b/assets/static/icons/flower.svg new file mode 100644 index 000000000..e53141dec --- /dev/null +++ b/assets/static/icons/flower.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/static/icons/flower/100.png b/assets/static/icons/flower/100.png new file mode 100644 index 000000000..334921d48 Binary files /dev/null and b/assets/static/icons/flower/100.png differ diff --git a/assets/static/icons/flower/1024.png b/assets/static/icons/flower/1024.png new file mode 100644 index 000000000..9858808e5 Binary files /dev/null and b/assets/static/icons/flower/1024.png differ diff --git a/assets/static/icons/flower/114.png b/assets/static/icons/flower/114.png new file mode 100644 index 000000000..f17df1f7c Binary files /dev/null and b/assets/static/icons/flower/114.png differ diff --git a/assets/static/icons/flower/120.png b/assets/static/icons/flower/120.png new file mode 100644 index 000000000..429ffd4c8 Binary files /dev/null and b/assets/static/icons/flower/120.png differ diff --git a/assets/static/icons/flower/128.png b/assets/static/icons/flower/128.png new file mode 100644 index 000000000..39538a066 Binary files /dev/null and b/assets/static/icons/flower/128.png differ diff --git a/assets/static/icons/flower/144.png b/assets/static/icons/flower/144.png new file mode 100644 index 000000000..774d41524 Binary files /dev/null and b/assets/static/icons/flower/144.png differ diff --git a/assets/static/icons/flower/152.png b/assets/static/icons/flower/152.png new file mode 100644 index 000000000..bb87d5fbd Binary files /dev/null and b/assets/static/icons/flower/152.png differ diff --git a/assets/static/icons/flower/16.png b/assets/static/icons/flower/16.png new file mode 100644 index 000000000..6a7f6fb3d Binary files /dev/null and b/assets/static/icons/flower/16.png differ diff --git a/assets/static/icons/flower/160.png b/assets/static/icons/flower/160.png new file mode 100644 index 000000000..aef462487 Binary files /dev/null and b/assets/static/icons/flower/160.png differ diff --git a/assets/static/icons/flower/167.png b/assets/static/icons/flower/167.png new file mode 100644 index 000000000..f9fd23acb Binary files /dev/null and b/assets/static/icons/flower/167.png differ diff --git a/assets/static/icons/flower/172.png b/assets/static/icons/flower/172.png new file mode 100644 index 000000000..a59f3e98c Binary files /dev/null and b/assets/static/icons/flower/172.png differ diff --git a/assets/static/icons/flower/175.png b/assets/static/icons/flower/175.png new file mode 100644 index 000000000..88128ebf8 Binary files /dev/null and b/assets/static/icons/flower/175.png differ diff --git a/assets/static/icons/flower/180.png b/assets/static/icons/flower/180.png new file mode 100644 index 000000000..133baa657 Binary files /dev/null and b/assets/static/icons/flower/180.png differ diff --git a/assets/static/icons/flower/192.png b/assets/static/icons/flower/192.png new file mode 100644 index 000000000..1b1a001bc Binary files /dev/null and b/assets/static/icons/flower/192.png differ diff --git a/assets/static/icons/flower/196.png b/assets/static/icons/flower/196.png new file mode 100644 index 000000000..c07d27f5c Binary files /dev/null and b/assets/static/icons/flower/196.png differ diff --git a/assets/static/icons/flower/20.png b/assets/static/icons/flower/20.png new file mode 100644 index 000000000..9869b8623 Binary files /dev/null and b/assets/static/icons/flower/20.png differ diff --git a/assets/static/icons/flower/200.png b/assets/static/icons/flower/200.png new file mode 100644 index 000000000..393749059 Binary files /dev/null and b/assets/static/icons/flower/200.png differ diff --git a/assets/static/icons/flower/216.png b/assets/static/icons/flower/216.png new file mode 100644 index 000000000..795318931 Binary files /dev/null and b/assets/static/icons/flower/216.png differ diff --git a/assets/static/icons/flower/256.png b/assets/static/icons/flower/256.png new file mode 100644 index 000000000..7955f3eb0 Binary files /dev/null and b/assets/static/icons/flower/256.png differ diff --git a/assets/static/icons/flower/267.png b/assets/static/icons/flower/267.png new file mode 100644 index 000000000..4a52ef9ca Binary files /dev/null and b/assets/static/icons/flower/267.png differ diff --git a/assets/static/icons/flower/29.png b/assets/static/icons/flower/29.png new file mode 100644 index 000000000..6cea5049f Binary files /dev/null and b/assets/static/icons/flower/29.png differ diff --git a/assets/static/icons/flower/32.png b/assets/static/icons/flower/32.png new file mode 100644 index 000000000..4890afe5a Binary files /dev/null and b/assets/static/icons/flower/32.png differ diff --git a/assets/static/icons/flower/40.png b/assets/static/icons/flower/40.png new file mode 100644 index 000000000..04a1c9d3f Binary files /dev/null and b/assets/static/icons/flower/40.png differ diff --git a/assets/static/icons/flower/400.png b/assets/static/icons/flower/400.png new file mode 100644 index 000000000..23fc2ed79 Binary files /dev/null and b/assets/static/icons/flower/400.png differ diff --git a/assets/static/icons/flower/48.png b/assets/static/icons/flower/48.png new file mode 100644 index 000000000..b09bfa248 Binary files /dev/null and b/assets/static/icons/flower/48.png differ diff --git a/assets/static/icons/flower/50.png b/assets/static/icons/flower/50.png new file mode 100644 index 000000000..f96163474 Binary files /dev/null and b/assets/static/icons/flower/50.png differ diff --git a/assets/static/icons/flower/512.png b/assets/static/icons/flower/512.png new file mode 100644 index 000000000..2b42c07ca Binary files /dev/null and b/assets/static/icons/flower/512.png differ diff --git a/assets/static/icons/flower/55.png b/assets/static/icons/flower/55.png new file mode 100644 index 000000000..e72cc0ae1 Binary files /dev/null and b/assets/static/icons/flower/55.png differ diff --git a/assets/static/icons/flower/56.png b/assets/static/icons/flower/56.png new file mode 100644 index 000000000..ac4433d45 Binary files /dev/null and b/assets/static/icons/flower/56.png differ diff --git a/assets/static/icons/flower/60.png b/assets/static/icons/flower/60.png new file mode 100644 index 000000000..66033b7cd Binary files /dev/null and b/assets/static/icons/flower/60.png differ diff --git a/assets/static/icons/flower/64.png b/assets/static/icons/flower/64.png new file mode 100644 index 000000000..b5276b945 Binary files /dev/null and b/assets/static/icons/flower/64.png differ diff --git a/assets/static/icons/flower/72.png b/assets/static/icons/flower/72.png new file mode 100644 index 000000000..7a8c1ea59 Binary files /dev/null and b/assets/static/icons/flower/72.png differ diff --git a/assets/static/icons/flower/76.png b/assets/static/icons/flower/76.png new file mode 100644 index 000000000..3342ea360 Binary files /dev/null and b/assets/static/icons/flower/76.png differ diff --git a/assets/static/icons/flower/80.png b/assets/static/icons/flower/80.png new file mode 100644 index 000000000..c742673ae Binary files /dev/null and b/assets/static/icons/flower/80.png differ diff --git a/assets/static/icons/flower/maskable/192.png b/assets/static/icons/flower/maskable/192.png new file mode 100644 index 000000000..d93f44e23 Binary files /dev/null and b/assets/static/icons/flower/maskable/192.png differ diff --git a/assets/static/icons/flower/maskable/512.png b/assets/static/icons/flower/maskable/512.png new file mode 100644 index 000000000..dc45a123a Binary files /dev/null and b/assets/static/icons/flower/maskable/512.png differ diff --git a/assets/static/icons/logo.svg b/assets/static/icons/logo.svg index eefa5cde4..9b77f9817 100644 --- a/assets/static/icons/logo.svg +++ b/assets/static/icons/logo.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/static/icons/logo/maskable/192.png b/assets/static/icons/logo/maskable/192.png new file mode 100644 index 000000000..d377ae492 Binary files /dev/null and b/assets/static/icons/logo/maskable/192.png differ diff --git a/assets/static/icons/logo/maskable/512.png b/assets/static/icons/logo/maskable/512.png new file mode 100644 index 000000000..9c625a4af Binary files /dev/null and b/assets/static/icons/logo/maskable/512.png differ diff --git a/assets/static/icons/mint.svg b/assets/static/icons/mint.svg index f02e9a793..e78e94af0 100644 --- a/assets/static/icons/mint.svg +++ b/assets/static/icons/mint.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/static/icons/mint/maskable/192.png b/assets/static/icons/mint/maskable/192.png new file mode 100644 index 000000000..4f6ddc3d6 Binary files /dev/null and b/assets/static/icons/mint/maskable/192.png differ diff --git a/assets/static/icons/mint/maskable/512.png b/assets/static/icons/mint/maskable/512.png new file mode 100644 index 000000000..01d26debf Binary files /dev/null and b/assets/static/icons/mint/maskable/512.png differ diff --git a/assets/static/icons/ring.svg b/assets/static/icons/ring.svg new file mode 100644 index 000000000..37a1ba85b --- /dev/null +++ b/assets/static/icons/ring.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/static/icons/ring/100.png b/assets/static/icons/ring/100.png new file mode 100644 index 000000000..d02e206f4 Binary files /dev/null and b/assets/static/icons/ring/100.png differ diff --git a/assets/static/icons/ring/1024.png b/assets/static/icons/ring/1024.png new file mode 100644 index 000000000..7f504ed9a Binary files /dev/null and b/assets/static/icons/ring/1024.png differ diff --git a/assets/static/icons/ring/114.png b/assets/static/icons/ring/114.png new file mode 100644 index 000000000..c46bb17fa Binary files /dev/null and b/assets/static/icons/ring/114.png differ diff --git a/assets/static/icons/ring/120.png b/assets/static/icons/ring/120.png new file mode 100644 index 000000000..2e0805eca Binary files /dev/null and b/assets/static/icons/ring/120.png differ diff --git a/assets/static/icons/ring/128.png b/assets/static/icons/ring/128.png new file mode 100644 index 000000000..46cebce21 Binary files /dev/null and b/assets/static/icons/ring/128.png differ diff --git a/assets/static/icons/ring/144.png b/assets/static/icons/ring/144.png new file mode 100644 index 000000000..06093c0ac Binary files /dev/null and b/assets/static/icons/ring/144.png differ diff --git a/assets/static/icons/ring/152.png b/assets/static/icons/ring/152.png new file mode 100644 index 000000000..88402d14d Binary files /dev/null and b/assets/static/icons/ring/152.png differ diff --git a/assets/static/icons/ring/16.png b/assets/static/icons/ring/16.png new file mode 100644 index 000000000..2aa8543e4 Binary files /dev/null and b/assets/static/icons/ring/16.png differ diff --git a/assets/static/icons/ring/160.png b/assets/static/icons/ring/160.png new file mode 100644 index 000000000..3f008c239 Binary files /dev/null and b/assets/static/icons/ring/160.png differ diff --git a/assets/static/icons/ring/167.png b/assets/static/icons/ring/167.png new file mode 100644 index 000000000..9373edc7d Binary files /dev/null and b/assets/static/icons/ring/167.png differ diff --git a/assets/static/icons/ring/172.png b/assets/static/icons/ring/172.png new file mode 100644 index 000000000..2d3b54e90 Binary files /dev/null and b/assets/static/icons/ring/172.png differ diff --git a/assets/static/icons/ring/175.png b/assets/static/icons/ring/175.png new file mode 100644 index 000000000..8206d3f71 Binary files /dev/null and b/assets/static/icons/ring/175.png differ diff --git a/assets/static/icons/ring/180.png b/assets/static/icons/ring/180.png new file mode 100644 index 000000000..c5c5f9873 Binary files /dev/null and b/assets/static/icons/ring/180.png differ diff --git a/assets/static/icons/ring/192.png b/assets/static/icons/ring/192.png new file mode 100644 index 000000000..e12f8ab7c Binary files /dev/null and b/assets/static/icons/ring/192.png differ diff --git a/assets/static/icons/ring/196.png b/assets/static/icons/ring/196.png new file mode 100644 index 000000000..2fd4f1024 Binary files /dev/null and b/assets/static/icons/ring/196.png differ diff --git a/assets/static/icons/ring/20.png b/assets/static/icons/ring/20.png new file mode 100644 index 000000000..38642f28e Binary files /dev/null and b/assets/static/icons/ring/20.png differ diff --git a/assets/static/icons/ring/200.png b/assets/static/icons/ring/200.png new file mode 100644 index 000000000..aaaadd912 Binary files /dev/null and b/assets/static/icons/ring/200.png differ diff --git a/assets/static/icons/ring/216.png b/assets/static/icons/ring/216.png new file mode 100644 index 000000000..f21875a4d Binary files /dev/null and b/assets/static/icons/ring/216.png differ diff --git a/assets/static/icons/ring/256.png b/assets/static/icons/ring/256.png new file mode 100644 index 000000000..b43ca2f39 Binary files /dev/null and b/assets/static/icons/ring/256.png differ diff --git a/assets/static/icons/ring/267.png b/assets/static/icons/ring/267.png new file mode 100644 index 000000000..080e281d9 Binary files /dev/null and b/assets/static/icons/ring/267.png differ diff --git a/assets/static/icons/ring/29.png b/assets/static/icons/ring/29.png new file mode 100644 index 000000000..6e2f03246 Binary files /dev/null and b/assets/static/icons/ring/29.png differ diff --git a/assets/static/icons/ring/32.png b/assets/static/icons/ring/32.png new file mode 100644 index 000000000..b333a7554 Binary files /dev/null and b/assets/static/icons/ring/32.png differ diff --git a/assets/static/icons/ring/40.png b/assets/static/icons/ring/40.png new file mode 100644 index 000000000..d0eaad87e Binary files /dev/null and b/assets/static/icons/ring/40.png differ diff --git a/assets/static/icons/ring/400.png b/assets/static/icons/ring/400.png new file mode 100644 index 000000000..0323a8d5a Binary files /dev/null and b/assets/static/icons/ring/400.png differ diff --git a/assets/static/icons/ring/48.png b/assets/static/icons/ring/48.png new file mode 100644 index 000000000..ba311055c Binary files /dev/null and b/assets/static/icons/ring/48.png differ diff --git a/assets/static/icons/ring/50.png b/assets/static/icons/ring/50.png new file mode 100644 index 000000000..57844b771 Binary files /dev/null and b/assets/static/icons/ring/50.png differ diff --git a/assets/static/icons/ring/512.png b/assets/static/icons/ring/512.png new file mode 100644 index 000000000..a7d689856 Binary files /dev/null and b/assets/static/icons/ring/512.png differ diff --git a/assets/static/icons/ring/55.png b/assets/static/icons/ring/55.png new file mode 100644 index 000000000..f5a940af6 Binary files /dev/null and b/assets/static/icons/ring/55.png differ diff --git a/assets/static/icons/ring/56.png b/assets/static/icons/ring/56.png new file mode 100644 index 000000000..0f3f3ffae Binary files /dev/null and b/assets/static/icons/ring/56.png differ diff --git a/assets/static/icons/ring/60.png b/assets/static/icons/ring/60.png new file mode 100644 index 000000000..527ef571d Binary files /dev/null and b/assets/static/icons/ring/60.png differ diff --git a/assets/static/icons/ring/64.png b/assets/static/icons/ring/64.png new file mode 100644 index 000000000..6f9fbe250 Binary files /dev/null and b/assets/static/icons/ring/64.png differ diff --git a/assets/static/icons/ring/72.png b/assets/static/icons/ring/72.png new file mode 100644 index 000000000..714421c8a Binary files /dev/null and b/assets/static/icons/ring/72.png differ diff --git a/assets/static/icons/ring/76.png b/assets/static/icons/ring/76.png new file mode 100644 index 000000000..79c76f225 Binary files /dev/null and b/assets/static/icons/ring/76.png differ diff --git a/assets/static/icons/ring/80.png b/assets/static/icons/ring/80.png new file mode 100644 index 000000000..62a611ffd Binary files /dev/null and b/assets/static/icons/ring/80.png differ diff --git a/assets/static/icons/ring/maskable/192.png b/assets/static/icons/ring/maskable/192.png new file mode 100644 index 000000000..9d0a13264 Binary files /dev/null and b/assets/static/icons/ring/maskable/192.png differ diff --git a/assets/static/icons/ring/maskable/512.png b/assets/static/icons/ring/maskable/512.png new file mode 100644 index 000000000..3fd39ef0a Binary files /dev/null and b/assets/static/icons/ring/maskable/512.png differ diff --git a/assets/static/icons/shutter.svg b/assets/static/icons/shutter.svg new file mode 100644 index 000000000..df7d44caa --- /dev/null +++ b/assets/static/icons/shutter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/static/icons/shutter/100.png b/assets/static/icons/shutter/100.png new file mode 100644 index 000000000..d21876a1a Binary files /dev/null and b/assets/static/icons/shutter/100.png differ diff --git a/assets/static/icons/shutter/1024.png b/assets/static/icons/shutter/1024.png new file mode 100644 index 000000000..05d142a51 Binary files /dev/null and b/assets/static/icons/shutter/1024.png differ diff --git a/assets/static/icons/shutter/114.png b/assets/static/icons/shutter/114.png new file mode 100644 index 000000000..bf01fc249 Binary files /dev/null and b/assets/static/icons/shutter/114.png differ diff --git a/assets/static/icons/shutter/120.png b/assets/static/icons/shutter/120.png new file mode 100644 index 000000000..b4345b1ab Binary files /dev/null and b/assets/static/icons/shutter/120.png differ diff --git a/assets/static/icons/shutter/128.png b/assets/static/icons/shutter/128.png new file mode 100644 index 000000000..6117279d8 Binary files /dev/null and b/assets/static/icons/shutter/128.png differ diff --git a/assets/static/icons/shutter/144.png b/assets/static/icons/shutter/144.png new file mode 100644 index 000000000..7e94dc3c7 Binary files /dev/null and b/assets/static/icons/shutter/144.png differ diff --git a/assets/static/icons/shutter/152.png b/assets/static/icons/shutter/152.png new file mode 100644 index 000000000..722ea6a58 Binary files /dev/null and b/assets/static/icons/shutter/152.png differ diff --git a/assets/static/icons/shutter/16.png b/assets/static/icons/shutter/16.png new file mode 100644 index 000000000..7857de97c Binary files /dev/null and b/assets/static/icons/shutter/16.png differ diff --git a/assets/static/icons/shutter/160.png b/assets/static/icons/shutter/160.png new file mode 100644 index 000000000..6fa8a66ed Binary files /dev/null and b/assets/static/icons/shutter/160.png differ diff --git a/assets/static/icons/shutter/167.png b/assets/static/icons/shutter/167.png new file mode 100644 index 000000000..3863b6048 Binary files /dev/null and b/assets/static/icons/shutter/167.png differ diff --git a/assets/static/icons/shutter/172.png b/assets/static/icons/shutter/172.png new file mode 100644 index 000000000..e0cd512cb Binary files /dev/null and b/assets/static/icons/shutter/172.png differ diff --git a/assets/static/icons/shutter/175.png b/assets/static/icons/shutter/175.png new file mode 100644 index 000000000..f7e12716d Binary files /dev/null and b/assets/static/icons/shutter/175.png differ diff --git a/assets/static/icons/shutter/180.png b/assets/static/icons/shutter/180.png new file mode 100644 index 000000000..ff6962023 Binary files /dev/null and b/assets/static/icons/shutter/180.png differ diff --git a/assets/static/icons/shutter/192.png b/assets/static/icons/shutter/192.png new file mode 100644 index 000000000..e6f3067ad Binary files /dev/null and b/assets/static/icons/shutter/192.png differ diff --git a/assets/static/icons/shutter/196.png b/assets/static/icons/shutter/196.png new file mode 100644 index 000000000..51792e7dc Binary files /dev/null and b/assets/static/icons/shutter/196.png differ diff --git a/assets/static/icons/shutter/20.png b/assets/static/icons/shutter/20.png new file mode 100644 index 000000000..e91dc2276 Binary files /dev/null and b/assets/static/icons/shutter/20.png differ diff --git a/assets/static/icons/shutter/200.png b/assets/static/icons/shutter/200.png new file mode 100644 index 000000000..0eef32efa Binary files /dev/null and b/assets/static/icons/shutter/200.png differ diff --git a/assets/static/icons/shutter/216.png b/assets/static/icons/shutter/216.png new file mode 100644 index 000000000..a2e182eaa Binary files /dev/null and b/assets/static/icons/shutter/216.png differ diff --git a/assets/static/icons/shutter/256.png b/assets/static/icons/shutter/256.png new file mode 100644 index 000000000..afbc9805d Binary files /dev/null and b/assets/static/icons/shutter/256.png differ diff --git a/assets/static/icons/shutter/267.png b/assets/static/icons/shutter/267.png new file mode 100644 index 000000000..de8f45bfe Binary files /dev/null and b/assets/static/icons/shutter/267.png differ diff --git a/assets/static/icons/shutter/29.png b/assets/static/icons/shutter/29.png new file mode 100644 index 000000000..4b9a4e465 Binary files /dev/null and b/assets/static/icons/shutter/29.png differ diff --git a/assets/static/icons/shutter/32.png b/assets/static/icons/shutter/32.png new file mode 100644 index 000000000..91ed96306 Binary files /dev/null and b/assets/static/icons/shutter/32.png differ diff --git a/assets/static/icons/shutter/40.png b/assets/static/icons/shutter/40.png new file mode 100644 index 000000000..a89499e15 Binary files /dev/null and b/assets/static/icons/shutter/40.png differ diff --git a/assets/static/icons/shutter/400.png b/assets/static/icons/shutter/400.png new file mode 100644 index 000000000..52b4fe19b Binary files /dev/null and b/assets/static/icons/shutter/400.png differ diff --git a/assets/static/icons/shutter/48.png b/assets/static/icons/shutter/48.png new file mode 100644 index 000000000..403d4b8cc Binary files /dev/null and b/assets/static/icons/shutter/48.png differ diff --git a/assets/static/icons/shutter/50.png b/assets/static/icons/shutter/50.png new file mode 100644 index 000000000..b6b4d3f87 Binary files /dev/null and b/assets/static/icons/shutter/50.png differ diff --git a/assets/static/icons/shutter/512.png b/assets/static/icons/shutter/512.png new file mode 100644 index 000000000..5524decbb Binary files /dev/null and b/assets/static/icons/shutter/512.png differ diff --git a/assets/static/icons/shutter/55.png b/assets/static/icons/shutter/55.png new file mode 100644 index 000000000..3df91b060 Binary files /dev/null and b/assets/static/icons/shutter/55.png differ diff --git a/assets/static/icons/shutter/56.png b/assets/static/icons/shutter/56.png new file mode 100644 index 000000000..7224951ba Binary files /dev/null and b/assets/static/icons/shutter/56.png differ diff --git a/assets/static/icons/shutter/60.png b/assets/static/icons/shutter/60.png new file mode 100644 index 000000000..f34694e1e Binary files /dev/null and b/assets/static/icons/shutter/60.png differ diff --git a/assets/static/icons/shutter/64.png b/assets/static/icons/shutter/64.png new file mode 100644 index 000000000..e7002ec3d Binary files /dev/null and b/assets/static/icons/shutter/64.png differ diff --git a/assets/static/icons/shutter/72.png b/assets/static/icons/shutter/72.png new file mode 100644 index 000000000..0b9b09e74 Binary files /dev/null and b/assets/static/icons/shutter/72.png differ diff --git a/assets/static/icons/shutter/76.png b/assets/static/icons/shutter/76.png new file mode 100644 index 000000000..8fbe973f5 Binary files /dev/null and b/assets/static/icons/shutter/76.png differ diff --git a/assets/static/icons/shutter/80.png b/assets/static/icons/shutter/80.png new file mode 100644 index 000000000..083f18d8a Binary files /dev/null and b/assets/static/icons/shutter/80.png differ diff --git a/assets/static/icons/shutter/maskable/192.png b/assets/static/icons/shutter/maskable/192.png new file mode 100644 index 000000000..33afdda95 Binary files /dev/null and b/assets/static/icons/shutter/maskable/192.png differ diff --git a/assets/static/icons/shutter/maskable/512.png b/assets/static/icons/shutter/maskable/512.png new file mode 100644 index 000000000..f87fc4ea4 Binary files /dev/null and b/assets/static/icons/shutter/maskable/512.png differ diff --git a/assets/static/icons/square.svg b/assets/static/icons/square.svg index 31c513e43..885a9fc63 100644 --- a/assets/static/icons/square.svg +++ b/assets/static/icons/square.svg @@ -1,13 +1 @@ - - - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/assets/static/icons/square/maskable/192.png b/assets/static/icons/square/maskable/192.png new file mode 100644 index 000000000..227e932ae Binary files /dev/null and b/assets/static/icons/square/maskable/192.png differ diff --git a/assets/static/icons/square/maskable/512.png b/assets/static/icons/square/maskable/512.png new file mode 100644 index 000000000..05f58c016 Binary files /dev/null and b/assets/static/icons/square/maskable/512.png differ diff --git a/assets/static/img/screenshots/narrow.jpg b/assets/static/img/screenshots/narrow.jpg new file mode 100644 index 000000000..93dc03ff2 Binary files /dev/null and b/assets/static/img/screenshots/narrow.jpg differ diff --git a/assets/static/img/screenshots/wide.jpg b/assets/static/img/screenshots/wide.jpg new file mode 100644 index 000000000..2cd9be15f Binary files /dev/null and b/assets/static/img/screenshots/wide.jpg differ diff --git a/assets/templates/404.gohtml b/assets/templates/404.gohtml index 26d9fc057..12d6d98b8 100644 --- a/assets/templates/404.gohtml +++ b/assets/templates/404.gohtml @@ -26,7 +26,7 @@ .e973c102-193a-465f-a6ce-238077277871{stroke:#efefef;stroke-miterlimit:10;stroke-width:5px;} .f5ddff88-48c1-46f9-a031-aee9bce94bd6{clip-path:url(#a1251993-bbf1-4548-8238-fa794c0bb4e3);} .ead6f749-dce3-444a-a4f2-acc8f3078dec{clip-path:url(#be2d8169-fac1-479f-9595-ff9fe03b48a4);} - .a34fac52-8499-4455-a7f4-105abc9df09b,.f18ba0a9-054f-4ae5-b0d0-1c52cbadb98f{font-size:63px;fill:#efefef;} + .a34fac52-8499-4455-a7f4-105abc9df09b,.f18ba0a9-054f-4ae5-b0d0-1c52cbadb98f{font-size:63px;fill:#efefef;direction:ltr;} .a34fac52-8499-4455-a7f4-105abc9df09b{font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";} .beccc81f-4365-4373-9899-0d823daf22a9{letter-spacing:0.01em;} .f18ba0a9-054f-4ae5-b0d0-1c52cbadb98f{font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";font-weight:300;letter-spacing:0em;} diff --git a/assets/templates/auth.gohtml b/assets/templates/auth.gohtml index 51b3cad56..8ac4ef709 100644 --- a/assets/templates/auth.gohtml +++ b/assets/templates/auth.gohtml @@ -30,6 +30,8 @@ "session.provider", "session.scope", "session.error", + "session.messageId", + "session.messageParams", ]; const storages = [localStorage, sessionStorage].filter(Boolean); const preferredStorage = @@ -48,27 +50,23 @@ const setItem = (key, value) => { preferredStorage.setItem(namespacedKey(key), value); }; - const removeItem = (key) => { - storages.forEach((storage) => storage.removeItem(namespacedKey(key))); - }; + {{/* clearSessionData() removes every session.* key (including session.error, + session.messageId, and session.messageParams), so each branch only sets + the keys it wants to persist. */}} {{ if eq .status "success" }} clearSessionData(); setItem("session.id", {{ .session_id }}); setItem("session.token", {{ .access_token }}); setItem("session.provider", {{ .provider }}); setItem("session.user", JSON.stringify({{ .user }})); - removeItem("session.error"); {{ else if eq .status "failed" }} clearSessionData(); setItem("session.error", {{ .error }}); + {{ if .messageId }}setItem("session.messageId", {{ .messageId }});{{ end }} + {{ if .messageParams }}setItem("session.messageParams", JSON.stringify({{ .messageParams }}));{{ end }} {{ else }} clearSessionData(); - removeItem("session.id"); - removeItem("session.token"); - removeItem("session.provider"); - removeItem("session.user"); - removeItem("session.error"); {{ end }} })(); window.location.href = {{ .config.LoginUri }}; diff --git a/assets/templates/oauth-error.gohtml b/assets/templates/oauth-error.gohtml new file mode 100644 index 000000000..835752c2e --- /dev/null +++ b/assets/templates/oauth-error.gohtml @@ -0,0 +1,34 @@ + + + + + + + + {{ .error }} – {{if and .config.SiteCaption .config.Sponsor }}{{ .config.SiteCaption }}{{else}}{{ .config.Name }}{{end}} + +{{template "favicons.gohtml" .}} +{{template "styles.gohtml" .}} + + + + +
+
+
+ +
+
+
+ + diff --git a/cmd/photoprism/photoprism.go b/cmd/photoprism/photoprism.go index 8b94cf90a..d849b4c84 100644 --- a/cmd/photoprism/photoprism.go +++ b/cmd/photoprism/photoprism.go @@ -12,7 +12,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. @@ -23,6 +23,7 @@ Additional information can be found in our Developer Guide: package main import ( + "fmt" "os" "github.com/urfave/cli/v2" @@ -33,7 +34,6 @@ import ( ) var version = "development" -var log = event.Log const appName = "PhotoPrism" const appAbout = "PhotoPrism®" @@ -55,6 +55,7 @@ var Metadata = map[string]any{ func main() { defer func() { if r := recover(); r != nil { + event.LogPanic(r) os.Exit(1) } }() @@ -69,7 +70,10 @@ func main() { app.Commands = commands.PhotoPrism app.Metadata = Metadata + // urfave/cli prints and exits with the code of any cli.Exit(...) error + // before returning here, so only plain errors reach this point; report + // them on stderr without forcing a specific exit code. if err := app.Run(os.Args); err != nil { - log.Error(err) + _, _ = fmt.Fprintln(os.Stderr, err) } } diff --git a/compose.intel.yaml b/compose.intel.yaml index bf95c530f..1bce61af7 100644 --- a/compose.intel.yaml +++ b/compose.intel.yaml @@ -67,6 +67,7 @@ services: PHOTOPRISM_OIDC_URI: "https://keycloak.localssl.dev/realms/master" PHOTOPRISM_OIDC_CLIENT: "photoprism-develop" PHOTOPRISM_OIDC_SECRET: "9d8351a0-ca01-4556-9c37-85eb634869b9" + PHOTOPRISM_OIDC_PROMPT: "" # authorization prompt: login, select_account, or consent (empty = seamless SSO) PHOTOPRISM_OIDC_PROVIDER: "Keycloak" PHOTOPRISM_OIDC_REGISTER: "true" PHOTOPRISM_OIDC_WEBDAV: "true" @@ -87,9 +88,10 @@ services: PHOTOPRISM_DEFAULT_TLS: "true" ## Site Information: PHOTOPRISM_SITE_URL: "https://app.localssl.dev/" # server URL in the format "http(s)://domain.name(:port)/(path)" - PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App" - PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" - PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" + PHOTOPRISM_SITE_NAME: "" # short name for identifying this instance within a cluster + PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App" # short caption or tagline shown alongside the title + PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" # longer description shown in SEO and social meta tags + PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" # site owner shown in the author meta tag PHOTOPRISM_DEBUG: "true" PHOTOPRISM_READONLY: "false" PHOTOPRISM_EXPERIMENTAL: "true" diff --git a/compose.latest.yaml b/compose.latest.yaml index 52bec2171..05b03509b 100644 --- a/compose.latest.yaml +++ b/compose.latest.yaml @@ -27,9 +27,10 @@ services: PHOTOPRISM_ADMIN_PASSWORD: "photoprism" # initial admin password (8-72 characters) PHOTOPRISM_AUTH_MODE: "password" # authentication mode (public, password) PHOTOPRISM_SITE_URL: "https://latest.localssl.dev/" # server URL in the format "http(s)://domain.name(:port)/(path)" - PHOTOPRISM_SITE_CAPTION: "Latest" - PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" - PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" + PHOTOPRISM_SITE_NAME: "" # short name for identifying this instance within a cluster + PHOTOPRISM_SITE_CAPTION: "Latest" # short caption or tagline shown alongside the title + PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" # longer description shown in SEO and social meta tags + PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" # site owner shown in the author meta tag PHOTOPRISM_DEBUG: "true" PHOTOPRISM_READONLY: "false" PHOTOPRISM_EXPERIMENTAL: "false" diff --git a/compose.nvidia.yaml b/compose.nvidia.yaml index e27c07349..12e47f8d1 100644 --- a/compose.nvidia.yaml +++ b/compose.nvidia.yaml @@ -70,6 +70,7 @@ services: PHOTOPRISM_OIDC_URI: "https://keycloak.localssl.dev/realms/master" PHOTOPRISM_OIDC_CLIENT: "photoprism-develop" PHOTOPRISM_OIDC_SECRET: "9d8351a0-ca01-4556-9c37-85eb634869b9" + PHOTOPRISM_OIDC_PROMPT: "" # authorization prompt: login, select_account, or consent (empty = seamless SSO) PHOTOPRISM_OIDC_PROVIDER: "Keycloak" PHOTOPRISM_OIDC_REGISTER: "true" PHOTOPRISM_OIDC_WEBDAV: "true" @@ -90,9 +91,10 @@ services: PHOTOPRISM_DEFAULT_TLS: "true" ## Site Information: PHOTOPRISM_SITE_URL: "https://app.localssl.dev/" # server URL in the format "http(s)://domain.name(:port)/(path)" - PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App" - PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" - PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" + PHOTOPRISM_SITE_NAME: "" # short name for identifying this instance within a cluster + PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App" # short caption or tagline shown alongside the title + PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" # longer description shown in SEO and social meta tags + PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" # site owner shown in the author meta tag PHOTOPRISM_DEBUG: "true" PHOTOPRISM_READONLY: "false" PHOTOPRISM_EXPERIMENTAL: "true" diff --git a/compose.preview.yaml b/compose.preview.yaml index d67c51340..3168a5adc 100644 --- a/compose.preview.yaml +++ b/compose.preview.yaml @@ -27,9 +27,10 @@ services: PHOTOPRISM_ADMIN_PASSWORD: "photoprism" # initial admin password (8-72 characters) PHOTOPRISM_AUTH_MODE: "password" # authentication mode (public, password) PHOTOPRISM_SITE_URL: "https://preview.localssl.dev/" # server URL in the format "http(s)://domain.name(:port)/(path)" - PHOTOPRISM_SITE_CAPTION: "Preview" - PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" - PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" + PHOTOPRISM_SITE_NAME: "" # short name for identifying this instance within a cluster + PHOTOPRISM_SITE_CAPTION: "Preview" # short caption or tagline shown alongside the title + PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" # longer description shown in SEO and social meta tags + PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" # site owner shown in the author meta tag PHOTOPRISM_DEBUG: "true" PHOTOPRISM_READONLY: "false" PHOTOPRISM_EXPERIMENTAL: "false" diff --git a/compose.yaml b/compose.yaml index 1eae3ddf5..c0a33880a 100644 --- a/compose.yaml +++ b/compose.yaml @@ -74,6 +74,7 @@ services: PHOTOPRISM_OIDC_URI: "https://keycloak.localssl.dev/realms/master" PHOTOPRISM_OIDC_CLIENT: "photoprism-develop" PHOTOPRISM_OIDC_SECRET: "9d8351a0-ca01-4556-9c37-85eb634869b9" + PHOTOPRISM_OIDC_PROMPT: "" # authorization prompt: login, select_account, or consent (empty = seamless SSO) PHOTOPRISM_OIDC_PROVIDER: "Keycloak" PHOTOPRISM_OIDC_REGISTER: "true" PHOTOPRISM_OIDC_WEBDAV: "true" @@ -94,9 +95,10 @@ services: PHOTOPRISM_DEFAULT_TLS: "true" ## Site Information: PHOTOPRISM_SITE_URL: "${PHOTOPRISM_SITE_URL:-https://app.localssl.dev/}" # "http(s)://domain.name(:port)/(path)" - PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App" - PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" - PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" + PHOTOPRISM_SITE_NAME: "" # short name for identifying this instance within a cluster + PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App" # short caption or tagline shown alongside the title + PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" # longer description shown in SEO and social meta tags + PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" # site owner shown in the author meta tag PHOTOPRISM_DEBUG: "true" PHOTOPRISM_READONLY: "false" PHOTOPRISM_EXPERIMENTAL: "true" @@ -143,11 +145,11 @@ services: ## Run/install on first startup (options: update tensorflow https intel gpu davfs yt-dlp): PHOTOPRISM_INIT: "https" ## Computer Vision (https://docs.photoprism.app/getting-started/config-options/#computer-vision): - PHOTOPRISM_VISION_API: "true" # server: enables service API endpoints under /api/v1/vision (requires access token) - PHOTOPRISM_VISION_URI: "" # client: service URI, e.g. http://hostname/api/v1/vision (leave blank to disable) - PHOTOPRISM_VISION_KEY: "" # client: service access token (for authentication) - OLLAMA_BASE_URL: "http://ollama:11434" # use "https://ollama.com" for Ollama Cloud - OLLAMA_API_KEY: "" # API key required to access Ollama (optional) + PHOTOPRISM_VISION_API: "true" # server: enables service API endpoints under /api/v1/vision (requires access token) + PHOTOPRISM_VISION_URI: "${PHOTOPRISM_VISION_URI:-}" # client: service URI, e.g. http://hostname/api/v1/vision (leave blank to disable) + PHOTOPRISM_VISION_KEY: "${PHOTOPRISM_VISION_KEY:-}" # client: service access token (for authentication) + OLLAMA_BASE_URL: "${OLLAMA_BASE_URL:-http://ollama:11434}" # use "https://ollama.com" for Ollama Cloud + OLLAMA_API_KEY: "${OLLAMA_API_KEY:-}" # optional API key for Ollama Cloud ## Additional dependencies and tools: TF_CPP_MIN_LOG_LEVEL: 1 GOCACHE: "${WORKING_DIR:-/go/src/github.com/photoprism/photoprism}/.local/gocache" @@ -195,7 +197,7 @@ services: ## Docs: https://mariadb.com/docs/reference/ ## Release Notes: https://mariadb.com/kb/en/changes-improvements-in-mariadb-1011/ mariadb: - image: mariadb:11 + image: mariadb:12.3 stop_grace_period: 15s security_opt: # see https://github.com/MariaDB/mariadb-docker/issues/434#issuecomment-1136151239 - seccomp:unconfined diff --git a/docker/README.md b/docker/README.md index a0e5b83b9..d15849992 100644 --- a/docker/README.md +++ b/docker/README.md @@ -30,7 +30,6 @@ A virtual machine with a dedicated operating system environment provides even mo | `demo/` | Build context for the public [demo site](https://demo.photoprism.app/), including Traefik and job configuration. | | `ddns/` | Minimal image for the Dynamic DNS updater used by our hosted services. | | `dummy/` | Test doubles for OIDC and WebDAV used by acceptance tests and local development. | -| `goproxy/` | Caching Go module proxy used to speed up CI and local builds. | ### Which Image Should I Use? diff --git a/docker/demo/compose.yaml b/docker/demo/compose.yaml index 6c1ef15c4..20b1230af 100644 --- a/docker/demo/compose.yaml +++ b/docker/demo/compose.yaml @@ -17,11 +17,12 @@ services: PHOTOPRISM_PUBLIC: "true" PHOTOPRISM_SITE_URL: "https://demo.yourdomain.com/" # PHOTOPRISM_CDN_URL: "https://demo-cdn.yourdomain.com/" - PHOTOPRISM_SITE_TITLE: "PhotoPrism" - PHOTOPRISM_SITE_CAPTION: "Demo" - PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" - PHOTOPRISM_SITE_PREVIEW: "https://i.photoprism.app/logo?cover=17&title=Demo" - PHOTOPRISM_SITE_AUTHOR: "PhotoPrism" + PHOTOPRISM_SITE_NAME: "" # short name for identifying this instance within a cluster + PHOTOPRISM_SITE_TITLE: "PhotoPrism" # main title shown in the web interface and meta tags + PHOTOPRISM_SITE_CAPTION: "Demo" # short caption or tagline shown alongside the title + PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" # longer description shown in SEO and social meta tags + PHOTOPRISM_SITE_PREVIEW: "https://i.photoprism.app/logo?cover=17&title=Demo" # sharing preview image URL + PHOTOPRISM_SITE_AUTHOR: "PhotoPrism" # site owner shown in the author meta tag PHOTOPRISM_HTTP_COMPRESSION: "zstd,gzip" PHOTOPRISM_DEFAULT_LOCALE: "en" diff --git a/docker/develop/armv7/Dockerfile b/docker/develop/armv7/Dockerfile index 7a60b4dbd..b92705546 100644 --- a/docker/develop/armv7/Dockerfile +++ b/docker/develop/armv7/Dockerfile @@ -85,11 +85,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ cp -r /etc/skel/.config /root/.config && \ /scripts/install-go.sh && \ /scripts/install-go-tools.sh && \ - echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-6/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/bookworm-slim/Dockerfile b/docker/develop/bookworm-slim/Dockerfile index bf4eb1459..3641b3760 100644 --- a/docker/develop/bookworm-slim/Dockerfile +++ b/docker/develop/bookworm-slim/Dockerfile @@ -67,11 +67,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ libmatroska-dev libdvdread-dev libebml5 libgav1-bin libatomic1 \ iputils-ping dnsutils binutils binutils-gold \ && \ - echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/bookworm/Dockerfile b/docker/develop/bookworm/Dockerfile index 54657e597..2e785f025 100644 --- a/docker/develop/bookworm/Dockerfile +++ b/docker/develop/bookworm/Dockerfile @@ -95,11 +95,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-hadolint.sh && \ /scripts/install-osv-scanner.sh && \ /scripts/install-gitleaks.sh && \ - echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-6/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/bullseye-slim/Dockerfile b/docker/develop/bullseye-slim/Dockerfile index 8e0147b1f..5f196b32e 100644 --- a/docker/develop/bullseye-slim/Dockerfile +++ b/docker/develop/bullseye-slim/Dockerfile @@ -87,11 +87,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ && \ /scripts/install-mariadb.sh mariadb-client && \ /scripts/install-darktable.sh && \ - echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/bullseye/Dockerfile b/docker/develop/bullseye/Dockerfile index c49965223..efa0ef74a 100644 --- a/docker/develop/bullseye/Dockerfile +++ b/docker/develop/bullseye/Dockerfile @@ -129,11 +129,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-darktable.sh && \ /scripts/install-go-tools.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: ALL" >> /etc/sudoers.d/all && \ - echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/buster/Dockerfile b/docker/develop/buster/Dockerfile index a44a199d2..e77966c77 100644 --- a/docker/develop/buster/Dockerfile +++ b/docker/develop/buster/Dockerfile @@ -125,11 +125,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-darktable.sh && \ /scripts/install-go-tools.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: ALL" >> /etc/sudoers.d/all && \ - echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/impish/Dockerfile b/docker/develop/impish/Dockerfile index 7002af3b0..840156f2a 100644 --- a/docker/develop/impish/Dockerfile +++ b/docker/develop/impish/Dockerfile @@ -123,11 +123,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-chrome.sh && \ /scripts/install-go.sh && \ /scripts/install-go-tools.sh && \ - echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: ALL" >> /etc/sudoers.d/all && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/jammy-slim/Dockerfile b/docker/develop/jammy-slim/Dockerfile index b93345cd9..d463e5d3d 100644 --- a/docker/develop/jammy-slim/Dockerfile +++ b/docker/develop/jammy-slim/Dockerfile @@ -72,11 +72,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-yt-dlp.sh && \ /scripts/install-libvips.sh && \ /scripts/install-libheif.sh && \ - echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/jammy/Dockerfile b/docker/develop/jammy/Dockerfile index a51071ca0..e54adf7ac 100644 --- a/docker/develop/jammy/Dockerfile +++ b/docker/develop/jammy/Dockerfile @@ -108,11 +108,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-hadolint.sh && \ /scripts/install-osv-scanner.sh && \ /scripts/install-gitleaks.sh && \ - echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-6/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/lunar-slim/Dockerfile b/docker/develop/lunar-slim/Dockerfile index 857e8c229..6bcd4dd39 100644 --- a/docker/develop/lunar-slim/Dockerfile +++ b/docker/develop/lunar-slim/Dockerfile @@ -66,11 +66,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-mariadb.sh mariadb-client && \ /scripts/install-darktable.sh && \ /scripts/install-libheif.sh && \ - echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/lunar/Dockerfile b/docker/develop/lunar/Dockerfile index c8380cf0f..b6b854512 100644 --- a/docker/develop/lunar/Dockerfile +++ b/docker/develop/lunar/Dockerfile @@ -91,11 +91,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-go.sh && \ /scripts/install-go-tools.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: ALL" >> /etc/sudoers.d/all && \ - echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-6/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/mantic-slim/Dockerfile b/docker/develop/mantic-slim/Dockerfile index 4b7f06533..495155ddd 100644 --- a/docker/develop/mantic-slim/Dockerfile +++ b/docker/develop/mantic-slim/Dockerfile @@ -66,11 +66,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-mariadb.sh mariadb-client && \ /scripts/install-darktable.sh && \ /scripts/install-libheif.sh && \ - echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/mantic/Dockerfile b/docker/develop/mantic/Dockerfile index e2997baae..ef21f5f66 100644 --- a/docker/develop/mantic/Dockerfile +++ b/docker/develop/mantic/Dockerfile @@ -91,11 +91,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-go.sh && \ /scripts/install-go-tools.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: ALL" >> /etc/sudoers.d/all && \ - echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-6/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/noble-slim/Dockerfile b/docker/develop/noble-slim/Dockerfile index 7c5f41c84..3a0891e81 100644 --- a/docker/develop/noble-slim/Dockerfile +++ b/docker/develop/noble-slim/Dockerfile @@ -68,11 +68,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-mariadb.sh mariadb-client && \ /scripts/install-darktable.sh && \ /scripts/install-libheif.sh && \ - echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/noble/Dockerfile b/docker/develop/noble/Dockerfile index 1955331e1..2e0cd0f20 100644 --- a/docker/develop/noble/Dockerfile +++ b/docker/develop/noble/Dockerfile @@ -96,11 +96,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ cp -r /etc/skel/.config /root/.config && \ /scripts/install-go.sh && \ /scripts/install-go-tools.sh && \ - echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-6/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/oracular-slim/Dockerfile b/docker/develop/oracular-slim/Dockerfile index 43201a4eb..1e5d67bb1 100644 --- a/docker/develop/oracular-slim/Dockerfile +++ b/docker/develop/oracular-slim/Dockerfile @@ -71,11 +71,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-mariadb.sh mariadb-client && \ /scripts/install-darktable.sh && \ /scripts/install-libheif.sh && \ - echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/oracular/Dockerfile b/docker/develop/oracular/Dockerfile index ed4025267..e13bec082 100644 --- a/docker/develop/oracular/Dockerfile +++ b/docker/develop/oracular/Dockerfile @@ -99,11 +99,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ cp -r /etc/skel/.config /root/.config && \ /scripts/install-go.sh && \ /scripts/install-go-tools.sh && \ - echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-6/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/plucky-slim/Dockerfile b/docker/develop/plucky-slim/Dockerfile index 10170cfaa..a43ade159 100644 --- a/docker/develop/plucky-slim/Dockerfile +++ b/docker/develop/plucky-slim/Dockerfile @@ -72,11 +72,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-darktable.sh && \ /scripts/install-yt-dlp.sh && \ /scripts/install-libheif.sh && \ - echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/plucky/Dockerfile b/docker/develop/plucky/Dockerfile index 0e7fa2b52..97119449e 100644 --- a/docker/develop/plucky/Dockerfile +++ b/docker/develop/plucky/Dockerfile @@ -109,11 +109,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ cp -r /etc/skel/.config /root/.config && \ /scripts/install-go.sh && \ /scripts/install-go-tools.sh && \ - echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-7/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/questing-slim/Dockerfile b/docker/develop/questing-slim/Dockerfile index fbb41ebe4..fd2a99e7b 100644 --- a/docker/develop/questing-slim/Dockerfile +++ b/docker/develop/questing-slim/Dockerfile @@ -72,11 +72,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-darktable.sh && \ /scripts/install-yt-dlp.sh && \ /scripts/install-libheif.sh && \ - echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/questing/Dockerfile b/docker/develop/questing/Dockerfile index 8fffd816a..c9a520650 100644 --- a/docker/develop/questing/Dockerfile +++ b/docker/develop/questing/Dockerfile @@ -112,11 +112,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-hadolint.sh && \ /scripts/install-osv-scanner.sh && \ /scripts/install-gitleaks.sh && \ - echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-7/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/resolute-slim/Dockerfile b/docker/develop/resolute-slim/Dockerfile index 0abe790b9..0bcdf958a 100644 --- a/docker/develop/resolute-slim/Dockerfile +++ b/docker/develop/resolute-slim/Dockerfile @@ -73,11 +73,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-darktable.sh && \ /scripts/install-yt-dlp.sh && \ /scripts/install-libheif.sh && \ - echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/resolute/Dockerfile b/docker/develop/resolute/Dockerfile index 8b7cd81e9..29da35020 100644 --- a/docker/develop/resolute/Dockerfile +++ b/docker/develop/resolute/Dockerfile @@ -113,11 +113,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-hadolint.sh && \ /scripts/install-osv-scanner.sh && \ /scripts/install-gitleaks.sh && \ - echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-7/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/trixie-slim/Dockerfile b/docker/develop/trixie-slim/Dockerfile index 86ba603a7..978d64cd7 100644 --- a/docker/develop/trixie-slim/Dockerfile +++ b/docker/develop/trixie-slim/Dockerfile @@ -71,11 +71,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ libmatroska-dev libdvdread-dev libebml5 libgav1-bin libatomic1 \ va-driver-all libva2 iputils-ping dnsutils binutils binutils-gold \ && \ - echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/trixie/Dockerfile b/docker/develop/trixie/Dockerfile index 801b62f8d..374abc881 100644 --- a/docker/develop/trixie/Dockerfile +++ b/docker/develop/trixie/Dockerfile @@ -99,11 +99,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-hadolint.sh && \ /scripts/install-osv-scanner.sh && \ /scripts/install-gitleaks.sh && \ - echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-7/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/dummy/oidc/app/go.mod b/docker/dummy/oidc/app/go.mod index 388539a44..46f6ffaf4 100644 --- a/docker/dummy/oidc/app/go.mod +++ b/docker/dummy/oidc/app/go.mod @@ -1,6 +1,6 @@ module caos-test-op -go 1.26.3 +go 1.26.4 require ( github.com/go-chi/chi/v5 v5.2.5 @@ -26,6 +26,6 @@ require ( go.opentelemetry.io/otel/metric v1.43.0 // indirect go.opentelemetry.io/otel/trace v1.43.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect - golang.org/x/sys v0.42.0 // indirect + golang.org/x/sys v0.46.0 // indirect golang.org/x/text v0.36.0 // indirect ) diff --git a/docker/dummy/oidc/app/go.sum b/docker/dummy/oidc/app/go.sum index 840f26ee2..7ba02046b 100644 --- a/docker/dummy/oidc/app/go.sum +++ b/docker/dummy/oidc/app/go.sum @@ -57,8 +57,8 @@ go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09 go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= +golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/docker/goproxy/Dockerfile b/docker/goproxy/Dockerfile deleted file mode 100644 index 122f55d50..000000000 --- a/docker/goproxy/Dockerfile +++ /dev/null @@ -1,30 +0,0 @@ -##################################################### BUILD STAGE ###################################################### -FROM golang:alpine AS build - -ENV DO_NOT_TRACK=true - -RUN apk add --no-cache -U make git mercurial subversion - -RUN git clone https://github.com/goproxyio/goproxy.git /src/goproxy && \ - cd /src/goproxy && \ - export CGO_ENABLED=0 && \ - make - -################################################## PRODUCTION STAGE #################################################### -FROM golang:alpine - -ENV DO_NOT_TRACK=true \ - TINI_VERSION=v0.19.0 - -ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-static-amd64 /usr/bin/tini -RUN chmod +x /usr/bin/tini - -RUN apk add --no-cache -U git mercurial subversion - -COPY --from=build /src/goproxy/bin/goproxy /goproxy -VOLUME "/go" - -EXPOSE 8888 - -ENTRYPOINT ["/usr/bin/tini", "--"] -CMD ["/goproxy", "-listen", "0.0.0.0:8888"] diff --git a/docker/photoprism/armv7/Dockerfile b/docker/photoprism/armv7/Dockerfile index abb932b92..d057cfae3 100644 --- a/docker/photoprism/armv7/Dockerfile +++ b/docker/photoprism/armv7/Dockerfile @@ -115,11 +115,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ && \ /scripts/install-yt-dlp.sh && \ /scripts/install-libheif.sh && \ - echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/photoprism/buster/Dockerfile b/docker/photoprism/buster/Dockerfile index 6e3276fef..918371019 100644 --- a/docker/photoprism/buster/Dockerfile +++ b/docker/photoprism/buster/Dockerfile @@ -118,11 +118,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ libavcodec-extra \ && \ /scripts/install-darktable.sh && \ - echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/photoprism/impish/Dockerfile b/docker/photoprism/impish/Dockerfile index 4a305bb1a..ffd7b3d50 100644 --- a/docker/photoprism/impish/Dockerfile +++ b/docker/photoprism/impish/Dockerfile @@ -117,11 +117,9 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ libavcodec-extra \ && \ /scripts/install-darktable.sh && \ - echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ - echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + /scripts/install-bashrc.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ - cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/frontend/.testcaferc.cjs b/frontend/.testcaferc.cjs new file mode 100644 index 000000000..73796641a --- /dev/null +++ b/frontend/.testcaferc.cjs @@ -0,0 +1,34 @@ +// Taken from https://testcafe.io/documentation/404388/guides/advanced-guides/modify-reporter-output +// And updated to show h m s ms time format. +function onBeforeWriteHook(writeInfo) { // This function will fire every time the reporter calls the "write" method. + if (writeInfo.initiator === 'reportTestDone') { // The "initiator" property contains the name of the reporter event that triggered the hook. + const { + name, + testRunInfo, + meta + } = writeInfo.data || {}; // If you attached this hook to a compatible reporter (such as "spec" or "list"), the hook can process data related to the event. + const testDuration = new Date(testRunInfo.durationMs).toISOString().slice(11, -1); // Save the duration of the test. + writeInfo.formattedText = writeInfo.formattedText + ' (' + testDuration + ')'; // Add test duration to the reporter output. + }; +} + + +module.exports = { // Attach the hook + hooks: { + reporter: { + onBeforeWrite: { + 'spec': onBeforeWriteHook, // This hook will fire when you use the default "spec" reporter. + }, + }, + }, + skipJsErrors: true, + quarantineMode: false, + selectorTimeout: 3500, + assertionTimeout: 3500, + hostname: "localhost", + retryTestPages: true, + screenshots: { + path: "tests/acceptance/screenshots/", + takeOnFails: true + }, +}; \ No newline at end of file diff --git a/frontend/AGENTS.md b/frontend/AGENTS.md index 829664c2e..3f88343a3 100644 --- a/frontend/AGENTS.md +++ b/frontend/AGENTS.md @@ -1,11 +1,11 @@ # Frontend Guidelines -**Last Updated:** May 5, 2026 +**Last Updated:** June 10, 2026 ## Dependencies & Pins - [`frontend/README.md`](README.md) is the canonical doc for dependency pin rationale, the `overrides` layer, ESM-only upgrade blockers, and the orphan-audit pattern. -- **Pins are intentional.** When a version has no caret (e.g., `"axios": "1.16.1"`, `"vuetify": "3.12.2"`), check `frontend/README.md` and `git log -p -S "" -- frontend/package.json` for the reason before changing it. +- **Pins are intentional.** When a version has no caret (e.g., `"axios": "1.17.0"`, `"vuetify": "3.12.2"`), check `frontend/README.md` and `git log -p -S "" -- frontend/package.json` for the reason before changing it. - npm is a workspace; run `npm install --ignore-scripts --no-audit --no-fund --no-update-notifier` from the **repo root** (not `frontend/`) so the root `package-lock.json` updates. - After dep changes run `make audit`, `make build-js`, `make test-js`, and `make notice`. - Before adding a new dep — and especially before declaring an existing one "unused" — verify with `rg -nF "" frontend …` plus `npm ls --all` that no consumer or peer-dep needs it. @@ -46,7 +46,7 @@ ## Playwright MCP Usage -- Default endpoint is `http://localhost:2342/`; default login routes are `/library/login` for CE, Plus, and Pro, and `/portal/admin/login` for Portal. +- Default endpoint is `http://localhost:2342/`; default login routes are `/library/login` for CE, Plus, and Pro, and `/portal/login` for Portal. - Use the local compose admin credentials; if login fails, inspect the active compose environment. - Desktop sessions default to `1280x900`; mobile sessions should use the mobile Playwright server with `375x667`. - Close the browser tab after scripted interactions. @@ -56,4 +56,4 @@ ## Frontend Test Gotchas -- Hidden-route UI checks under `/library/hidden` or `/portal/admin/hidden` require both `files.file_error` and `photos.photo_quality = -1`; `file_error` alone will not surface the row. +- Hidden-route UI checks under `/library/hidden` or `/portal/hidden` require both `files.file_error` and `photos.photo_quality = -1`; `file_error` alone will not surface the row. diff --git a/frontend/CODEMAP.md b/frontend/CODEMAP.md index 1679bd78e..d0b079f18 100644 --- a/frontend/CODEMAP.md +++ b/frontend/CODEMAP.md @@ -18,7 +18,7 @@ Directory Map (src) - `src/app.js` — app bootstrap: creates Vue app, installs Vuetify + plugins, configures router, mounts to `#app` - `src/app/routes.js` — all route definitions (guards, titles, meta) - `src/app/session.js` — `$config` and `$session` singletons wired from server-provided `window.__CONFIG__` and storage -- `src/common/*` — framework-agnostic helpers: `$api` (Axios), `$notify`, `$view`, `$event` (PubSub), i18n (`gettext`), util, fullscreen, map utils, websocket +- `src/common/*` — framework-agnostic helpers: `$api` (Axios), `$notify`, `$view`, `$event` (PubSub), i18n (`gettext`), util, fullscreen, map utils, websocket, `sphere.js` (lazy-loaded 360° viewer wrapper) - `src/component/*` — Vue components; `src/component/components.js` registers global components - `src/page/*` — route views (Albums, Photos, Places, Settings, Admin, Discover, Help, Login, etc.) - `src/model/*` — REST models; base `Rest` class (`model/rest.js`) wraps Axios CRUD for collections and entities @@ -39,7 +39,7 @@ Runtime & Plugins - **Known caveats at 3.12.2:** - Vuetify upstream issue #22828 — `v-select`'s `@blur` fires when the menu opens (introduced by the 3.12.2 screenreader navigation fix). PhotoPrism is not affected because we only bind `@blur` on `v-text-field`, `v-textarea`, and `v-combobox`; if you ever attach `@blur` to a `v-select`, expect spurious calls until that upstream bug is fixed. - The `.v-field--focused` CSS class can linger on a previously-focused `v-autocomplete` input after the user clicks into another autocomplete (`document.activeElement` is correct, but Vuetify's internal `isFocused` is under-aggressive about clearing in 3.12.2). This is the inverse symptom of Vuetify #22697 — fixing it overshot in 3.12.3 and caused #5538. Functionally harmless in the photo edit dialog because the affected fields are not on screen together. -- Router: Vue Router 4, history base at `$config.frontendUri` (default `/library` for CE/Plus/Pro and `/portal/admin` for Portal) +- Router: Vue Router 4, history base at `$config.frontendUri` (default `/library` for CE/Plus/Pro and `/portal` for Portal) - I18n: `vue3-gettext` via `common/gettext.js`; canonical extraction via root `make gettext-extract` (scans `frontend/src` plus available overlays in `plus/frontend`, `pro/frontend`, and `portal/frontend`), compile with `npm run gettext-compile` - HTML sanitization: `vue-3-sanitize` + `vue-sanitize-directive` - Tooltips: Vuetify `` component + `v-tooltip` directive (auto-imported per SFC by `webpack-plugin-vuetify`) diff --git a/frontend/NOTICE b/frontend/NOTICE index d119c8420..f166e1814 100644 --- a/frontend/NOTICE +++ b/frontend/NOTICE @@ -1,93 +1,94 @@ -Package License Copyright -------- ------- --------- -@babel/cli MIT The Babel Team (https://babel.dev/team) -@babel/core MIT The Babel Team (https://babel.dev/team) -@babel/plugin-transform-runtime MIT The Babel Team (https://babel.dev/team) -@babel/preset-env MIT The Babel Team (https://babel.dev/team) -@babel/register MIT The Babel Team (https://babel.dev/team) -@babel/runtime MIT The Babel Team (https://babel.dev/team) -@eslint/eslintrc MIT Nicholas C. Zakas -@eslint/js MIT n/a -@mdi/font Apache-2.0 Austin Andrews -@testing-library/jest-dom MIT Ernesto Garcia (http://gnapse.github.io) -@vitejs/plugin-vue MIT Evan You -@vitest/browser MIT n/a -@vitest/coverage-v8 MIT Anthony Fu -@vitest/ui MIT n/a -@vue/compiler-sfc MIT Evan You -@vue/language-server MIT n/a -@vue/test-utils MIT Lachlan Miller lachlan.miller.1990@outlook.com -@vvo/tzdb MIT Vincent Voyer -axios MIT Matt Zabriskie -axios-mock-adapter MIT Colin Timmermans -babel-loader MIT Luis Couto -babel-plugin-istanbul BSD-3-Clause Thai Pangsakulyanont @dtinth -babel-plugin-polyfill-corejs3 MIT n/a -browserslist MIT Andrey Sitnik -core-js MIT Denis Pushkarev zloirock@zloirock.ru http://zloirock.ru -cross-env MIT Kent C. Dodds (https://kentcdodds.com) -css-loader MIT Tobias Koppers @sokra -cssnano MIT Ben Briggs beneb.info@gmail.com http://beneb.info -eslint MIT Nicholas C. Zakas -eslint-config-prettier MIT Simon Lydell -eslint-formatter-pretty MIT Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com -eslint-plugin-html ISC n/a -eslint-plugin-import MIT Ben Mosher -eslint-plugin-node MIT Toru Nagashima -eslint-plugin-vue MIT Toru Nagashima (https://github.com/mysticatea) -eslint-plugin-vuetify MIT Kael Watts-Deuchar -eslint-webpack-plugin MIT Ricardo Gobbo de Souza -eventsource-polyfill MIT amvtek -file-loader MIT Tobias Koppers @sokra -file-saver MIT Eli Grey -globals MIT Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com -hls.js Apache-2.0 n/a -i MIT Pavan Kumar Sunkara (pksunkara.github.com) -jsdom MIT n/a -luxon MIT Isaac Cambron -maplibre-gl BSD-3-Clause n/a -memoize-one MIT Alex Reardon -mini-css-extract-plugin MIT Tobias Koppers @sokra -minimist MIT James Halliday mail@substack.net http://substack.net -node-storage-shim ISC Michael Nahkies -passive-events-support MIT Ignas Damunskis -photoswipe MIT Dmytro Semenov (https://dimsemenov.com) -playwright Apache-2.0 Microsoft Corporation -postcss MIT Andrey Sitnik -postcss-import MIT Maxime Thirouin -postcss-loader MIT Andrey Sitnik -postcss-preset-env MIT-0 n/a -postcss-reporter MIT David Clark david.dave.clark@gmail.com https://davidtheclark.com -prettier MIT James Long -pubsub-js MIT Morgan Roderick morgan@roderick.dk http://roderick.dk -regenerator-runtime MIT Ben Newman -resolve-url-loader MIT bholloway -sanitize-html MIT Apostrophe Technologies, Inc. -sass MIT Natalie Weizenbaum nweiz@google.com https://github.com/nex3 -sass-loader MIT J. Tangelder -sockette MIT Luke Edwards luke.edwards05@gmail.com lukeed.com -style-loader MIT Tobias Koppers @sokra -svg-url-loader MIT Hovhannes Babayan -tar BlueOak-1.0.0 Isaac Z. Schlueter -url-loader MIT Tobias Koppers @sokra -util MIT Joyent http://www.joyent.com -vitest MIT Anthony Fu -vue MIT Evan You -vue-3-sanitize MIT Vannsl, Vanessa Otto -vue-loader MIT Evan You -vue-loader-plugin ISC Ivan liu -vue-luxon MIT Cas Bloem -vue-router MIT Eduardo San Martin Morote posva13@gmail.com -vue-sanitize-directive MIT Leonardo Piccioni de Almeida leopiccionia@gmail.com -vue-style-loader MIT Evan You -vue3-gettext MIT Leo Zurbriggen -vuetify MIT John Leider john@vuetifyjs.com -webpack MIT Tobias Koppers @sokra -webpack-bundle-analyzer MIT Yury Grunin -webpack-cli MIT n/a -webpack-hot-middleware MIT Glen Mailer -webpack-manifest-plugin MIT Dane Thurber -webpack-md5-hash MIT Kirill Ermolov -webpack-merge MIT Juho Vepsalainen -webpack-plugin-vuetify MIT Kael Watts-Deuchar -workbox-webpack-plugin MIT Google's Web DevRel Team and Google's Aurora Team +Package License Copyright +------- ------- --------- +@babel/cli MIT The Babel Team (https://babel.dev/team) +@babel/core MIT The Babel Team (https://babel.dev/team) +@babel/plugin-transform-runtime MIT The Babel Team (https://babel.dev/team) +@babel/preset-env MIT The Babel Team (https://babel.dev/team) +@babel/register MIT The Babel Team (https://babel.dev/team) +@babel/runtime MIT The Babel Team (https://babel.dev/team) +@eslint/eslintrc MIT Nicholas C. Zakas +@eslint/js MIT n/a +@mdi/font Apache-2.0 Austin Andrews +@photo-sphere-viewer/core MIT Damien 'Mistic' Sorel contact@git.strangeplanet.fr +@photo-sphere-viewer/equirectangular-video-adapter MIT Damien 'Mistic' Sorel contact@git.strangeplanet.fr +@photo-sphere-viewer/video-plugin MIT Damien 'Mistic' Sorel contact@git.strangeplanet.fr +@testing-library/jest-dom MIT Ernesto Garcia (http://gnapse.github.io) +@vitejs/plugin-vue MIT Evan You +@vitest/coverage-v8 MIT Anthony Fu +@vue/compiler-sfc MIT Evan You +@vue/language-server MIT n/a +@vue/test-utils MIT Lachlan Miller lachlan.miller.1990@outlook.com +@vvo/tzdb MIT Vincent Voyer +axios MIT Matt Zabriskie +axios-mock-adapter MIT Colin Timmermans +babel-loader MIT Luis Couto +babel-plugin-polyfill-corejs3 MIT n/a +browserslist MIT Andrey Sitnik +core-js MIT Denis Pushkarev zloirock@zloirock.ru http://zloirock.ru +cross-env MIT Kent C. Dodds (https://kentcdodds.com) +css-loader MIT Tobias Koppers @sokra +cssnano MIT Ben Briggs beneb.info@gmail.com http://beneb.info +eslint MIT Nicholas C. Zakas +eslint-config-prettier MIT Simon Lydell +eslint-formatter-pretty MIT Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com +eslint-plugin-html ISC n/a +eslint-plugin-import MIT Ben Mosher +eslint-plugin-node MIT Toru Nagashima +eslint-plugin-vue MIT Toru Nagashima (https://github.com/mysticatea) +eslint-plugin-vuetify MIT Kael Watts-Deuchar +eslint-webpack-plugin MIT Ricardo Gobbo de Souza +eventsource-polyfill MIT amvtek +file-loader MIT Tobias Koppers @sokra +file-saver MIT Eli Grey +globals MIT Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com +hls.js Apache-2.0 n/a +i MIT Pavan Kumar Sunkara (pksunkara.github.com) +jsdom MIT n/a +luxon MIT Isaac Cambron +maplibre-gl BSD-3-Clause n/a +memoize-one MIT Alex Reardon +mini-css-extract-plugin MIT Tobias Koppers @sokra +minimist MIT James Halliday mail@substack.net http://substack.net +node-storage-shim ISC Michael Nahkies +passive-events-support MIT Ignas Damunskis +photoswipe MIT Dmytro Semenov (https://dimsemenov.com) +playwright Apache-2.0 Microsoft Corporation +postcss MIT Andrey Sitnik +postcss-import MIT Maxime Thirouin +postcss-loader MIT Andrey Sitnik +postcss-preset-env MIT-0 n/a +postcss-reporter MIT David Clark david.dave.clark@gmail.com https://davidtheclark.com +prettier MIT James Long +pubsub-js MIT Morgan Roderick morgan@roderick.dk http://roderick.dk +regenerator-runtime MIT Ben Newman +resolve-url-loader MIT bholloway +sanitize-html MIT Apostrophe Technologies, Inc. +sass MIT Natalie Weizenbaum nweiz@google.com https://github.com/nex3 +sass-loader MIT J. Tangelder +sockette MIT Luke Edwards luke.edwards05@gmail.com lukeed.com +style-loader MIT Tobias Koppers @sokra +svg-url-loader MIT Hovhannes Babayan +tar BlueOak-1.0.0 Isaac Z. Schlueter +url-loader MIT Tobias Koppers @sokra +util MIT Joyent http://www.joyent.com +vite MIT Evan You +vitest MIT Anthony Fu +vue MIT Evan You +vue-3-sanitize MIT Vannsl, Vanessa Otto +vue-loader MIT Evan You +vue-loader-plugin ISC Ivan liu +vue-luxon MIT Cas Bloem +vue-router MIT Eduardo San Martin Morote posva13@gmail.com +vue-sanitize-directive MIT Leonardo Piccioni de Almeida leopiccionia@gmail.com +vue-style-loader MIT Evan You +vue3-gettext MIT Leo Zurbriggen +vuetify MIT John Leider john@vuetifyjs.com +webpack MIT Tobias Koppers @sokra +webpack-bundle-analyzer MIT Yury Grunin +webpack-cli MIT n/a +webpack-hot-middleware MIT Glen Mailer +webpack-manifest-plugin MIT Dane Thurber +webpack-md5-hash MIT Kirill Ermolov +webpack-merge MIT Juho Vepsalainen +webpack-plugin-vuetify MIT Kael Watts-Deuchar +workbox-webpack-plugin MIT Google's Web DevRel Team and Google's Aurora Team diff --git a/frontend/README.md b/frontend/README.md index 3ce91fbde..162ca835b 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -27,14 +27,14 @@ Other frontend documentation lives next to this file: ## Dependency Pinning Policy -**Pins are intentional.** When a version is locked without a caret (e.g., `"axios": "1.16.1"`), it is intentional. Before adjusting any pin, check the table below, the inline `//` comments at the top of `package.json`, and the git log (`git log -p -- frontend/package.json | grep -B2 -A4 ""`). +**Pins are intentional.** When a version is locked without a caret (e.g., `"axios": "1.18.1"`), it is intentional. Before adjusting any pin, check the table below, the inline `//` comments at the top of `package.json`, and the git log (`git log -p -- frontend/package.json | grep -B2 -A4 ""`). ### Currently Pinned Packages -| Package | Pin | Reason | -|-----------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `vuetify` | `3.12.2` | 3.12.3+ added an `onFocusout` handler to `VAutocomplete`/`VSelect`/`VCombobox` that closes long autocomplete/select dropdowns on open (#5538). Still unfixed in 3.12.5; upstream development moved to v4. See the long `//vuetify` comment in `package.json` and `frontend/CODEMAP.md` for retest steps. | -| `axios` | `1.16.1` | High-risk package. Originally pinned to `1.14.0` after the March 2026 supply-chain compromise (malicious `1.14.1`/`0.30.4` from a hijacked maintainer account). Quarantine was unwound on 2026-04-27 once OSV-Scanner came back clean. Keep an exact pin (no caret) per industry guidance for high-risk packages. | +| Package | Pin | Reason | +|-----------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `vuetify` | `3.12.2` | 3.12.3+ added an `onFocusout` handler to `VAutocomplete`/`VSelect`/`VCombobox` that closes long autocomplete/select dropdowns on open (#5538). Still unfixed in 3.12.5; upstream development moved to v4. See the long `//vuetify` comment in `package.json` and `frontend/CODEMAP.md` for retest steps. | +| `axios` | `1.18.1` | High-risk package. Originally pinned to `1.14.0` after the March 2026 supply-chain compromise (malicious `1.14.1`/`0.30.4` from a hijacked maintainer account). Quarantine was unwound on 2026-04-27 once OSV-Scanner came back clean; bumped to `1.17.0` on 2026-06-10, then to `1.18.1` on 2026-06-22 (security-hardening minor: strips caller-supplied sensitive headers on cross-origin redirects, rejects malformed http/https URLs, tightens prototype-pollution defenses; no breaking changes; OSV-Scanner clean). Keep an exact pin (no caret) per industry guidance for high-risk packages. | ### Override Layer (Transitive Pins) @@ -48,14 +48,49 @@ When an upstream advisory is fully resolved, retire the override and rerun `make ## Major-Version Upgrades — Known Blockers -Some major upgrades are blocked by config-file module style. The configs referenced below are CommonJS today; an ESM migration is required before bumping these. Track each as its own change: +Some major upgrades are blocked by config-file module style (the configs referenced below are CommonJS today and need an ESM migration first) or by a bundler-level incompatibility in the package itself. Track each as its own change: -| Package | Latest | Blocker | -|-------------------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------| -| `postcss-preset-env` 11.x | ESM | `frontend/postcss.config.js` is CommonJS (`module.exports = { plugins: [require("postcss-preset-env"), ...] }`). | -| `webpack-manifest-plugin` 6.x | ESM | `frontend/webpack.config.js` is CommonJS (`require("webpack-manifest-plugin")`). Webpack accepts ESM configs, but the migration is non-trivial. | -| `vuetify` 4.x | — | See the `vuetify` row in [Currently Pinned Packages](#currently-pinned-packages); also a separate v3 → v4 migration project. | -| `vue-router` 5.x | — | Major release with breaking changes across `frontend/src/app/routes.js` and dynamic imports. Needs its own evaluation pass with TestCafe verification. | +| Package | Latest | Blocker | +|-------------------------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `postcss-preset-env` 11.x | ESM | `frontend/postcss.config.js` is CommonJS (`module.exports = { plugins: [require("postcss-preset-env"), ...] }`). | +| `webpack-manifest-plugin` 6.x | ESM | `frontend/webpack.config.js` is CommonJS (`require("webpack-manifest-plugin")`). Webpack accepts ESM configs, but the migration is non-trivial. | +| `vue3-gettext` 4.x | ESM | v4 is ESM-only and exports its extraction tooling from the same runtime entry: `dist/index.js` does an unconditional `import PO from "pofile"`, and `pofile` calls `require("fs")`. The `exports` map has no runtime-only subpath and the package sets no `sideEffects: false`, so webpack cannot tree-shake it — `make build-js` fails with `Can't resolve 'fs'` in `pofile/lib/po.js`. The runtime API itself (`createGettext({ translations, silent, defaultLanguage })`, the `$gettext`/`$ngettext`/`$pgettext`/`$npgettext` globals, `%{}` interpolation) is compatible and the removed `` component / `v-translate` directive are unused here, so the only fix needed is a bundler workaround (e.g. `resolve.fallback: { fs: false }`, which ships dead extraction code), an upstream split of runtime vs. tooling exports, or a [migration to Vite](#migrating-the-production-build-from-webpack-to-vite) (Rollup externalizes `fs` instead of failing). | +| `vuetify` 4.x | — | See the `vuetify` row in [Currently Pinned Packages](#currently-pinned-packages); also a separate v3 → v4 migration project. | +| `vue-router` 5.x | — | Major release with breaking changes across `frontend/src/app/routes.js` and dynamic imports. Needs its own evaluation pass with TestCafe verification. | + +## Migrating the Production Build From webpack to Vite + +**Status: not started — tracked in #5679.** The production bundle is built with webpack (`frontend/webpack.config.js`, run via `make build-js`); Vitest already runs on Vite (`frontend/vitest.config.js`), so a production migration would converge the two toolchains. This is its own project (related: #5659 test-side Vite v8, and the historical #838). It is *not* a prerequisite for any single dependency bump; treat the ESM-only unblock (e.g. `vue3-gettext` 4.x) as a side benefit, not the reason. + +**Why it helps the ESM-only blockers.** Vite/Rollup externalize Node built-ins for the browser — a `fs` import resolves to a stub that only throws if actually called at runtime — instead of failing the build the way webpack 5 does. Verified locally: a minimal Vite build of `vue3-gettext` 4's `createGettext` succeeds with a `Module "fs" has been externalized` warning. Caveat: Vite does **not** tree-shake the dead extraction tooling either (the package sets no `sideEffects: false`), so the runtime bundle still carries the `pofile`/parser code — migrate for the modernization, not as a bundle slimmer. + +**The contract that must not break.** The Go server reads a **flat** asset manifest: `internal/config/client_assets.go` (`ClientAssets`) unmarshals `assets/static/build/assets.json` keyed by logical name — `app.js`, `app.css`, `share.js`, `share.css`, `splash.js`, `splash.css`, plus named font/image entries (`MaterialIcons-Regular.*`, `default-skin.svg`, `preloader.gif`, …). That shape is `webpack-manifest-plugin`'s output. Vite's default `.vite/manifest.json` is keyed by **source path** with nested objects and is not interchangeable, so the migration must either emit the flat `assets.json` from a small post-build step or teach `ClientAssets.Load` the Vite shape. All editions (`plus`/`pro`/`portal`) read the same struct, so whatever shape is chosen must hold for every edition build. + +**Feature-by-feature mapping** (from `webpack.config.js`): + +| webpack today | Vite equivalent | +|-------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------| +| 3 entries `app`/`share`/`splash` | `build.rollupOptions.input` (3 inputs) | +| `output` → `../assets/static/build`, `[name].[contenthash].js`, `clean` | `build.outDir` + `emptyOutDir` + `entryFileNames`/`chunkFileNames`/`assetFileNames` with `[name].[hash]` | +| flat `assets.json` via `webpack-manifest-plugin` | `build.manifest` + post-build transform to the flat shape (see contract above) | +| `resolve.modules: [src]` + `preferRelative` | reuse the `resolve.alias` map already in `vitest.config.js` | +| `vue-loader`, `vue$` runtime alias, `whitespace: "preserve"` | `@vitejs/plugin-vue` (already a dep) + alias + `template.compilerOptions` | +| `webpack-plugin-vuetify` (auto-import) | `vite-plugin-vuetify` *(new dep)* | +| `babel-loader` + `@babel/preset-env` + `core-js` (browserslist Safari 13 / iOS 13) | `@vitejs/plugin-legacy` *(new dep; reads browserslist)* — esbuild alone won't downlevel to the iOS 13 baseline | +| `workbox-webpack-plugin` `GenerateSW` (`sw.js`, `importScripts` `sw-scope-cleanup.js`, `modifyURLPrefix: static/build/`, exclusions, 5 MiB cap) | `vite-plugin-pwa` *(new dep; workbox under the hood)* with the same options | +| CSS/PostCSS/Sass loader stack (`mini-css-extract-plugin`, `css-loader`, `postcss-loader`, `resolve-url-loader`, `sass-loader`) | Vite native CSS (reads `postcss.config.js`; keep the `sass` dep) | +| `DefinePlugin` Vue flags (`__VUE_OPTIONS_API__`, `__VUE_PROD_DEVTOOLS__`, `__VUE_PROD_HYDRATION_MISMATCH_DETAILS__`) | Vite `define` | +| `EmitStaticFilePlugin` (copies `sw-scope-cleanup.js`) | `publicDir` or a small emit plugin | +| `hls.js` → `hls.light.min.js` alias | same `resolve.alias` entry | +| png/jpg/svg/font `asset/resource` | Vite asset pipeline — confirm the named manifest entries still land in `assets.json` | +| `CUSTOM_SRC`/`CUSTOM_NAME` edition overlay | env-driven `resolve.alias`/input | +| `webpack-bundle-analyzer` (`BUILD_ENV=analyze`) | `rollup-plugin-visualizer` | +| `make watch-js` (`webpack --watch`) | `vite build --watch` — **not** the dev server; Go serves the embedded build output, so HMR isn't wired into the templates | +| `postbuild` `scripts/precompress.js` | unchanged; it operates on the output dir, not the bundler | + +**Dependency churn.** Retire `webpack`, `webpack-cli`, `webpack-manifest-plugin`, `webpack-plugin-vuetify`, `workbox-webpack-plugin`, `eslint-webpack-plugin`, `webpack-bundle-analyzer`, `vue-loader`, and the loader stack (`babel-loader`, `css-loader`, `postcss-loader`, `resolve-url-loader`, `mini-css-extract-plugin`, `vue-style-loader`, `file-loader`, `url-loader`, `svg-url-loader`). Add `vite-plugin-vuetify`, `@vitejs/plugin-legacy`, `vite-plugin-pwa`, and `rollup-plugin-visualizer` (`vite` and `@vitejs/plugin-vue` are already deps). Then `make audit` and `make notice`. + +**Validation.** `make build-js` emits `assets/static/build/assets.json` in the flat shape and the Go server renders the app/share/splash entrypoints without `cannot read assets.json`; `sw.js` is generated and the precompressed `.gz`/`.zst` siblings appear; smoke-test the Safari 13 / iOS 13 baseline; the `plus`/`pro`/`portal` edition builds still produce valid manifests; finally `make test-js` and the acceptance suite. ## Auditing for Orphaned Dependencies diff --git a/frontend/karma.conf.js b/frontend/karma.conf.js deleted file mode 100644 index 9c685d41a..000000000 --- a/frontend/karma.conf.js +++ /dev/null @@ -1,164 +0,0 @@ -/* - -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. - - This program is free software: you can redistribute it and/or modify - it under Version 3 of the GNU Affero General Public License (the "AGPL"): - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - The AGPL is supplemented by our Trademark and Brand Guidelines, - which describe how our Brand Assets may be used: - - -Feel free to send an email to hello@photoprism.app if you have questions, -want to support our work, or just want to say hello. - -Additional information can be found in our Developer Guide: - - -*/ - -const path = require("path"); -const findChrome = require("chrome-finder"); -const chromeBin = findChrome(); - -if (chromeBin) { - // proceed, chrome/chromium was found - process.env.CHROME_BIN = chromeBin; - console.log(`chrome-bin: ${chromeBin}`); -} else { - // abort, no chrome binary was found - console.error("Chrome/Chromium not found."); - process.exit(1); -} - -// test setup -module.exports = (config) => { - config.set({ - logLevel: config.LOG_ERROR, - webpackMiddleware: { - stats: "errors-only", - }, - - frameworks: ["mocha"], - - browsers: ["LocalChrome"], - - customLaunchers: { - LocalChrome: { - base: "ChromeHeadless", - flags: ["--disable-translate", "--disable-extensions", "--no-sandbox", "--disable-web-security", "--disable-dev-shm-usage"], - }, - }, - - files: [{ pattern: "tests/unit/**/*_test.js", watched: false }], - - // Preprocess through webpack - preprocessors: { - "tests/unit/**/*_test.js": ["webpack"], - }, - - reporters: ["progress", "coverage-istanbul", "html"], - - htmlReporter: { - outputFile: "tests/unit.html", - }, - - coverageIstanbulReporter: { - // reports can be any that are listed here: https://github.com/istanbuljs/istanbuljs/tree/aae256fb8b9a3d19414dcf069c592e88712c32c6/packages/istanbul-reports/lib - "reports": ["lcov", "text-summary"], - - // base output directory. If you include %browser% in the path it will be replaced with the karma browser name - "dir": path.join(__dirname, "coverage"), - - // Combines coverage information from multiple browsers into one report rather than outputting a report - // for each browser. - "combineBrowserReports": true, - - // if using webpack and pre-loaders, work around webpack breaking the source path - "fixWebpackSourcePaths": true, - - // Omit files with no statements, no functions and no branches from the report - "skipFilesWithNoCoverage": true, - - // Most reporters accept additional config options. You can pass these through the `report-config` option - "report-config": { - // all options available at: https://github.com/istanbuljs/istanbuljs/blob/aae256fb8b9a3d19414dcf069c592e88712c32c6/packages/istanbul-reports/lib/html/index.js#L135-L137 - html: { - // outputs the report in ./coverage/html - subdir: "html", - }, - }, - - // enforce percentage thresholds - // anything under these percentages will cause karma to fail with an exit code of 1 if not running in watch mode - "thresholds": { - emitWarning: true, // set to `true` to not fail the test command when thresholds are not met - // thresholds for all files - global: { - //statements: 90, - lines: 90, - //branches: 90, - //functions: 90, - }, - // thresholds per file - each: { - //statements: 90, - lines: 90, - //branches: 90, - //functions: 90, - overrides: { - "src/common/viewer.js": { - lines: 0, - functions: 0, - }, - }, - }, - }, - - "verbose": true, // output config used by istanbul for debugging - }, - - webpack: { - mode: "development", - resolve: { - fallback: { - util: require.resolve("util"), - }, - modules: [path.join(__dirname, "src"), path.join(__dirname, "node_modules"), path.join(__dirname, "tests/unit")], - preferRelative: true, - alias: { - vue$: "vue/dist/vue.runtime.esm-bundler.js", - }, - }, - module: { - rules: [ - { - test: /\.js$/, - exclude: (file) => /node_modules/.test(file), - use: [ - { - loader: "babel-loader", - options: { - compact: false, - presets: ["@babel/preset-env"], - plugins: ["@babel/plugin-transform-runtime", ["istanbul", { exclude: ["**/*_test.js"] }]], - }, - }, - ], - }, - ], - }, - }, - - singleRun: true, - }); - - // Set default timezone. - process.env.TZ = "UTC"; -}; diff --git a/frontend/package.json b/frontend/package.json index 905f96f2f..9007206e1 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -47,21 +47,21 @@ "@eslint/eslintrc": "^3.3.5", "@eslint/js": "^9.33.0", "@mdi/font": "^7.4.47", + "@photo-sphere-viewer/core": "^5.14.3", + "@photo-sphere-viewer/equirectangular-video-adapter": "^5.14.3", + "@photo-sphere-viewer/video-plugin": "^5.14.3", "@testing-library/jest-dom": "^6.9.1", "@vitejs/plugin-vue": "^6.0.7", - "@vitest/browser": "^3.2.4", - "@vitest/coverage-v8": "^3.2.6", - "@vitest/ui": "^3.2.4", - "@vue/compiler-sfc": "^3.5.35", - "@vue/language-server": "^3.3.3", - "@vue/test-utils": "^2.4.10", + "@vitest/coverage-v8": "^4.1.10", + "@vue/compiler-sfc": "^3.5.39", + "@vue/language-server": "^3.3.6", + "@vue/test-utils": "^2.4.11", "@vvo/tzdb": "^6.198.0", - "axios": "1.16.1", + "axios": "1.18.1", "axios-mock-adapter": "^2.1.0", "babel-loader": "^10.1.1", - "babel-plugin-istanbul": "^7.0.1", "babel-plugin-polyfill-corejs3": "^0.14.2", - "browserslist": "^4.28.2", + "browserslist": "^4.28.5", "core-js": "^3.49.0", "cross-env": "^10.1.0", "css-loader": "^7.1.4", @@ -72,13 +72,13 @@ "eslint-plugin-html": "^8.1.4", "eslint-plugin-import": "^2.32.0", "eslint-plugin-node": "^11.1.0", - "eslint-plugin-vue": "^10.9.1", + "eslint-plugin-vue": "^10.9.2", "eslint-plugin-vuetify": "^2.7.2", "eslint-webpack-plugin": "^5.0.3", "eventsource-polyfill": "^0.9.6", "file-loader": "^6.2.0", "file-saver": "^2.0.5", - "globals": "^17.6.0", + "globals": "^17.7.0", "hls.js": "^1.6.16", "i": "^0.3.7", "jsdom": "^29.1.1", @@ -90,27 +90,28 @@ "node-storage-shim": "^2.0.1", "passive-events-support": "^1.1.0", "photoswipe": "^5.4.4", - "playwright": "^1.60.0", - "postcss": "^8.5.15", + "playwright": "^1.61.1", + "postcss": "^8.5.16", "postcss-import": "^16.1.1", "postcss-loader": "^8.2.1", "postcss-preset-env": "^10.6.1", "postcss-reporter": "^7.1.0", - "prettier": "^3.8.3", + "prettier": "^3.9.3", "pubsub-js": "^1.9.5", "regenerator-runtime": "^0.14.1", "resolve-url-loader": "^5.0.0", - "sanitize-html": "^2.17.4", - "sass": "^1.100.0", + "sanitize-html": "^2.17.5", + "sass": "^1.101.0", "sass-loader": "^16.0.8", "sockette": "^2.0.6", "style-loader": "^4.0.0", - "svg-url-loader": "^8.0.0", - "tar": "^7.5.16", + "svg-url-loader": "^8.1.0", + "tar": "^7.5.19", "url-loader": "^4.1.1", "util": "^0.12.5", - "vitest": "^3.2.4", - "vue": "^3.5.35", + "vite": "^8.1.3", + "vitest": "^4.1.10", + "vue": "^3.5.39", "vue-3-sanitize": "^0.1.4", "vue-loader": "^17.4.2", "vue-loader-plugin": "^1.3.0", @@ -120,7 +121,7 @@ "vue-style-loader": "^4.1.3", "vue3-gettext": "^2.4.0", "vuetify": "3.12.2", - "webpack": "^5.107.2", + "webpack": "5.107.2", "webpack-bundle-analyzer": "^5.3.0", "webpack-cli": "^6.0.1", "webpack-hot-middleware": "^2.26.1", diff --git a/frontend/src/app.js b/frontend/src/app.js index 2fc0a3c1e..372074ded 100644 --- a/frontend/src/app.js +++ b/frontend/src/app.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/app/routes.js b/frontend/src/app/routes.js index 11af3bbad..fdc0a1ec2 100644 --- a/frontend/src/app/routes.js +++ b/frontend/src/app/routes.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. @@ -33,9 +33,11 @@ import Labels from "page/labels.vue"; import People from "page/people.vue"; import Library from "page/library.vue"; import Settings from "page/settings.vue"; +import Services from "page/services.vue"; import Admin from "page/admin.vue"; import Cluster from "page/cluster.vue"; import Login from "page/auth/login.vue"; +import Instances from "page/auth/instances.vue"; import Discover from "page/discover.vue"; import About from "page/about/about.vue"; import License from "page/about/license.vue"; @@ -114,7 +116,7 @@ export default [ beforeEnter: (to, from, next) => { // Honor an inbound `return_to` query param so cross-frontend hand-offs // (e.g. the Portal OIDC OP redirecting an unauthenticated user from - // /oauth/authorize) can land back on the originally-requested URL + // /api/v1/oauth/authorize) can land back on the originally-requested URL // after a successful login. The value is recorded the same way the // global router guard records internal deep links, so the rest of // the flow (followLoginRedirectUrl on success) needs no further @@ -151,8 +153,18 @@ export default [ // hard-navigate to the deep link the router guard recorded so the // stored absolute path (incl. frontend base) is honored verbatim. if ($session.hasLoginRedirectUrl()) { - $session.followLoginRedirectUrl(); - next(false); + if ($session.loginRedirectLooping()) { + // We followed this redirect moments ago and bounced straight back — the + // target couldn't authenticate the navigation. Drop it and fall through + // to the default route instead of looping. + $session.clearLoginRedirectAttempt(); + $session.clearLoginRedirectUrl(); + next({ name: $session.getDefaultRoute() }); + } else { + $session.markLoginRedirectAttempt(); + $session.followLoginRedirectUrl(); + next(false); + } } else { next({ name: $session.getDefaultRoute() }); } @@ -163,11 +175,35 @@ export default [ path: "/logout", meta: { title: siteTitle, requiresAuth: false, hideNav: true }, beforeEnter: (to, from, next) => { - // signOut() resets client state synchronously so /login sees an - // unauthenticated user; the one-shot logout flag suppresses the next - // auto-OIDC bounce. Server DELETE runs best-effort in the background. - $session.signOut(); - next({ name: loginRoute }); + // Resolve the session kind and landing before sign-out clears the provider: + // a cluster-OIDC user returns to the Portal login (or the local form when the + // Portal login URL is unknown), everyone else to the local form. The cluster + // decision must not depend on the redirect target, or a node without a + // persisted Portal login URL would silently skip the cluster-wide sign-out. + const isClusterSession = $session.isClusterSession(); + // RP-initiated logout (OIDC + PHOTOPRISM_OIDC_LOGOUT) returns a provider logout URL + // that must be followed AFTER the async DELETE resolves; an OIDC node that is not a + // cluster session still needs this so direct /logout entry ends the upstream session, + // matching the nav-menu Sign-Out. + const rpInitiated = $session.getProvider() === "oidc" && $config.oidcLogout(); + const redirectUri = $session.logoutRedirectUri(); + if (isClusterSession || rpInitiated) { + // Await the cluster-wide sign-out (peer fan-out + Portal OP cookie clear) BEFORE + // redirecting; logoutEverywhere resolves to the provider logout URL when present (it + // ends the upstream session), else fall back to the local landing. A standalone OIDC + // node has no peers, so the fan-out is a no-op and only the RP-logout follow applies. + next(false); + $session + .logoutEverywhere(true) + .then((uri) => $session.followRedirect(uri || redirectUri)) + .catch(() => $session.followRedirect(redirectUri)); + } else { + // Local: signOut() resets client state synchronously so /login sees an + // unauthenticated user; the one-shot logout flag suppresses the next auto-OIDC + // bounce, and the DELETE fan-out (current + peers) runs best-effort. + $session.signOut(); + next({ name: loginRoute }); + } }, }, { @@ -213,6 +249,28 @@ export default [ } }, }, + { + name: "instances", + path: "/instances", + component: Instances, + meta: { + title: $gettext("Instances"), + requiresAuth: true, + hideNav: true, + settings: false, + background: "background", + }, + beforeEnter: (to, from, next) => { + // The instance selector is the durable landing page for non-operators; + // any signed-in user may enter, and unauthenticated requests fall through + // to login (the global guard records the return_to deep link). + if ($session.loginRequired()) { + next({ name: loginRoute }); + } else { + next(); + } + }, + }, { name: "upgrade", path: "/upgrade", @@ -619,6 +677,19 @@ export default [ }, props: { tab: "settings_content" }, }, + { + name: "settings_collections", + path: "/settings/collections", + component: Settings, + meta: { + title: $gettext("Settings"), + requiresAuth: true, + admin: true, + settings: true, + background: "background", + }, + props: { tab: "settings_collections" }, + }, { name: "settings_media", path: "/settings/media", @@ -640,7 +711,7 @@ export default [ { name: "settings_services", path: "/settings/services", - component: Settings, + component: Services, meta: { title: $gettext("Settings"), requiresAuth: true, @@ -648,7 +719,15 @@ export default [ settings: true, background: "background", }, - props: { tab: "settings_services" }, + beforeEnter: (to, from, next) => { + if ($session.loginRequired()) { + next({ name: loginRoute }); + } else if (!$config.feature("services") || $config.deny("services", "manage")) { + next({ name: $session.getDefaultRoute() }); + } else { + next(); + } + }, }, { name: "settings_account", diff --git a/frontend/src/common/README.md b/frontend/src/common/README.md index a38b8a38a..1ff1ddad1 100644 --- a/frontend/src/common/README.md +++ b/frontend/src/common/README.md @@ -27,6 +27,7 @@ When integrating third-party clients such as native mobile apps that embed the P - In the standard login UI, this preference is exposed through the `Stay signed in on this device` toggle. Checked means persistent namespaced `localStorage`; unchecked means ephemeral namespaced `sessionStorage`. - The login page initializes that toggle from the current session storage mode when available, and otherwise falls back to the stored namespaced `session` preference flag. - Logout and session reset clear the current app namespace from both `localStorage` and `sessionStorage`, and also remove deprecated raw legacy auth keys from both stores, without touching other namespaced instances on the same origin. +- When `PHOTOPRISM_OIDC_LOGOUT` is enabled, `DELETE /api/v1/session` returns a `providerLogoutUri`; `logout()` passes it to `onLogout()`, which redirects the browser to the provider's end-session endpoint (RP-initiated logout) instead of the local login page, so the provider's SSO session is ended too. `onLogout()` also resolves to that landing URL, so callers that pass `noRedirect` and navigate themselves — the `/logout` route guard and the Portal instance-chooser Sign-Out — follow the same provider URL rather than discarding it. Without the flag, sign-out lands on the local/Portal login page as before. - Regression tests for session restore should exercise both preferred `sessionStorage` and a real `Config`-shaped object so namespace resolution bugs cannot silently fall back to `pp:root:`. Preferred integration contract for new native or web view clients: diff --git a/frontend/src/common/api.js b/frontend/src/common/api.js index 4e17cac92..53bdd1b20 100644 --- a/frontend/src/common/api.js +++ b/frontend/src/common/api.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. @@ -25,7 +25,7 @@ Additional information can be found in our Developer Guide: import Axios from "axios"; import $notify from "common/notify"; -import { $gettext } from "common/gettext"; +import { $gettext, Tp } from "common/gettext"; import $event from "common/event"; import { getAppStorage } from "common/storage"; @@ -111,7 +111,10 @@ $api.interceptors.response.use( code = data.code; } - if (data.message) { + if (data.messageId) { + // Render the backend message in the current UI locale from its source id and params. + errorMessage = Tp(data.messageId, data.messageParams); + } else if (data.message) { errorMessage = data.message; } else if (data.error) { errorMessage = data.error; diff --git a/frontend/src/common/can.js b/frontend/src/common/can.js index 0769b6602..184c54733 100644 --- a/frontend/src/common/can.js +++ b/frontend/src/common/can.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/common/clipboard.js b/frontend/src/common/clipboard.js index 0360132b4..bac2cd90e 100644 --- a/frontend/src/common/clipboard.js +++ b/frontend/src/common/clipboard.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/common/config.js b/frontend/src/common/config.js index 9a6da984e..51666d88d 100644 --- a/frontend/src/common/config.js +++ b/frontend/src/common/config.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. @@ -24,12 +24,13 @@ Additional information can be found in our Developer Guide: */ import $api from "common/api"; -import $event, { ACTION_CREATED, ACTION_UPDATED, ACTION_DELETED } from "common/event"; +import $event from "common/event"; import * as themes from "options/themes"; import * as options from "options/options"; import { Photo } from "model/photo"; import { onInit, onSetTheme } from "common/hooks"; import { ref, reactive } from "vue"; +import memoizeOne from "memoize-one"; onInit(); @@ -47,6 +48,9 @@ const frontendLoginUri = (frontendUri) => { return `${frontendUri.replace(/\/+$/, "")}/login`; }; +// schemeUriRegExp matches a leading URI scheme ("https:", "data:") so absolute references are left untouched. +const schemeUriRegExp = /^[a-z][a-z0-9+.-]*:/i; + export default class Config { /** * @param {Storage} storage @@ -139,13 +143,14 @@ export default class Config { $event.subscribe("config.updated", (ev, data) => this.setValues(data.config)); $event.subscribe("config.tokens", (ev, data) => this.setTokens(data)); $event.subscribe("count", (ev, data) => this.onCount(ev, data)); - $event.subscribe("people", (ev, data) => this.onPeople(ev, data)); if (this.has("settings")) { this.setTheme(this.get("settings").ui.theme); } else { this.setTheme("default"); } + + this.setReduceMotion(this.getSettings()?.ui.reduceMotion); } loading() { @@ -206,6 +211,7 @@ export default class Config { this.setBatchSize(values.settings); await this.setLanguage(this.getLanguageLocale(), true); this.setTheme(values.settings.ui.theme); + this.setReduceMotion(values.settings.ui.reduceMotion); } // Adjust album counts by access level. @@ -230,72 +236,6 @@ export default class Config { } } - onPeople(ev, data) { - const type = ev.split(".")[1]; - - if (this.debug) { - console.log(ev, data); - } - - if (!this.values.people) { - this.values.people = []; - } - - if (!data || !data.entities || !Array.isArray(data.entities)) { - return; - } - - switch (type) { - case ACTION_CREATED: - this.values.people.unshift(...data.entities); - break; - case ACTION_UPDATED: - for (let i = 0; i < data.entities.length; i++) { - const values = data.entities[i]; - - this.values.people - .filter((m) => m.UID === values.UID) - .forEach((m) => { - for (let key in values) { - if (key !== "UID" && values.hasOwnProperty(key) && values[key] != null && typeof values[key] !== "object") { - m[key] = values[key]; - } - } - }); - } - break; - case ACTION_DELETED: - for (let i = 0; i < data.entities.length; i++) { - const index = this.values.people.findIndex((m) => m.UID === data.entities[i]); - - if (index >= 0) { - this.values.people.splice(index, 1); - } - } - break; - } - } - - // getPerson returns the details of a person by name - // (case-insensitive), or null if it does not exist. - getPerson(name) { - name = name.toLowerCase(); - - const result = this.values.people.filter((m) => m.Name.toLowerCase() === name); - const l = result ? result.length : 0; - - if (l === 0) { - return null; - } else if (l === 1) { - return result[0]; - } else { - if (this.debug) { - console.warn("more than one person having the same name", result); - } - return result[0]; - } - } - // onCount updates the media type, location, people and other // counters used e.g. in the expanded sidebar navigation. onCount(ev, data) { @@ -654,6 +594,16 @@ export default class Config { } } + // setReduceMotion toggles the "reduce-motion" class on the element so CSS can + // suppress interface animations and transitions when the accessibility setting is enabled. + setReduceMotion(enabled) { + if (document && document.documentElement) { + document.documentElement.classList.toggle("reduce-motion", !!enabled); + } + + return this; + } + // getSettings returns the current user's configuration settings. getSettings() { return this.values.settings; @@ -675,6 +625,7 @@ export default class Config { this.setBatchSize(settings); this.setLanguage(settings.ui.language, false); this.setTheme(settings.ui.theme); + this.setReduceMotion(settings.ui.reduceMotion); return this; } @@ -796,6 +747,11 @@ export default class Config { return this.values.settings.features[name] === true; } + // featAppPasswords checks if app passwords (app-specific passwords) are enabled. + featAppPasswords() { + return this.feature("appPasswords"); + } + // filesQuotaReached returns true if the filesystem quota is reached or exceeded. filesQuotaReached() { return Boolean(this.values?.usage?.filesUsedPct >= 100); @@ -864,6 +820,36 @@ export default class Config { return !!this.values?.portal; } + // isClusterOidc returns true when the OIDC provider is the cluster Portal (not an external IdP). + isClusterOidc() { + return !!this.values?.ext?.oidc?.cluster; + } + + // oidcEnabled returns true when OIDC single sign-on is configured. + oidcEnabled() { + return !!this.values?.ext?.oidc?.enabled; + } + + // ldapEnabled returns true when LDAP/AD directory authentication is configured. + ldapEnabled() { + return !!this.values?.ext?.ldap?.enabled; + } + + // oidcLoginUri returns the OIDC login endpoint that starts the provider roundtrip, or "" when off. + oidcLoginUri() { + return this.values?.ext?.oidc?.loginUri || ""; + } + + // oidcLogout returns true when sign-out should perform RP-initiated logout against the provider. + oidcLogout() { + return !!this.values?.ext?.oidc?.logout; + } + + // portalLoginUri returns the cluster Portal's browser-facing login page, or "" when unknown. + portalLoginUri() { + return this.values?.ext?.oidc?.portalLoginUri || ""; + } + // isPro returns true if this is team version. isPro() { return !!this.values?.ext["pro"]; @@ -943,15 +929,36 @@ export default class Config { return s; } + // themeAssetUri resolves a theme asset reference against the base URI (e.g. + // "logo.svg" → "{baseUri}/_theme/logo.svg"); memoized since the base URI is + // fixed once the config is loaded. + themeAssetUri = memoizeOne((uri) => { + if (typeof uri !== "string" || uri === "") { + return uri; + } else if (schemeUriRegExp.test(uri) || uri.startsWith("//")) { + return uri; // absolute, data:/blob:, or protocol-relative + } else if (!uri.startsWith("/")) { + return `${this.baseUri || ""}/_theme/${uri}`; // bare name → theme dir + } else if (this.baseUri && uri.startsWith(`${this.baseUri}/`)) { + return uri; // already prefixed + } + + return `${this.baseUri || ""}${uri}`; // other root path → add prefix + }); + getIcon() { if (this.theme?.variables?.icon) { - return this.theme.variables.icon; + return this.themeAssetUri(this.theme.variables.icon); } switch (this.get("appIcon")) { case "crisp": case "mint": case "bold": + case "bloom": + case "flower": + case "ring": + case "shutter": return `${this.staticUri}/icons/${this.get("appIcon")}.svg`; default: return `${this.staticUri}/icons/logo.svg`; @@ -961,7 +968,7 @@ export default class Config { getLoginIcon() { const loginTheme = themes.Get("login", false); if (loginTheme?.variables?.icon) { - return loginTheme?.variables?.icon; + return this.themeAssetUri(loginTheme?.variables?.icon); } return this.getIcon(); diff --git a/frontend/src/common/download.js b/frontend/src/common/download.js index c4db50bf2..a852c6b7f 100644 --- a/frontend/src/common/download.js +++ b/frontend/src/common/download.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/common/event.js b/frontend/src/common/event.js index 0300a400b..3a74946fe 100644 --- a/frontend/src/common/event.js +++ b/frontend/src/common/event.js @@ -39,7 +39,7 @@ if (trace) { // Action-verb constants for the backend's entity-event helpers — // kept in sync with EntityCreated / EntityUpdated / EntityDeleted / -// EntityArchived / EntityRestored / EntityEdited in +// EntityArchived / EntityRestored in // internal/event/publish_entities.go. Exported as symbols (not just // strings in a Set) so that switch cases and grep / IDE find- // references can locate every event-handling site without having @@ -50,13 +50,12 @@ export const ACTION_UPDATED = "updated"; export const ACTION_DELETED = "deleted"; export const ACTION_ARCHIVED = "archived"; export const ACTION_RESTORED = "restored"; -export const ACTION_EDITED = "edited"; // ENTITY_MUTATIONS lists the action verbs the cache layers and // namespace-level subscribers treat as "something changed; evict". // Frozen so call sites can't mutate the shared default; pass a // different Set explicitly when a caller needs a narrower scope. -export const ENTITY_MUTATIONS = Object.freeze(new Set([ACTION_CREATED, ACTION_UPDATED, ACTION_DELETED, ACTION_ARCHIVED, ACTION_RESTORED, ACTION_EDITED])); +export const ENTITY_MUTATIONS = Object.freeze(new Set([ACTION_CREATED, ACTION_UPDATED, ACTION_DELETED, ACTION_ARCHIVED, ACTION_RESTORED])); // Subscribes to every . event whose action is // in `actions`. Mirrors the page/photos.vue onUpdate switch diff --git a/frontend/src/common/face-markers.js b/frontend/src/common/face-markers.js index 257eddc5e..31f03f422 100644 --- a/frontend/src/common/face-markers.js +++ b/frontend/src/common/face-markers.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/common/form.js b/frontend/src/common/form.js index e647be447..c42841ef2 100644 --- a/frontend/src/common/form.js +++ b/frontend/src/common/form.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/common/gettext.js b/frontend/src/common/gettext.js index 2a3ffc2d0..c2a1a0061 100644 --- a/frontend/src/common/gettext.js +++ b/frontend/src/common/gettext.js @@ -21,6 +21,37 @@ function interpolate(message, params = {}) { }); } +// interpolatePositional substitutes Go printf verbs (%s, %d, %v, %%, …) sequentially from an +// ordered params array, bridging the backend's positional placeholders to the frontend runtime. +// The verb must be a real Go fmt letter and no space flag is allowed, so a literal percent in a +// translated string (e.g. "100% sicher") is not mistaken for a verb and corrupted. +function interpolatePositional(message, params) { + if (message === null || message === undefined) { + return ""; + } + + const text = String(message); + + if (!Array.isArray(params) || params.length === 0) { + return text; + } + + let i = 0; + + return text.replace(/%(%|[-+0#]*\d*(?:\.\d+)?[vTtbcdoOqxXUeEfFgGsp])/g, (match, verb) => { + if (verb === "%") { + return "%"; + } + + if (i >= params.length) { + return match; + } + + const value = params[i++]; + return value === undefined || value === null ? "" : String(value); + }); +} + export let gettext = { $gettext: (msgid, params) => interpolate(msgid, params), $ngettext: (msgid, plural, n, params) => interpolate(n > 1 ? plural : msgid, params), @@ -32,6 +63,12 @@ export function T(msgid, params) { return gettext.$gettext(msgid, params); } +// Tp translates a backend message by its English source id, then substitutes the ordered +// positional params, so backend notifications render in the current UI language. +export function Tp(msgid, params) { + return interpolatePositional(gettext.$gettext(msgid), params); +} + export function $gettext(msgid, params) { return gettext.$gettext(msgid, params); } diff --git a/frontend/src/common/input.js b/frontend/src/common/input.js index 49f7a2a03..67f63832d 100644 --- a/frontend/src/common/input.js +++ b/frontend/src/common/input.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/common/instances.js b/frontend/src/common/instances.js new file mode 100644 index 000000000..5a92dccbf --- /dev/null +++ b/frontend/src/common/instances.js @@ -0,0 +1,343 @@ +/* + +Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. + + This program is free software: you can redistribute it and/or modify + it under Version 3 of the GNU Affero General Public License (the "AGPL"): + + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + The AGPL is supplemented by our Trademark and Brand Guidelines, + which describe how our Brand Assets may be used: + + +Feel free to send an email to hello@photoprism.app if you have questions, +want to support our work, or just want to say hello. + +Additional information can be found in our Developer Guide: + + +*/ + +import { listAuthSessions, buildNamespace, createNamespacedStorage } from "common/storage"; + +// Storage suffixes under which each instance records its public identity, so +// peers on the same shared-domain origin can render a navigation switcher entry. +// The namespace is a SHA-256 hash of the SiteUrl and is not reversible, so the +// URL and title must be persisted explicitly under the instance's namespace. +const InstanceUrlKey = "instance.url"; +const InstanceTitleKey = "instance.title"; +const InstanceIconKey = "instance.icon"; +const InstanceRouteKey = "instance.route"; +const InstancePortalKey = "instance.portal"; + +// InstanceIdentityKeys lists the suffix keys written by persistInstanceIdentity, +// so callers (e.g. session logout) can clear them across storage backends. +export const InstanceIdentityKeys = [InstanceUrlKey, InstanceTitleKey, InstanceIconKey, InstanceRouteKey, InstancePortalKey]; + +// safeWindow returns the browser window if available, else null. +const safeWindow = () => (typeof window === "undefined" ? null : window); + +// isHttpUrl reports whether url is an absolute http(s) URL. Instance URLs are +// read from shared same-origin storage written by peer instances, so the +// switcher rejects any other scheme (javascript:, data:, …) before listing or +// navigating to them. +function isHttpUrl(url) { + if (!url || typeof url !== "string") { + return false; + } + try { + const protocol = new URL(url).protocol; + return protocol === "http:" || protocol === "https:"; + } catch { + return false; + } +} + +// instanceLabel derives a short, distinctive display name from a SiteUrl — the +// last base-path segment (e.g. "pro-1" for ".../i/pro-1/"). The switcher can +// only surface same-origin instances, which always differ by path, so the path +// segment is more distinctive than the frequently-generic site caption/title +// (multiple instances commonly share the default "PhotoPrism" caption). Returns +// "" for a root-path or unparseable URL so the caller falls back to the title. +export function instanceLabel(siteUrl) { + if (!siteUrl || typeof siteUrl !== "string") { + return ""; + } + try { + const segments = new URL(siteUrl).pathname.split("/").filter(Boolean); + return segments.length ? segments[segments.length - 1] : ""; + } catch { + return ""; + } +} + +// instanceTitle derives the switcher label from an instance's client config values, +// preferring the operator-configured site name so a distinctively branded instance +// shows its real name (e.g. "ACME") instead of the lowercase base-path slug. The +// backend siteName (Config.SiteName) resolves SITE_NAME → AppName → SiteTitle and is +// empty for an unbranded instance, so we then fall back to the distinctive base-path +// segment (instanceLabel) — which the menu still shows as a subtitle to keep peers +// that share a generic name distinguishable. Returns "" only when no field is usable. +export function instanceTitle(values) { + if (!values || typeof values !== "object") { + return ""; + } + return values.siteName || instanceLabel(values.siteUrl) || values.siteTitle || values.name || values.siteUrl || ""; +} + +// instancePath returns the base path of a SiteUrl (e.g. "/i/pro-1") so the +// switcher can show how same-origin peers differ without repeating the shared +// origin. Returns "/" for a root install and "" for an unparseable URL. +export function instancePath(siteUrl) { + if (!siteUrl || typeof siteUrl !== "string") { + return ""; + } + try { + const path = new URL(siteUrl).pathname.replace(/\/+$/, ""); + return path || "/"; + } catch { + return ""; + } +} + +// persistInstanceIdentity records this instance's SiteUrl, display title, app icon, +// and frontend route in the given (namespaced) store, so other instances on the same +// origin can list it in the navigation instance switcher and open it at its app entry +// point. The route is the frontend URI (e.g. "/portal" or "/i/pro-1/library"); +// the switcher opens it so a web-overlay landing page at the site root is bypassed. +// No-op without a URL or usable store. +export function persistInstanceIdentity(store, identity) { + if (!store || typeof store.setItem !== "function" || !identity || !identity.url) { + return; + } + + store.setItem(InstanceUrlKey, identity.url); + + if (identity.title) { + store.setItem(InstanceTitleKey, identity.title); + } else { + store.removeItem(InstanceTitleKey); + } + + if (identity.icon) { + store.setItem(InstanceIconKey, identity.icon); + } else { + store.removeItem(InstanceIconKey); + } + + if (identity.route) { + store.setItem(InstanceRouteKey, identity.route); + } else { + store.removeItem(InstanceRouteKey); + } + + // Mark the Portal's own session; Sign-Out delegates it to the Portal end-session endpoint. + if (identity.portal) { + store.setItem(InstancePortalKey, "true"); + } else { + store.removeItem(InstancePortalKey); + } +} + +// listReachableInstances returns the instances (other than currentNamespace) that +// have a live session token and a recorded identity in shared browser storage, +// for the navigation instance switcher. Both localStorage (persistent sessions) +// and sessionStorage (ephemeral sessions, shared across same-tab navigations) are +// scanned, since recordInstanceIdentity writes to whichever the instance uses. +// Results are ordered so the Portal (origin root path) leads, then co-located peers +// by ascending base-path. Returns an empty array on standalone or subdomain-isolated +// deployments where no peer sessions are discoverable. +export function listReachableInstances(options) { + const opts = options || {}; + + let stores; + if (opts.storage) { + stores = [opts.storage]; + } else if (Array.isArray(opts.stores)) { + stores = opts.stores; + } else { + const w = safeWindow(); + stores = [w?.localStorage, w?.sessionStorage]; + } + + const currentPrefix = buildNamespace(opts.currentNamespace); + const seen = new Set(); + const instances = []; + + stores.forEach((store) => { + if (!store || typeof store.getItem !== "function") { + return; + } + + listAuthSessions(store).forEach((session) => { + const namespace = session && session.namespace; + if (!namespace) { + return; + } + + const prefix = buildNamespace(namespace); + if (prefix === currentPrefix || seen.has(prefix)) { + return; + } + + const url = store.getItem(prefix + InstanceUrlKey); + if (!isHttpUrl(url)) { + return; + } + + // route is the app-entry URL to navigate to (the SiteUrl origin + the peer's + // frontend URI). Resolve the stored route against the SiteUrl and reject any + // non-http(s) result; fall back to the SiteUrl for legacy/empty entries. + const storedRoute = store.getItem(prefix + InstanceRouteKey); + let route = url; + if (storedRoute) { + try { + const resolved = new URL(storedRoute, url).href; + if (isHttpUrl(resolved)) { + route = resolved; + } + } catch { + // keep the SiteUrl when the stored route can't be resolved. + } + } + + seen.add(prefix); + instances.push({ + namespace, + url, + route, + title: store.getItem(prefix + InstanceTitleKey) || url, + icon: store.getItem(prefix + InstanceIconKey) || "", + }); + }); + }); + + // Order the switcher so the Portal (origin root path "/") leads, then peers by + // ascending base-path length: co-located instances live under distinct base paths + // (e.g. "/i/pro-1"), so the shortest path is always the Portal at the origin root. + instances.sort((a, b) => { + const pa = instancePath(a.url) || "/"; + const pb = instancePath(b.url) || "/"; + return pa.length - pb.length || pa.localeCompare(pb); + }); + + return instances; +} + +// instanceSessionUrl returns the absolute DELETE-session endpoint for a peer, +// derived from its recorded SiteUrl (api/v1/session), or "" when the +// SiteUrl is missing or not http(s). Same-origin by design (shared-domain proxy). +export function instanceSessionUrl(siteUrl) { + if (!isHttpUrl(siteUrl)) { + return ""; + } + try { + const base = siteUrl.endsWith("/") ? siteUrl : siteUrl + "/"; + const resolved = new URL("api/v1/session", base).href; + return isHttpUrl(resolved) ? resolved : ""; + } catch { + return ""; + } +} + +// listLogoutTargets returns the peer sessions a cluster-wide Sign-Out should revoke +// server-side — {namespace, authToken, url} each, excluding currentNamespace (signed +// out via the normal path). Scans both storage backends. A peer with an unresolvable +// URL is still returned (url === "") so its local storage is still cleared. +export function listLogoutTargets(options) { + const opts = options || {}; + + let stores; + if (opts.storage) { + stores = [opts.storage]; + } else if (Array.isArray(opts.stores)) { + stores = opts.stores; + } else { + const w = safeWindow(); + stores = [w?.localStorage, w?.sessionStorage]; + } + + const currentPrefix = buildNamespace(opts.currentNamespace); + const seen = new Set(); + const targets = []; + + stores.forEach((store) => { + if (!store || typeof store.getItem !== "function") { + return; + } + + listAuthSessions(store).forEach((session) => { + const namespace = session && session.namespace; + const authToken = session && session.authToken; + if (!namespace || !authToken) { + return; + } + + const prefix = buildNamespace(namespace); + if (prefix === currentPrefix || seen.has(prefix)) { + return; + } + + seen.add(prefix); + targets.push({ + namespace, + authToken, + url: instanceSessionUrl(store.getItem(prefix + InstanceUrlKey)), + // True for the cluster Portal's own session (delegated to its end-session endpoint). + portal: store.getItem(prefix + InstancePortalKey) === "true", + }); + }); + }); + + return targets; +} + +// signOutInstances best-effort revokes each target's session via a DELETE +// authenticated with the target's own token. Same-origin only; a target without a +// URL is skipped and failures (unreachable, 401) are swallowed so one bad peer +// can't block Sign-Out. Resolves once all settle; never rejects. +export function signOutInstances(targets, fetchImpl) { + const doFetch = fetchImpl || (typeof fetch === "function" ? fetch.bind(safeWindow() || undefined) : null); + + if (!doFetch || !Array.isArray(targets) || targets.length === 0) { + return Promise.resolve([]); + } + + return Promise.allSettled( + targets + .filter((t) => t && t.url && t.authToken) + .map((t) => + doFetch(t.url, { + method: "DELETE", + // Authenticate with the peer's own token; same-origin so the response + // Set-Cookie (clearing the Portal OP cookie) is honored. + headers: { "X-Auth-Token": t.authToken }, + credentials: "same-origin", + cache: "no-store", + }).catch(() => {}) + ) + ); +} + +// clearInstanceStorage removes every namespaced key for each of namespaces from the +// given raw storage backends, so a cluster-wide Sign-Out leaves no peer tokens or +// stale switcher entries. Each namespace is cleared via a NamespacedStorage wrapper. +export function clearInstanceStorage(namespaces, stores) { + if (!Array.isArray(namespaces) || namespaces.length === 0) { + return; + } + + const backends = (Array.isArray(stores) ? stores : [stores]).filter((s) => s && typeof s.removeItem === "function"); + + namespaces.forEach((namespace) => { + if (!namespace) { + return; + } + backends.forEach((store) => createNamespacedStorage(store, namespace).clear()); + }); +} diff --git a/frontend/src/common/links.js b/frontend/src/common/links.js index 01a6f262d..30adf654b 100644 --- a/frontend/src/common/links.js +++ b/frontend/src/common/links.js @@ -1,23 +1,24 @@ export default { docs: "https://link.photoprism.app/docs", userGuide: "https://docs.photoprism.app/user-guide/", + syncSettings: "https://docs.photoprism.app/user-guide/settings/sync/", developerGuide: "https://docs.photoprism.app/developer-guide/", developerSetup: "https://docs.photoprism.app/developer-guide/setup/", firstSteps: "https://docs.photoprism.app/user-guide/first-steps/", troubleshooting: "https://docs.photoprism.app/getting-started/troubleshooting/", missingPictures: "https://docs.photoprism.app/getting-started/troubleshooting/#missing-pictures", - kb: "https://www.photoprism.app/kb", - bugs: "https://www.photoprism.app/kb/reporting-bugs", + kb: "https://www.photoprism.app/kb/", + bugs: "https://www.photoprism.app/kb/reporting-bugs/", account: "https://my.photoprism.app/dashboard", connect: "https://my.photoprism.app/connect/", compare: "https://link.photoprism.app/personal-editions", - contact: "https://www.photoprism.app/contact", + contact: "https://www.photoprism.app/contact/", pro: { - kb: "https://www.photoprism.app/pro/kb", - support: "https://www.photoprism.app/pro/support", + kb: "https://www.photoprism.app/pro/kb/", + support: "https://www.photoprism.app/pro/support/", supportEmail: "mailto:support@photoprism.pro", register: "https://my.photoprism.app/register/pro", - activation: "https://www.photoprism.app/pro/kb/activation", + activation: "https://www.photoprism.app/pro/kb/activation/", compare: "https://link.photoprism.app/team-editions", }, }; diff --git a/frontend/src/common/log.js b/frontend/src/common/log.js index bd9995145..686788a39 100644 --- a/frontend/src/common/log.js +++ b/frontend/src/common/log.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/common/map.js b/frontend/src/common/map.js index cbfd69a91..8cba93560 100644 --- a/frontend/src/common/map.js +++ b/frontend/src/common/map.js @@ -1,6 +1,124 @@ let loading = false; let maplibregl = null; +// Screen-space distance (in pixels) below which two photo markers are treated as sharing the +// same spot and merged into one stack. Roughly the marker size, so pictures that would +// otherwise overlap and hide each other are grouped until the map is zoomed in far enough to +// separate them. +const stackTolerancePx = 40; + +// projectCoords resolves a feature's [lng, lat] coordinate to a screen point using the given +// projection. It accepts maplibregl Point objects ({x, y}) as well as plain [x, y] arrays and +// falls back to the raw coordinate so the grouping stays testable without a live map. +function projectCoords(coords, project) { + if (typeof project === "function") { + const p = project(coords); + if (p && typeof p.x === "number" && typeof p.y === "number") { + return [p.x, p.y]; + } + if (Array.isArray(p) && p.length >= 2) { + return [p[0], p[1]]; + } + } + // No projection: compare raw [lng, lat] degrees. The tolerance is then in degrees, not + // pixels, and grouping is no longer zoom-aware — callers rendering on a live map MUST pass + // a projection. This path exists so the grouping can be unit-tested without a map. + return [coords[0], coords[1]]; +} + +// groupGeoFeatures groups point features that render close enough to overlap so that +// coincident or near-coincident pictures stack into a single marker with a counter instead of +// hiding each other once the map is zoomed past the clustering threshold. The optional +// `project` callback maps a feature's [lng, lat] coordinate to screen pixels, which keeps the +// grouping zoom-aware: truly coincident pictures always stack, while ones a few meters apart +// only separate once zoomed in far enough. Exact-coordinate keying is intentionally avoided +// because stored coordinates rarely match bit for bit (GPS jitter, tile quantization). +// Features are deduplicated by UID because querySourceFeatures may return the same point once +// per tile it overlaps. Each group carries the lat/lng bounding box of its members and a +// stable key (smallest UID) so a click opens exactly those pictures and the marker survives +// re-renders. +export function groupGeoFeatures(features, project, tolerance = stackTolerancePx) { + const groups = []; + + if (!Array.isArray(features)) { + return groups; + } + + const limit = tolerance * tolerance; + + for (let i = 0; i < features.length; i++) { + const feature = features[i]; + const coords = feature?.geometry?.coordinates; + + if (!Array.isArray(coords) || coords.length < 2) { + continue; + } + + const point = projectCoords(coords, project); + + // Join the first existing group whose anchor lies within the tolerance. + let group = null; + for (let g = 0; g < groups.length; g++) { + const dx = groups[g].point[0] - point[0]; + const dy = groups[g].point[1] - point[1]; + if (dx * dx + dy * dy <= limit) { + group = groups[g]; + break; + } + } + + if (!group) { + group = { + coords, + point, + features: [], + uids: {}, + bounds: { latN: coords[1], lngE: coords[0], latS: coords[1], lngW: coords[0] }, + }; + groups.push(group); + } + + const uid = feature.properties?.UID; + + // Skip duplicate features that reference the same picture. + if (uid) { + if (group.uids[uid]) { + continue; + } + group.uids[uid] = true; + } + + group.features.push(feature); + + // Expand the group's lat/lng bounding box to include this picture. + const lng = coords[0]; + const lat = coords[1]; + if (lat > group.bounds.latN) { + group.bounds.latN = lat; + } + if (lat < group.bounds.latS) { + group.bounds.latS = lat; + } + if (lng > group.bounds.lngE) { + group.bounds.lngE = lng; + } + if (lng < group.bounds.lngW) { + group.bounds.lngW = lng; + } + } + + // Derive a stable key from the smallest UID so the marker survives re-renders, even when + // querySourceFeatures returns the same pictures in a different order between frames. Fall + // back to the first feature's id (never the float coordinates, which drift between frames). + for (let g = 0; g < groups.length; g++) { + const group = groups[g]; + const uids = Object.keys(group.uids); + group.key = uids.length ? uids.sort()[0] : String(group.features[0]?.id ?? g); + } + + return groups; +} + // Loads the maplibregl library. export async function load() { if (maplibregl !== null || loading) { diff --git a/frontend/src/common/notify.js b/frontend/src/common/notify.js index 55c6b90d6..10692d7b5 100644 --- a/frontend/src/common/notify.js +++ b/frontend/src/common/notify.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. @@ -30,26 +30,34 @@ let ajaxPending = 0; let ajaxCallbacks = []; const $notify = { - info: function (message) { - $event.publish("notify.info", { message }); + // info publishes an info notification. + info: function (message, messageId, messageParams) { + $event.publish("notify.info", { message, messageId, messageParams }); }, - warn: function (message) { - $event.publish("notify.warning", { message }); + // warn publishes a warning notification. + warn: function (message, messageId, messageParams) { + $event.publish("notify.warning", { message, messageId, messageParams }); }, - error: function (message) { - $event.publish("notify.error", { message }); + // error publishes an error notification; the optional messageId/messageParams + // let notify.vue render it in the current UI locale via Tp. + error: function (message, messageId, messageParams) { + $event.publish("notify.error", { message, messageId, messageParams }); }, - success: function (message) { - $event.publish("notify.success", { message }); + // success publishes a success notification. + success: function (message, messageId, messageParams) { + $event.publish("notify.success", { message, messageId, messageParams }); }, - logout: function (message) { - $event.publish("notify.error", { message }); - $event.publish("session.logout", { message }); + // logout publishes an error notification and triggers a session.logout event. + logout: function (message, messageId, messageParams) { + $event.publish("notify.error", { message, messageId, messageParams }); + $event.publish("session.logout", { message, messageId, messageParams }); }, + // ajaxStart marks an AJAX request as started and emits ajax.start. ajaxStart: function () { ajaxPending++; $event.publish("ajax.start"); }, + // ajaxEnd marks an AJAX request as finished, emits ajax.end, and runs queued idle callbacks. ajaxEnd: function () { ajaxPending--; $event.publish("ajax.end"); @@ -60,6 +68,7 @@ const $notify = { callbacks.forEach((cb) => cb()); } }, + // ajaxBusy reports whether any AJAX requests are still pending. ajaxBusy: function () { if (ajaxPending < 0) { ajaxPending = 0; @@ -67,6 +76,7 @@ const $notify = { return ajaxPending > 0; }, + // ajaxWait resolves once no AJAX requests are pending or the timeout elapses. ajaxWait: function (idleDelay = 64, timeout = 8000) { return new Promise((resolve) => { const start = Date.now(); @@ -94,6 +104,7 @@ const $notify = { settle(); }); }, + // blockUI shows the busy overlay, optionally setting its CSS class. blockUI: function (className) { const el = document.getElementById("busy-overlay"); @@ -104,6 +115,7 @@ const $notify = { } } }, + // unblockUI hides the busy overlay. unblockUI: function () { const el = document.getElementById("busy-overlay"); @@ -112,9 +124,11 @@ const $notify = { el.className = ""; } }, + // wait shows a "Please wait" info notification. wait: function () { this.info($gettext("Please wait…")); }, + // busy shows a "Busy, please wait" warning notification. busy: function () { this.warn($gettext("Busy, please wait…")); }, diff --git a/frontend/src/common/pwa.js b/frontend/src/common/pwa.js index baa84c4e7..95589321c 100644 --- a/frontend/src/common/pwa.js +++ b/frontend/src/common/pwa.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/common/selection.js b/frontend/src/common/selection.js index 9d60a13a8..39ac2510a 100644 --- a/frontend/src/common/selection.js +++ b/frontend/src/common/selection.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/common/server.js b/frontend/src/common/server.js index 7a98278ab..489471be0 100644 --- a/frontend/src/common/server.js +++ b/frontend/src/common/server.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. @@ -26,6 +26,7 @@ Additional information can be found in our Developer Guide: import $api from "common/api"; import { $config } from "app/session"; import $notify from "common/notify"; +import { $gettext } from "common/gettext"; function poll(interval, maxAttempts) { let attempts = 0; @@ -75,13 +76,13 @@ export function restart(uri) { }) .catch(() => { $notify.ajaxEnd(); - $notify.error("Failed to restart server"); + $notify.error($gettext("Failed to restart server")); $notify.unblockUI(); }); }) .catch(() => { $notify.ajaxEnd(); - $notify.error("Failed to restart server"); + $notify.error($gettext("Failed to restart server")); $notify.unblockUI(); }); } diff --git a/frontend/src/common/session.js b/frontend/src/common/session.js index c63f65582..7eb06a4b5 100644 --- a/frontend/src/common/session.js +++ b/frontend/src/common/session.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. @@ -26,6 +26,14 @@ Additional information can be found in our Developer Guide: import $api from "common/api"; import $event from "common/event"; import { createNamespacedStorage } from "common/storage"; +import { + persistInstanceIdentity, + InstanceIdentityKeys, + instanceTitle, + listLogoutTargets, + signOutInstances, + clearInstanceStorage, +} from "common/instances"; import { $view } from "common/view"; import User from "model/user"; import Socket from "websocket.js"; @@ -42,6 +50,12 @@ const LogoutSignalKey = "login.logout"; // in sessionStorage so a closed tab clears it, and so a failed/abandoned OIDC // roundtrip can fall back to the local login form instead of looping. const OidcAttemptKey = "login.oidc.attempt"; +// Loop guard for the post-login redirect (login.next): the timestamp of the last +// follow, and the window within which a re-entry counts as a bounce-back loop. +// Lets /login fall back to the default route instead of looping when the redirect +// target (e.g. the OIDC OP /api/v1/oauth/authorize) can't authenticate the navigation. +const LoginRedirectAttemptKey = "login.next.at"; +const LoginRedirectLoopWindow = 6000; const resolveStorageNamespace = (config) => { if (typeof config?.storageNamespace === "string" && config.storageNamespace !== "") { @@ -148,6 +162,11 @@ export default class Session { // Authenticated? this.auth = this.isUser(); + // Record this instance's identity so peers on a shared domain can switch to it. + if (this.auth) { + this.recordInstanceIdentity(); + } + // Subscribe to session events. $event.subscribe("session.logout", () => { return this.onLogout(); @@ -332,6 +351,8 @@ export default class Session { this.clearLegacyKey("session.scope"); this.clearLegacyKey("authError"); this.clearLegacyKey("session.error"); + this.clearLegacyKey("session.messageId"); + this.clearLegacyKey("session.messageParams"); delete $api.defaults.headers.common[RequestHeader]; } @@ -438,6 +459,35 @@ export default class Session { this.user = new User(user); this.storage.setItem(this.storageKey + ".user", JSON.stringify(user)); this.auth = this.isUser(); + + if (this.auth) { + this.recordInstanceIdentity(); + } + } + + // recordInstanceIdentity stores this instance's SiteUrl, display title, and app + // icon under the active namespace so other instances on the same origin can offer + // a switch entry. The title prefers the configured site name (see instanceTitle) + // and falls back to the distinctive base-path segment for unbranded instances; + // the icon is the root-relative app icon, which resolves on the shared origin from + // any peer. No-op when the site URL is unknown or storage is unavailable. + recordInstanceIdentity() { + const values = this.config?.values; + + if (!values || !values.siteUrl) { + return; + } + + persistInstanceIdentity(this.storage, { + url: values.siteUrl, + // Frontend URI (e.g. "/portal" or "/i/pro-1/library") so peers open the + // app entry point rather than a web-overlay landing page at the site root. + route: this.config?.frontendUri, + title: instanceTitle(values), + icon: this.config.getIcon(), + // Flag the Portal's own session so Sign-Out delegates it to the Portal end-session endpoint. + portal: !!this.config?.isPortal?.(), + }); } getUser() { @@ -609,6 +659,9 @@ export default class Session { this.clearNamespacedKey(this.storageKey + ".user"); this.clearLegacyKey("user"); this.clearLegacyKey("session.user"); + // Drop this instance's switcher identity so a logged-out instance is no + // longer offered as a switch target by peers on the same shared domain. + InstanceIdentityKeys.forEach((key) => this.clearNamespacedKey(key)); } deleteClipboard() { @@ -753,7 +806,36 @@ export default class Session { $view.redirect(url, delay, true); } - onLogout(noRedirect) { + // isClusterSession reports whether the current session was signed in through the + // cluster Portal OIDC provider, so sign-out runs the cluster-wide fan-out and + // clears the Portal OP cookie. Read before reset()/signOut() clears the provider. + isClusterSession() { + return this.getProvider() === "oidc" && !!this.config?.isClusterOidc?.(); + } + + // logoutRedirectUri returns the post-sign-out landing URL: a cluster-OIDC session + // goes directly to the Portal login page (re-auth → instance chooser), everyone + // else to the local login. The instance OIDC roundtrip is never re-initiated on + // sign-out, since that would pin the Portal login's return_to to the just-left + // instance and dead-end accounts without a grant there; when the Portal login URL + // is unknown, the local form is the fallback landing. Read provider before reset(). + logoutRedirectUri() { + if (this.isClusterSession()) { + return this.config.portalLoginUri() || this.config.loginUri; + } + + return this.config.loginUri; + } + + // onLogout resets client state and resolves to the post-sign-out landing URL. It follows + // the redirect itself unless noRedirect is set, in which case the caller does (e.g. the + // /logout route guard), so the resolved URL — the provider logout URL when present — is + // returned either way. + onLogout(noRedirect, providerLogoutUri) { + // Prefer the backend's provider logout URL (RP-initiated logout); else the local target, + // resolved before reset() clears the auth provider. + const redirectUri = providerLogoutUri || this.logoutRedirectUri(); + this.reset(); // Drop stale deep-link redirects; raise one-shot flag so /login skips @@ -762,10 +844,10 @@ export default class Session { this.localStorage?.setItem(LogoutSignalKey, "1"); if (noRedirect !== true && !this.isLogin()) { - this.followRedirect(this.config.loginUri); + this.followRedirect(redirectUri); } - return Promise.resolve(); + return Promise.resolve(redirectUri); } // Reads and clears the one-shot logout flag set by onLogout(). @@ -800,12 +882,34 @@ export default class Session { return raised; } + // Records the time we last followed the post-login redirect, so a fast + // bounce-back can be recognized as a loop. Stored per browser tab. + markLoginRedirectAttempt() { + this.sessionStorage?.setItem(LoginRedirectAttemptKey, String(Date.now())); + return this; + } + + // loginRedirectLooping reports whether the post-login redirect was followed + // within the last LoginRedirectLoopWindow ms, i.e. the target bounced straight + // back without authenticating the navigation — used to break redirect loops. + loginRedirectLooping() { + const at = parseInt(this.sessionStorage?.getItem(LoginRedirectAttemptKey) || "0", 10); + return at > 0 && Date.now() - at < LoginRedirectLoopWindow; + } + + // Clears the post-login redirect loop guard. + clearLoginRedirectAttempt() { + this.sessionStorage?.removeItem(LoginRedirectAttemptKey); + return this; + } + logout(noRedirect) { if (this.isAuthenticated()) { return $api .delete("session") - .then(() => { - return this.onLogout(noRedirect); + .then((resp) => { + // providerLogoutUri (RP-initiated logout) redirects the browser to the provider. + return this.onLogout(noRedirect, resp?.data?.providerLogoutUri); }) .catch(() => { return this.onLogout(noRedirect); @@ -815,10 +919,55 @@ export default class Session { } } - // Synchronous logout for SPA route guards (/logout): fires server DELETE - // with the captured token first (avoiding a 401 echo that would re-raise - // the logout flag), then resets client state. + // revokePeerSessions best-effort revokes every reachable peer instance's session + // server-side and clears their namespaced keys from local storage. The peer keys + // are cleared synchronously (the DELETEs hold their own tokens), so a route guard + // can fire-and-forget while the async revocation settles. Returns the fan-out + // promise. Shared by logoutEverywhere (awaits) and signOut (fire-and-forget). + // + // Unwraps to the raw underlying store first: this.localStorage / this.sessionStorage + // are NamespacedStorage wrappers (getAppStorage), so enumerating or clearing a + // cross-namespace key through one double-prefixes it (pp:a:pp:b:…) and misses it. + revokePeerSessions() { + const rawStore = (s) => (s && s.storage ? s.storage : s); + const stores = [rawStore(this.localStorage), rawStore(this.sessionStorage)]; + + let targets = []; + try { + targets = listLogoutTargets({ currentNamespace: this.storageNamespace, stores }); + } catch { + targets = []; + } + + // Cluster-OIDC Sign-Out delegates the Portal session to its end-session endpoint (which + // performs the upstream RP-logout); revoking it here would strip the session it needs. + let deleteTargets = targets; + if (this.isClusterSession() && this.config?.oidcLogout?.()) { + deleteTargets = targets.filter((t) => !t.portal); + } + + const revoked = signOutInstances(deleteTargets).catch(() => {}); + clearInstanceStorage( + targets.map((t) => t.namespace), + stores + ); + return revoked; + } + + // logoutEverywhere performs a cluster-wide Sign-Out (Tier 2): best-effort revokes + // every reachable peer instance's session server-side, drops their local tokens, + // then signs out the current instance (clearing the OP cookie) and redirects. + // Shared-domain (same-origin) clusters only; always resolves. + logoutEverywhere(noRedirect) { + return this.revokePeerSessions().then(() => this.logout(noRedirect)); + } + + // Synchronous cluster-wide logout for SPA route guards (/logout): revokes every + // reachable peer session and the current one (best-effort, in the background), + // clears shared storage, then resets client state. Firing the current DELETE with + // the captured token avoids a 401 echo that would re-raise the logout flag. signOut() { + this.revokePeerSessions(); const token = this.getAuthToken(); if (token) { $api.delete("session", { headers: { [RequestHeader]: token } }).catch(() => {}); diff --git a/frontend/src/common/sphere.js b/frontend/src/common/sphere.js new file mode 100644 index 000000000..1d6503a3d --- /dev/null +++ b/frontend/src/common/sphere.js @@ -0,0 +1,114 @@ +/* + +Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. + + This program is free software: you can redistribute it and/or modify + it under Version 3 of the GNU Affero General Public License (the "AGPL"): + + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + The AGPL is supplemented by our Trademark and Brand Guidelines, + which describe how our Brand Assets may be used: + + +Feel free to send an email to hello@photoprism.app if you have questions, +want to support our work, or just want to say hello. + +Additional information can be found in our Developer Guide: + + +*/ + +import * as media from "common/media"; + +// EQUIRECTANGULAR_RATIO_TOLERANCE bounds how far a video frame may deviate from the +// 2:1 equirectangular aspect ratio and still be treated as 360° media. +const EQUIRECTANGULAR_RATIO_TOLERANCE = 0.15; + +// is360Equirectangular reports whether a slide/thumb model is equirectangular 360° +// content that should open in the sphere viewer. An explicit "equirectangular" +// projection is authoritative, but a full sphere is ~2:1: when the frame size is known +// and clearly not 2:1 it stays in the flat viewer, since a partial/cylindrical panorama +// tagged equirectangular (or promoted from GPano markers) would otherwise render as a +// vertically distorted sphere. Any other non-empty projection (cubemap, …) is never 360°. +// Many 360° videos carry no projection tag PhotoPrism can read, so a panorama-flagged +// video with no projection falls back to the same 2:1 frame test — this keeps genuine +// spherical videos opening while cubemap (4:3, 6:1) and ultrawide (~2.35:1) clips stay flat. +export function is360Equirectangular(model) { + const projection = (model?.Projection || "").toLowerCase(); + const w = Number(model?.Width); + const h = Number(model?.Height); + const known = w > 0 && h > 0; + const is2to1 = known && Math.abs(w / h - 2) <= EQUIRECTANGULAR_RATIO_TOLERANCE; + if (projection === "equirectangular") { + return !known || is2to1; + } + if (projection) { + return false; + } + const isVideo = model?.Type === media.Video || model?.Type === media.Animated; + if (!isVideo || model?.Panorama !== true) { + return false; + } + return is2to1; +} + +// createSphereViewer mounts a Photo Sphere Viewer instance for an equirectangular photo or video. +// The renderer (and its ThreeJS dependency) is dynamic-imported on first call so the base bundle +// is unaffected when no 360° media is opened. +export async function createSphereViewer(container, src, opts = {}) { + const [coreMod, videoMod, videoAdapterMod] = await Promise.all([ + import(/* webpackChunkName: "sphere-viewer" */ "@photo-sphere-viewer/core"), + opts.isVideo + ? import(/* webpackChunkName: "sphere-viewer" */ "@photo-sphere-viewer/video-plugin") + : Promise.resolve(null), + opts.isVideo + ? import(/* webpackChunkName: "sphere-viewer" */ "@photo-sphere-viewer/equirectangular-video-adapter") + : Promise.resolve(null), + ]); + + await import(/* webpackChunkName: "sphere-viewer" */ "@photo-sphere-viewer/core/index.css"); + + if (opts.isVideo) { + await import(/* webpackChunkName: "sphere-viewer" */ "@photo-sphere-viewer/video-plugin/index.css"); + return new coreMod.Viewer({ + container, + adapter: [videoAdapterMod.EquirectangularVideoAdapter, { muted: !!opts.muted, autoplay: false }], + panorama: { source: src }, + plugins: [videoMod.VideoPlugin], + navbar: false, + keyboard: "always", + defaultYaw: 0, + defaultPitch: 0, + }); + } + + return new coreMod.Viewer({ + container, + panorama: src, + navbar: false, + keyboard: "always", + defaultYaw: 0, + defaultPitch: 0, + }); +} + +// findSphereVideoElement returns the underlying HTMLVideoElement that PSV's +// EquirectangularVideoAdapter uses as a WebGL texture source. The adapter does +// not insert the element into the DOM, so we read it off the adapter instance +// the viewer exposes after the panorama has finished loading. +export function findSphereVideoElement(viewer) { + return viewer?.adapter?.video || null; +} + +// destroySphereViewer tears down a viewer instance, releasing its WebGL context and textures. +// Safe to call on null or an already-destroyed viewer. +export function destroySphereViewer(viewer) { + if (viewer && typeof viewer.destroy === "function") { + viewer.destroy(); + } +} diff --git a/frontend/src/common/storage.js b/frontend/src/common/storage.js index d2574b729..d29909bdc 100644 --- a/frontend/src/common/storage.js +++ b/frontend/src/common/storage.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. @@ -38,6 +38,8 @@ const defaultLegacyClearKeys = new Set([ "session.provider", "session.scope", "session.error", + "session.messageId", + "session.messageParams", "clipboard", "clipboard.photos", "clipboard.albums", diff --git a/frontend/src/common/typeahead-cache.js b/frontend/src/common/typeahead-cache.js index bc5ca0df2..0a2396abb 100644 --- a/frontend/src/common/typeahead-cache.js +++ b/frontend/src/common/typeahead-cache.js @@ -1,9 +1,11 @@ -// Module-scope cache for the labels and albums typeahead lists shared by the -// sidebar info panel, batch-edit dialog, and edit-dialog labels tab. -// getLabels / getAlbums return a Promise and coalesce concurrent callers -// onto a single in-flight request. WS mutation events evict the matching slot. +// Module-scope cache for the labels, albums, and people typeahead lists shared +// by the sidebar info panel, batch-edit dialog, edit-dialog tabs, and the +// people/face name pickers. getLabels / getAlbums / getPeople return a +// Promise and coalesce concurrent callers onto a single in-flight +// request. WS mutation events evict the matching slot. import Album from "model/album"; import Label from "model/label"; +import Subject from "model/subject"; import $event, { subscribeEntityActions } from "common/event"; // Pragmatic ceiling shared by every consumer; over-cap libraries log a warning @@ -11,10 +13,14 @@ import $event, { subscribeEntityActions } from "common/event"; export const CAP = 5000; const state = { - labels: { data: null, fetch: null }, - albums: { data: null, fetch: null }, + labels: { data: null, fetch: null, epoch: 0 }, + albums: { data: null, fetch: null, epoch: 0 }, + people: { data: null, fetch: null, epoch: 0 }, }; +// Bumping the epoch invalidates any fetch that started before this point, so a +// request still in flight when the slot is evicted (or seeded) cannot resolve +// later and silently overwrite the slot with stale data. See get(). function evict(field) { const slot = state[field]; if (!slot) { @@ -22,6 +28,61 @@ function evict(field) { } slot.data = null; slot.fetch = null; + slot.epoch += 1; +} + +// upsertPeople merges saved subjects into a populated people slot so a freshly +// created or renamed name is suggestible immediately, without waiting for the +// subjects/people WS event (which can lag a quick re-entry). It only mutates an +// already-loaded slot; a cold slot is left untouched so the next getPeople() +// fetches the full, server-ordered list. Entries are matched by UID, falling +// back to a case-insensitive name match so an existing person is updated rather +// than duplicated. The merge is idempotent: re-saving an unchanged name leaves +// the slot and its epoch untouched, so a redundant save cannot invalidate a +// pending fetch or replace the list with an equivalent copy. +// +// Contract: Marker.setName() and Face.setName() seed automatically. Callers that +// create or rename a person through any other path (e.g. Subject.update() from +// the recognized-people page) must call upsertPerson() themselves. +function upsertPeople(items) { + const slot = state.people; + if (!Array.isArray(slot.data) || !Array.isArray(items)) { + return; + } + + const next = slot.data.slice(); + let changed = false; + + for (const raw of items) { + const name = (raw?.Name || "").trim(); + if (!name) { + continue; + } + + const uid = raw?.UID || ""; + let idx = uid ? next.findIndex((p) => p && p.UID === uid) : -1; + if (idx === -1) { + idx = next.findIndex((p) => p && p.Name && p.Name.localeCompare(name, undefined, { sensitivity: "base" }) === 0); + } + + if (idx >= 0) { + const existing = next[idx]; + const mergedUid = uid || existing.UID; + // Nothing to do when the slot already holds this exact UID and name. + if (existing.UID === mergedUid && existing.Name === name) { + continue; + } + next[idx] = { ...existing, UID: mergedUid, Name: name }; + } else { + next.push({ UID: uid, Name: name }); + } + changed = true; + } + + if (changed) { + slot.data = next; + slot.epoch += 1; + } } function fetchLabels() { @@ -44,6 +105,16 @@ function fetchAlbums() { }); } +function fetchPeople() { + return Subject.search({ count: CAP, order: "name", type: "person" }).then((resp) => { + const models = Array.isArray(resp?.models) ? resp.models : []; + if (models.length === CAP) { + console.warn(`Subject.search returned ${CAP} results — list may be truncated.`); + } + return models; + }); +} + function get(field, fetcher) { const slot = state[field]; if (slot.data) { @@ -52,14 +123,21 @@ function get(field, fetcher) { if (slot.fetch) { return slot.fetch; } + // Snapshot the epoch so a fetch that finishes after an evict/upsert (which + // bump the epoch) is discarded instead of caching now-stale results. + const epoch = slot.epoch; slot.fetch = fetcher() .then((data) => { - slot.data = data; - slot.fetch = null; + if (slot.epoch === epoch) { + slot.data = data; + slot.fetch = null; + } return data; }) .catch((err) => { - slot.fetch = null; + if (slot.epoch === epoch) { + slot.fetch = null; + } throw err; }); return slot.fetch; @@ -70,11 +148,15 @@ function get(field, fetcher) { export const typeaheadCache = { getLabels: () => get("labels", fetchLabels), getAlbums: () => get("albums", fetchAlbums), + getPeople: () => get("people", fetchPeople), + upsertPerson: (person) => upsertPeople([person]), evictLabels: () => evict("labels"), evictAlbums: () => evict("albums"), + evictPeople: () => evict("people"), clear: () => { evict("labels"); evict("albums"); + evict("people"); }, }; @@ -83,15 +165,21 @@ export const typeaheadCache = { subscribeEntityActions("labels", () => evict("labels")); subscribeEntityActions("albums", () => evict("albums")); +// People mutations surface on both the subjects and people channels (a rename +// publishes subjects.updated and people.updated); either evicts the people slot. +subscribeEntityActions("subjects", () => evict("people")); +subscribeEntityActions("people", () => evict("people")); + // Belt-and-braces eviction for album mutations that surface only as a config // reload (covers future config-touching mutations not on the entity channel). $event.subscribe("config.updated", () => evict("albums")); -// Drop both lists on logout so user A's data cannot be served to user B in +// Drop all lists on logout so user A's data cannot be served to user B in // the same tab; mirrors Photo.clearCache()'s session.logout path. $event.subscribe("session.logout", () => { evict("labels"); evict("albums"); + evict("people"); }); export default typeaheadCache; diff --git a/frontend/src/common/util.js b/frontend/src/common/util.js index 97e40f5f3..60a1bc698 100644 --- a/frontend/src/common/util.js +++ b/frontend/src/common/util.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. @@ -470,6 +470,27 @@ export default class $util { return navigator.maxTouchPoints > 0; } + // shouldOpenOnHover reports whether menus should open on hover: the user's UI + // preference (default on) gated by the device having no touch input. + static shouldOpenOnHover() { + return ($config.getSettings()?.ui?.openOnHover ?? true) && !$util.hasTouch(); + } + + // mapAnimateDuration returns the map fly-to animation duration in milliseconds, forcing 0 + // (no animation) when the Reduce Motion accessibility setting is enabled. A non-negative + // overrideMs takes precedence over the global Maps.Animate preference. + static mapAnimateDuration(settings, overrideMs = -1) { + if (settings?.ui?.reduceMotion) { + return 0; + } + + if (overrideMs >= 0) { + return overrideMs; + } + + return settings?.maps?.animate ?? 0; + } + // isMobile returns true when the current user agent or touch capability indicates a mobile device. // The `> 2` touch check covers iPads in desktop mode, where the user agent omits the mobile hint. static isMobile() { diff --git a/frontend/src/common/view.js b/frontend/src/common/view.js index 9a30af08c..f2948479f 100644 --- a/frontend/src/common/view.js +++ b/frontend/src/common/view.js @@ -5,6 +5,15 @@ import { getAppSessionStorage, getAppStorage } from "common/storage"; const TouchStartEvent = "touchstart"; const TouchMoveEvent = "touchmove"; +// Selector for the document's viewport meta tag. +const ViewportMetaSelector = 'meta[name="viewport"]'; + +// Viewport content that disables the browser's native pinch-zoom of the whole page. +const ViewportNoZoom = "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"; + +// Token in a viewport content string indicating native zoom is already disabled. +const ViewportNoZoomToken = "user-scalable=no"; + // True if debug and/or trace logs should be recorded. const debug = window.__CONFIG__?.debug; const trace = window.__CONFIG__?.trace; @@ -405,6 +414,7 @@ export class View { this.scopes = []; this.hideScrollbar = false; this.preventNavigation = false; + this.savedViewportContent = ""; this.focusScopes = new Map(); // Tracks the most recent history position and derived navigation direction so components can @@ -555,6 +565,7 @@ export class View { let hideScrollbar = this.len() > 2 ? this.hideScrollbar : false; let disableScrolling = false; let disableNavigationGestures = false; + let disableViewportZoom = false; let preventNavigation = uid > 0 && !name.startsWith("PPage"); switch (name) { @@ -582,6 +593,7 @@ export class View { hideScrollbar = true; disableScrolling = true; disableNavigationGestures = true; + disableViewportZoom = true; preventNavigation = true; break; } @@ -661,6 +673,14 @@ export class View { } } + // Lock native pinch-zoom while a flagged overlay is active, restore it otherwise. + // Both helpers are idempotent, so re-applying the same state is a no-op. + if (disableViewportZoom) { + this.disableNativeZoom(); + } else { + this.restoreNativeZoom(); + } + if (debug) { console.groupEnd(); } @@ -818,6 +838,47 @@ export class View { return setFocus(el, selector, scroll); } + // disableNativeZoom locks the viewport so the browser can't pinch-zoom the whole page + // while an overlay (e.g. the lightbox) handles zoom itself; restoreNativeZoom restores + // the saved content. Idempotent; assumes one active overlay (savedViewportContent is + // app-global), which View.apply() upholds by locking only for the top-of-stack view. + disableNativeZoom() { + if (this.savedViewportContent) { + return; + } + + const viewport = document.querySelector(ViewportMetaSelector); + + if (!viewport) { + return; + } + + const content = viewport.getAttribute("content") || ""; + + // Nothing to restore if the base viewport already blocks zoom (e.g. the Zoom setting is off). + if (content.includes(ViewportNoZoomToken)) { + return; + } + + this.savedViewportContent = content; + viewport.setAttribute("content", ViewportNoZoom); + } + + // restoreNativeZoom restores the viewport content saved by disableNativeZoom, if any. + restoreNativeZoom() { + if (!this.savedViewportContent) { + return; + } + + const viewport = document.querySelector(ViewportMetaSelector); + + if (viewport) { + viewport.setAttribute("content", this.savedViewportContent); + } + + this.savedViewportContent = ""; + } + // Navigates to the specified URL, optionally with a delay set in milliseconds and a blocked user interface. redirect(url, delay, blockUI) { // Return if no URL was passed. diff --git a/frontend/src/common/websocket.js b/frontend/src/common/websocket.js index 1a1674de7..cc0e3514e 100644 --- a/frontend/src/common/websocket.js +++ b/frontend/src/common/websocket.js @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/component/action/menu.vue b/frontend/src/component/action/menu.vue index fe6c73dd4..fb8d1608c 100644 --- a/frontend/src/component/action/menu.vue +++ b/frontend/src/component/action/menu.vue @@ -63,9 +63,15 @@ export default { return { visible: false, actions: [], - openOnHover: !this.$util.hasTouch(), }; }, + computed: { + // openOnHover reactively reflects the user's menu open-on-hover preference so a settings + // change applies without a page reload (persistent menus keep no mount-time snapshot). + openOnHover() { + return this.$util.shouldOpenOnHover(); + }, + }, methods: { show() { this.actions = this.items().filter((action) => action.visible); diff --git a/frontend/src/component/album/edit/dialog.vue b/frontend/src/component/album/edit/dialog.vue index bae854e20..f8d0acb4b 100644 --- a/frontend/src/component/album/edit/dialog.vue +++ b/frontend/src/component/album/edit/dialog.vue @@ -96,6 +96,7 @@ diff --git a/frontend/src/component/defaults.js b/frontend/src/component/defaults.js index 0d1e3b69b..0fe136e3d 100644 --- a/frontend/src/component/defaults.js +++ b/frontend/src/component/defaults.js @@ -184,7 +184,8 @@ export default { ripple: false, }, VDataTable: { - color: "background", + // Forwarded to the footer only as the "items per page" select's active-item color (not the table). + color: "surface-variant", itemsPerPage: -1, hover: true, }, diff --git a/frontend/src/component/lightbox.vue b/frontend/src/component/lightbox.vue index a739c9a29..674eb0663 100644 --- a/frontend/src/component/lightbox.vue +++ b/frontend/src/component/lightbox.vue @@ -22,6 +22,7 @@ @keydown.tab="onTabKey" @click.capture="captureDialogClick" @pointerdown.capture="captureDialogPointerDown" + @wheel.capture="captureDialogWheel" > @@ -128,6 +170,7 @@ import * as media from "common/media"; import { getAppSessionStorage, getAppStorage } from "common/storage"; import * as contexts from "options/contexts"; import { $faceMarkers } from "common/face-markers"; +import { createSphereViewer, destroySphereViewer, findSphereVideoElement, is360Equirectangular } from "common/sphere"; const VIDEO_EVENT_TYPES = [ "loadstart", @@ -150,6 +193,10 @@ const VIDEO_EVENT_TYPES = [ const VIDEO_REMOTE_EVENT_TYPES = ["connect", "connecting", "disconnect"]; +// Max pointer travel (px) for a press on a 360° sphere to still count as a tap +// rather than a pan, used to toggle the lightbox controls on touch devices. +const SPHERE_TAP_SLOP = 10; + import PLightboxMenu from "component/lightbox/menu.vue"; import PLightboxSidebar from "component/lightbox/sidebar.vue"; import { Marker } from "model/marker"; @@ -170,6 +217,11 @@ const shouldHideCaption = () => { return appStorage.getItem("lightbox.caption") === "false"; }; +// Most recent Escape KeyboardEvent handled by onEscapeKey; comparing identity +// collapses the press's duplicate dispatch (see onEscapeKey) into one unwind. +// Module-scoped rather than instance state — PLightbox is mounted once per session. +let _lastEscapeEvent = null; + export default { name: "PLightbox", components: [PLightboxMenu, PLightboxSidebar], @@ -659,6 +711,29 @@ export default { loading: false, }; + // Route equirectangular 360° media to the lazy-loaded sphere viewer before the video branch, + // since panoramic videos are also Playable and would otherwise fall through. is360Equirectangular + // routes on the equirectangular projection when present, and falls back to the 2:1 frame for + // panorama-flagged videos that carry no readable projection tag — cubemap and ultrawide clips + // stay flat. See common/sphere.js for the discriminator. + const isEquirect = is360Equirectangular(model); + if (isEquirect && model?.Hash) { + const isVideo = model?.Type === media.Video || model?.Type === media.Animated; + // Request the largest available size so 360° photos stay crisp when zoomed; $util.thumb + // clamps to the biggest size the server advertises (fit_15360 when the on-demand limit allows). + const src = isVideo ? this.$util.videoUrl(model.Hash, model?.Codec, model?.Mime) : this.$util.thumb(model.Thumbs, 15360, 8640).src; + return { + type: "html", + html: `
`, + model: model, + isSphere: true, + isVideo: isVideo, + src: src, + msrc: img.src, + loading: true, + }; + } + // Check if content is playable and return the data needed to render it in "contentLoad". if (model?.Playable && model?.Hash) { /* @@ -694,14 +769,164 @@ export default { return img; }, isContentZoomable(isContentZoomable, content) { + if (content.data?.isSphere) { + return false; + } if (content.data?.model?.Type === media.Live) { isContentZoomable = true; } return isContentZoomable; }, + // slideZoomable reports whether a slide supports the flat zoom button and + // pinch/click-to-zoom. 360° sphere slides own their zoom/pan, and videos and + // animations are never flatly zoomable; the result drives the `.is-zoomable` + // class that shows or hides the PhotoSwipe zoom button. + slideZoomable(data) { + if (data?.isSphere) { + return false; + } + return data?.model?.Type !== media.Video && data?.model?.Type !== media.Animated; + }, + // trapSphereGestures stops PhotoSwipe's swipe/zoom gesture detection from running + // while the user interacts with a 360° sphere. It swallows pointer + wheel events + // on the sphere container during the bubble phase, before they reach PhotoSwipe's + // listeners on the scroll wrapper above it. + // + // Touch events are deliberately NOT trapped: PhotoSwipe binds pointer events on our + // browser baseline (it only falls back to touch when PointerEvent is unavailable), + // while Photo Sphere Viewer drives panning from touchmove/touchend listeners bound on + // `window`. A bubble-phase stopPropagation here would keep those events from reaching + // PSV and break 360° panning on touch devices. UI buttons (close, prev/next, sidebar) + // live on the PhotoSwipe wrapper outside this container and stay clickable. + // + // Trapping the pointer events also swallows PhotoSwipe's tap detection, which is what + // reveals the prev/next arrows and top bar on touch devices. To restore that, a short + // press without a pan toggles the controls here. Only touch/pen taps do so — mouse + // users still get the controls via mousemove, so desktop behavior is unchanged. + // + // Pausing a running slideshow on interaction is NOT done here — the dialog's capture + // handlers (captureDialogPointerDown / captureDialogWheel) own that for every slide type. + // The tap-toggle only reads the `_slideshowPausedByPointer` flag they set, so a tap that + // paused the slideshow lands on the paused view with the revealed controls left intact. + trapSphereGestures(el) { + const stop = (e) => e.stopPropagation(); + let tapX = 0; + let tapY = 0; + let tapping = false; + el.addEventListener( + "pointerdown", + (e) => { + e.stopPropagation(); + tapping = e.pointerType !== "mouse"; + tapX = e.clientX; + tapY = e.clientY; + }, + { capture: false } + ); + el.addEventListener( + "pointerup", + (e) => { + e.stopPropagation(); + // Skip the toggle when the dialog's capture handler paused the slideshow on this + // pointer: pauseSlideshow() already revealed the controls, so toggling would hide them. + if (tapping && !this._slideshowPausedByPointer && Math.abs(e.clientX - tapX) < SPHERE_TAP_SLOP && Math.abs(e.clientY - tapY) < SPHERE_TAP_SLOP) { + this.toggleControls(); + } + tapping = false; + }, + { capture: false } + ); + el.addEventListener( + "pointercancel", + (e) => { + e.stopPropagation(); + tapping = false; + }, + { capture: false } + ); + ["pointermove", "wheel"].forEach((type) => { + el.addEventListener(type, stop, { capture: false }); + }); + }, + // setSphereClass toggles the `pswp--sphere` marker on the PhotoSwipe root element so + // CSS can keep the prev/next arrows reachable on touch devices for 360° slides, where + // swipe is captured for panning instead of navigation. PhotoSwipe hides the arrows on + // touch by default, leaving such slides with no way to switch photos otherwise. + setSphereClass(enabled) { + const el = this.pswp()?.element; + if (el?.classList) { + el.classList.toggle("pswp--sphere", enabled); + } + }, onContentLoad(ev) { const { content } = ev; + if (content.data?.isSphere) { + ev.preventDefault(); + + try { + const sphereEl = document.createElement("div"); + sphereEl.setAttribute("class", "pswp__media pswp__media--sphere"); + sphereEl.style.width = "100%"; + sphereEl.style.height = "100%"; + sphereEl.style.touchAction = "none"; + this.trapSphereGestures(sphereEl); + + content.element = sphereEl; + content.state = "loading"; + content.data.loading = false; + content.onLoaded(); + + createSphereViewer(sphereEl, content.data.src, { isVideo: content.data.isVideo, muted: this.muted }) + .then((viewer) => { + content.data.sphereViewer = viewer; + // For 360° videos, expose the underlying