54 Commits

Author SHA1 Message Date
7de3c74f3c fix(iframe): stop an absent iframe parameter from framing the page in itself
An empty value resolved against window.location.href, so a page without an iframe parameter passed both the scheme check and the origin allowlist carrying its own URL. Every load entered fullscreen and framed the page inside itself, and the navigation observer wrote that URL back into the parameter, nesting it deeper on every poll until the URL ran to kilometres. safeUrl now rejects a missing value, the caller tests the parameter before validating it, and the history entry keeps the URL it was given rather than the resolved one.

The regression spec covers the four properties a page without the parameter must have, and fails on each of them when the defect is put back.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 10:15:52 +02:00
7353e8d96a fix(iframe): hand the sinks the validated URL, not the parameter
The scheme and origin checks lived in a boolean guard in another function, so the raw query parameter still reached the iframe src, the history entry and window.open. The validator now returns the normalised href or null, and every sink consumes only that. Which URLs are accepted does not change: openIframe still checks the scheme alone, because the modal opens configured targets that are not among the page's iframe links.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 02:10:05 +02:00
4cc8052a88 test: parse the page instead of matching tags with a regex
The inline-script check matched <script\b[^>]*> and then filtered the matched text, so a > inside an attribute value split one tag into a fragment that had already lost the attribute the filter looks for. An html.parser subclass decides on the parsed attributes instead. The i18n test imported unittest twice, once plain and once as a from-import.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 02:09:23 +02:00
87c4405aa4 ci: run the Node jobs on the version Cypress supports
Cypress 16 declares node ^22 || ^24 || >=26, and both jobs installed it on Node 20, which npm reported as EBADENGINE on every run. Node 25 would match the Dockerfile but falls in the gap between ^24 and >=26.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 02:08:24 +02:00
ff6e7d3689 fix(vendor): find the marked 18 browser build
marked 18 ships lib/marked.umd.js and no minified bundle at all, so the postinstall hook threw 'no browser UMD build found' and took npm install down with it. Both the JavaScript lint job and the end-to-end job died there. Teach the candidate list that layout; the older, minified layouts keep their precedence.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 02:07:20 +02:00
4eb57011ba Release version 2.2.1 2026-09-23 01:00:06 +02:00
70d5871e94 ci: cancel the runs of a branch that is closed
The concurrency group only deduplicates live work on a branch; a run that was queued or still building kept its runner after the branch was deleted or its pull request closed. A delete and a pull_request closed trigger now cancel everything of that branch that has not completed, minus the cancelling run itself, which shares the head branch on a pull request event.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 00:59:08 +02:00
10ea289563 ci: run one CI run per branch at a time
Every push started its own run, so two pushes to the same branch raced through the same jobs and burned runner minutes twice. One concurrency group per ref now covers all six jobs, including the reusable workflows. Pull request runs cancel their predecessor; branch pushes queue instead, so a release push is never cancelled between the per-architecture push and the manifest merge.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 00:54:03 +02:00
62a2aa5827 Merge pull request #14 from kevinveenbirkenbach/dependabot/github_actions/docker/setup-buildx-action-4.4.1
build(deps): bump docker/setup-buildx-action from 3.12.0 to 4.4.1
2026-09-23 00:50:07 +02:00
b0c8316b0d Merge pull request #7 from kevinveenbirkenbach/dependabot/npm_and_yarn/app/jquery-4.0.0
build(deps): bump jquery from 3.6.0 to 4.0.0 in /app
2026-09-23 00:49:51 +02:00
dependabot[bot]
d5104f5680 build(deps): bump jquery from 3.6.0 to 4.0.0 in /app
Bumps [jquery](https://github.com/jquery/jquery) from 3.6.0 to 4.0.0.
- [Release notes](https://github.com/jquery/jquery/releases)
- [Changelog](https://github.com/jquery/jquery/blob/main/changelog.md)
- [Commits](https://github.com/jquery/jquery/compare/3.6.0...4.0.0)

---
updated-dependencies:
- dependency-name: jquery
  dependency-version: 4.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-22 22:49:42 +00:00
fc646d8826 Merge pull request #6 from kevinveenbirkenbach/dependabot/docker/python-3.14-slim
build(deps): bump python from 3.12-slim to 3.14-slim
2026-09-23 00:48:49 +02:00
1bff38ed64 Merge pull request #5 from kevinveenbirkenbach/dependabot/github_actions/cypress-io/github-action-7.4.4
build(deps): bump cypress-io/github-action from 6.10.9 to 7.4.4
2026-09-23 00:48:37 +02:00
dd0454274b Merge pull request #4 from kevinveenbirkenbach/dependabot/docker/node-25-slim
build(deps): bump node from 22-slim to 25-slim
2026-09-23 00:47:49 +02:00
fd4d1e77c8 Merge pull request #3 from kevinveenbirkenbach/dependabot/github_actions/hadolint/hadolint-action-3.5.0
build(deps): bump hadolint/hadolint-action from 3.3.0 to 3.5.0
2026-09-23 00:47:33 +02:00
d1043c4cb0 Merge pull request #2 from kevinveenbirkenbach/dependabot/github_actions/actions/setup-python-7
build(deps): bump actions/setup-python from 6 to 7
2026-09-23 00:47:08 +02:00
dependabot[bot]
62a6a8cb66 build(deps): bump docker/setup-buildx-action from 3.12.0 to 4.4.1
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3.12.0 to 4.4.1.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](8d2750c68a...f87e5991a6)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: 4.4.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-22 22:46:28 +00:00
4d1092fe5e Merge pull request #8 from kevinveenbirkenbach/dependabot/github_actions/docker/build-push-action-7.4.0
build(deps): bump docker/build-push-action from 6.19.2 to 7.4.0
2026-09-23 00:45:06 +02:00
2ed4164dc3 Merge pull request #13 from kevinveenbirkenbach/dependabot/npm_and_yarn/app/marked-18.0.13
build(deps): bump marked from 4.3.0 to 18.0.13 in /app
2026-09-23 00:44:31 +02:00
85e1f437e0 Merge pull request #9 from kevinveenbirkenbach/dependabot/npm_and_yarn/app/bootstrap-5.3.8
build(deps): bump bootstrap from 5.2.2 to 5.3.8 in /app
2026-09-23 00:43:47 +02:00
dependabot[bot]
0733af88ba build(deps): bump marked from 4.3.0 to 18.0.13 in /app
Bumps [marked](https://github.com/markedjs/marked) from 4.3.0 to 18.0.13.
- [Release notes](https://github.com/markedjs/marked/releases)
- [Commits](https://github.com/markedjs/marked/compare/v4.3.0...v18.0.13)

---
updated-dependencies:
- dependency-name: marked
  dependency-version: 18.0.13
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-22 22:43:38 +00:00
31bed38478 Merge branch 'main' into dependabot/npm_and_yarn/app/bootstrap-5.3.8 2026-09-23 00:43:29 +02:00
3f75ebd327 Merge pull request #10 from kevinveenbirkenbach/dependabot/npm_and_yarn/app/cypress-16.1.0
build(deps-dev): bump cypress from 14.5.4 to 16.1.0 in /app
2026-09-23 00:42:20 +02:00
169891fcf0 Merge pull request #12 from kevinveenbirkenbach/dependabot/npm_and_yarn/app/fortawesome/fontawesome-free-7.3.1
build(deps): bump @fortawesome/fontawesome-free from 6.7.2 to 7.3.1 in /app
2026-09-23 00:42:05 +02:00
dependabot[bot]
578d84de0c build(deps): bump @fortawesome/fontawesome-free in /app
Bumps [@fortawesome/fontawesome-free](https://github.com/FortAwesome/Font-Awesome) from 6.7.2 to 7.3.1.
- [Release notes](https://github.com/FortAwesome/Font-Awesome/releases)
- [Changelog](https://github.com/FortAwesome/Font-Awesome/blob/7.x/CHANGELOG.md)
- [Commits](https://github.com/FortAwesome/Font-Awesome/compare/6.7.2...7.3.1)

---
updated-dependencies:
- dependency-name: "@fortawesome/fontawesome-free"
  dependency-version: 7.3.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-22 22:41:39 +00:00
20b36e518d Merge pull request #11 from kevinveenbirkenbach/dependabot/npm_and_yarn/app/bootstrap-icons-1.13.1
build(deps): bump bootstrap-icons from 1.9.1 to 1.13.1 in /app
2026-09-23 00:41:34 +02:00
d3a37f2268 Merge pull request #1 from kevinveenbirkenbach/dependabot/github_actions/actions/checkout-7
build(deps): bump actions/checkout from 6 to 7
2026-09-23 00:40:56 +02:00
dependabot[bot]
fe6c2a0f11 build(deps): bump bootstrap-icons from 1.9.1 to 1.13.1 in /app
Bumps [bootstrap-icons](https://github.com/twbs/icons) from 1.9.1 to 1.13.1.
- [Release notes](https://github.com/twbs/icons/releases)
- [Commits](https://github.com/twbs/icons/compare/v1.9.1...v1.13.1)

---
updated-dependencies:
- dependency-name: bootstrap-icons
  dependency-version: 1.13.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-22 22:39:27 +00:00
dependabot[bot]
21f24a3c0d build(deps-dev): bump cypress from 14.5.4 to 16.1.0 in /app
Bumps [cypress](https://github.com/cypress-io/cypress) from 14.5.4 to 16.1.0.
- [Release notes](https://github.com/cypress-io/cypress/releases)
- [Changelog](https://github.com/cypress-io/cypress/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/cypress-io/cypress/compare/v14.5.4...v16.1.0)

---
updated-dependencies:
- dependency-name: cypress
  dependency-version: 16.1.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-22 22:39:20 +00:00
dependabot[bot]
20566ca0c4 build(deps): bump bootstrap from 5.2.2 to 5.3.8 in /app
Bumps [bootstrap](https://github.com/twbs/bootstrap) from 5.2.2 to 5.3.8.
- [Release notes](https://github.com/twbs/bootstrap/releases)
- [Commits](https://github.com/twbs/bootstrap/compare/v5.2.2...v5.3.8)

---
updated-dependencies:
- dependency-name: bootstrap
  dependency-version: 5.3.8
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-22 22:39:19 +00:00
dependabot[bot]
f998ceb298 build(deps): bump docker/build-push-action from 6.19.2 to 7.4.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.19.2 to 7.4.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](10e90e3645...c3c9e263c2)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 7.4.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-22 22:39:13 +00:00
dependabot[bot]
abc17e8b1e build(deps): bump python from 3.12-slim to 3.14-slim
Bumps python from 3.12-slim to 3.14-slim.

---
updated-dependencies:
- dependency-name: python
  dependency-version: 3.14-slim
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-22 22:39:09 +00:00
dependabot[bot]
c188a6089d build(deps): bump cypress-io/github-action from 6.10.9 to 7.4.4
Bumps [cypress-io/github-action](https://github.com/cypress-io/github-action) from 6.10.9 to 7.4.4.
- [Release notes](https://github.com/cypress-io/github-action/releases)
- [Changelog](https://github.com/cypress-io/github-action/blob/master/CHANGELOG.md)
- [Commits](f790eee7a5...01e3b659a4)

---
updated-dependencies:
- dependency-name: cypress-io/github-action
  dependency-version: 7.4.4
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-22 22:39:06 +00:00
dependabot[bot]
b76bbba4a3 build(deps): bump node from 22-slim to 25-slim
Bumps node from 22-slim to 25-slim.

---
updated-dependencies:
- dependency-name: node
  dependency-version: 25-slim
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-22 22:39:03 +00:00
dependabot[bot]
362ca6f499 build(deps): bump hadolint/hadolint-action from 3.3.0 to 3.5.0
Bumps [hadolint/hadolint-action](https://github.com/hadolint/hadolint-action) from 3.3.0 to 3.5.0.
- [Release notes](https://github.com/hadolint/hadolint-action/releases)
- [Commits](2332a7b74a...06be81baf8)

---
updated-dependencies:
- dependency-name: hadolint/hadolint-action
  dependency-version: 3.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-22 22:39:00 +00:00
dependabot[bot]
13e0331460 build(deps): bump actions/setup-python from 6 to 7
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6 to 7.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-22 22:38:57 +00:00
dependabot[bot]
5d39720d54 build(deps): bump actions/checkout from 6 to 7
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-22 22:38:51 +00:00
49a0d2fe6d ci: let Dependabot watch the dependencies
The SHA-pinned actions, the two base images, the compose file, the Python project and the npm assets had no update stream, so a pinned reference only moved when someone noticed it by hand. Adds a daily Dependabot config for all five.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 00:38:10 +02:00
dae34991e9 Release version 2.2.0 2026-09-23 00:30:21 +02:00
b7874eab1d ci: publish the image for amd64 and arm64 natively
The publish job built a single-arch image on ubuntu-latest, so every release manifest carried linux/amd64 only. Split it into a version job that exports the semver tag and image name, a matrix publish job that builds each architecture on its own native runner (ubuntu-latest, ubuntu-24.04-arm) and pushes an arch-suffixed tag, and a manifest job that joins both under the release tag. Native runners avoid the QEMU emulation layer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 00:28:35 +02:00
be04b24eb0 Release version 2.1.3 2026-09-11 23:30:48 +02:00
3c899d971b fix(fullscreen): stop the recalc loop once the header stops animating
recalcWhileCollapsing ran a requestAnimationFrame loop and cancelled it on
the header's max-height transitionend. When no max-height transition ran,
for example because the header was already in its target state, that event
never fired and the loop recalculated the scroll container on every frame
for the rest of the page's life; each further call started another such
loop. The loop now continues only while header.getAnimations() reports a
running animation.

The resize handler entered or exited fullscreen on every resize event. It
now returns early when the UI fullscreen state already matches the body
class, so a resize that changes nothing starts no recalc loop.

A Cypress spec spies on adjustScrollContainerHeight after exitFullscreen()
and requires the call count to stop growing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-11 23:25:51 +02:00
a7a6d205e1 fix(iframe): stop observing when the iframe's first location is cross-origin
observeIframeNavigation read iframe.contentWindow.location.href once,
outside any guard. For a cross-origin iframe that read throws a
SecurityError, which escaped as an uncaught exception and never reached
the polling loop, whose own read of the same property is already guarded.
The first read is now guarded as well, and the observer returns because it
cannot follow a cross-origin frame anyway.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-11 23:25:51 +02:00
2c12c1c327 fix(card): make the icon fallback onerror handler compile
The handler assigned through an optional chain,
this.nextElementSibling?.style.display='inline-block'. An optional chain
is not a valid assignment target, so the whole attribute failed to compile
("SyntaxError: Invalid left-hand side in assignment") whenever an icon
image failed to load: the broken image stayed visible and the fallback
<i> icon never appeared. An explicit null check does the same and
compiles.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-11 23:25:51 +02:00
2400cc2ea1 fix(csp): ship the interface strings as a JSON data block, not an inline script
base.html.j2 set window.I18N from an executable inline <script>. A host
CSP can only allow an inline script by hash or by 'unsafe-inline', and this
script's content changes with every language, so no hash can cover it.
Infinito.Nexus serves the dashboard with a hash-based script-src-elem
whenever its logout feature is off, and there the script was blocked:
every page logged "Executing inline script violates the following Content
Security Policy directive 'script-src-elem ...'" and window.I18N stayed
undefined.

The strings now ship as <script id="i18n" type="application/json">, which
the browser does not execute and CSP does not govern; modal.js parses the
block before its first use. tojson escapes <, > and &, so a string that
contains "</script>" cannot end the block early.

Integration tests require that a page ships no executable inline script
and that a catalogue string containing "</script>" survives the round trip
through the block.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-11 23:25:51 +02:00
f76794df78 Release version 2.1.2 2026-09-10 18:06:21 +02:00
c6667f3b05 feat(i18n): ship interface translations for every offered language
The language switcher offers all 184 ISO 639-1 languages, but only 29
had a UI catalogue, so the other 154 rendered Close, Imprint, Language
and the rest of the interface strings in English. Nothing noticed:
the existing unit test only checks the catalogues that are present.

A new integration test requires every language except the source to
ship a catalogue with a non-empty entry for each of the 11 interface
strings, and lists missing catalogues apart from incomplete ones. The
154 missing catalogues are added, written through
i18n_sync.write_catalog so they share the existing format; make i18n-ui
never overwrites them, so a later correction survives.

The translations were written without a native reviewer. Most widely
used languages are solid; these are best-effort and likely wrong:
ae, cr, ii, kr, na, nv, oj, sg, aa, hz, ho, mh, za, vo. Uncertain:
ab, ak, av, ay, bi, bm, bo, ce, ch, cu, dv, dz, ee, ff, fj, gn, gv, ie,
ik, iu, kg, ki, kj, kl, ks, kv, kw, lg, li, ln, lu, ng, nr, os, pi, qu,
rn, sa, se, ss, to, tw, ty, ve, wa, wo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 18:05:33 +02:00
b8891fe6fd fix(app): print the startup line only when app.py runs as a script
The "Starting app on host:port" line sat at module level, so every
import printed it, including the test suites and any WSGI server that
loads the module; CodeQL reported it as a print during import. It now
lives in the __main__ block, which the Docker CMD and the e2e runner
reach through python app.py; the e2e Flask log still shows the line.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 17:35:07 +02:00
2c7f0a23d1 ci(actions): pin the third-party actions to commit SHAs
CodeQL flagged docker/setup-buildx-action, docker/login-action,
docker/build-push-action and cypress-io/github-action as unpinned: a
moving v3 or v6 tag lets whoever controls it change what runs with the
workflow's GHCR write token.

Each action is now pinned to the commit its tag points to today, with
the exact release as a trailing comment (v3.12.0, v3.7.0, v6.19.2,
v6.10.9), resolved through the GitHub API, so the code that runs does
not change. GitHub's own actions/* were not flagged and keep their tags.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 17:35:07 +02:00
330881260c fix(i18n): build catalogue paths from the language table, not the request
catalog() joined the requested language code straight into the UI and
content catalogue paths, and read_catalog logged those paths. Both the
negotiated Accept-Language code and the /<lang>/ route only ever pass
supported codes, but that guarantee lived in the callers, so CodeQL
reported path injection and log injection on the request value.

catalog() now resolves the code through a table of the supported
languages and builds the file names from the table's value, so an
unsupported code returns an empty catalogue and never becomes a path.
A unit test holds "../content/de" to that without reading any file,
and the translate_tree fixture moves from the made-up code "xx" to "de"
because unsupported codes now translate to English by design.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 17:35:07 +02:00
857c470c9e fix(iframe): open only configured origins from the iframe query parameter
?iframe=<url> loaded any http(s) page into the dashboard frame, and
"Open in new tab" handed the same query value to window.open unchecked,
so a crafted link could show an arbitrary site inside the trusted page.
CodeQL flagged both as client-side URL redirection and XSS. The scheme
check sat before the fade callback that sets the iframe src, so it did
not guard that sink, and isSafeUrl itself assigned the untrusted value
to an anchor's href to parse it.

isAllowedIframeUrl now requires a safe scheme and an origin that is the
page's own or one of the configured .iframe-link targets; both query
string entry points check it before openIframe or window.open run.
Clicks on configured links and popup entries keep calling openIframe
directly, which still rejects unsafe schemes. isSafeUrl parses with
new URL instead of a detached anchor.

The Cypress case that expected https://example.com/ to open from the
query string encoded the redirection, so it now asserts that a
configured target opens and that a foreign origin neither loads in the
frame nor reaches window.open. make test passes with 109 Cypress tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 17:35:07 +02:00
793e2de899 build(docker): ship only the runtime assets, without node or dev packages
The image ran npm install without --omit=dev, so every published tag
carried Cypress with its downloaded binary, ESLint and the whole dev
tree next to nodejs and npm. The npm install layer alone was 229 MB of
the 349 MB compressed 2.0.0 image, and all seven npm audit findings
(extract-zip, form-data, tmp, qs, uuid via @cypress/request) came from
it, although the app only serves five vendored asset directories.

A node:22-slim stage now runs npm install --omit=dev, whose postinstall
writes static/vendor, and the final runtime stage copies just that
directory onto the Python base. A dev stage keeps nodejs and npm for
docker-compose, which bind-mounts app/ and runs npm install on start;
compose now builds that target. .dockerignore keeps a local
app/node_modules and app/static/vendor out of COPY app/.

Measured on make build: the runtime image is 142 MB uncompressed, has
no node, npm, node_modules or Cypress cache, and serves /, /de/ and
every vendored asset with 200. The dev stage has node 20.19.2 and npm
9.2.0. make test passes, hadolint included, with 107 Cypress tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 17:17:05 +02:00
f830153cf4 build(make): run every local suite from make test in a project virtualenv
make test installed the project into whatever PYTHON pointed at, which is
the system python3 by default. On Manjaro, Debian and Ubuntu that Python
is externally managed, so pip refuses (PEP 668) and not a single suite
runs, although AGENTS.md requires make test before every commit. It also
stopped at the first failing suite, so one broken linter hid the result
of every test behind it.

make test now creates .venv on first use and runs ci with --keep-going
and that interpreter, so every suite runs and make lists each failed
target. The path is fixed to the checkout: an exported VENV, which other
tooling sets, would otherwise redirect it. It is absolute because
run-e2e.sh changes into app/ before starting Flask. All other targets
keep PYTHON ?= python3.

Verified with a full make test: actionlint, ruff, yamllint, eslint,
hadolint, shellcheck, the lint, security, unit and integration suites,
bandit, pip-audit and 107 Cypress tests all pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 17:17:05 +02:00
308741346e fix(ci): install the project before running the lint tests
tests/lint/test_tooling_configuration.py imports yaml, but the lint test
job only set up Python and ran unittest, so every push since the test
arrived failed with "ModuleNotFoundError: No module named 'yaml'". The
job gates the end-to-end tests and the image publish, which is why no
image exists for 2.1.0 or 2.1.1.

The job now installs the project exactly like the unit, integration and
security jobs, and make test-lint depends on install like its siblings.
Reproduced in a clean virtualenv: the lint suite fails on the missing
module without the install and passes all 18 tests with it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 17:17:04 +02:00
183 changed files with 2161 additions and 95 deletions

2
.dockerignore Normal file
View File

@@ -0,0 +1,2 @@
app/node_modules/
app/static/vendor/

47
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,47 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
time: "00:00"
labels:
- "dependencies"
- "ci"
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "daily"
time: "00:00"
labels:
- "dependencies"
- "docker"
- package-ecosystem: "docker-compose"
directory: "/"
schedule:
interval: "daily"
time: "00:00"
labels:
- "dependencies"
- "docker"
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "daily"
time: "00:00"
labels:
- "dependencies"
- "python"
- package-ecosystem: "npm"
directory: "/app"
schedule:
interval: "daily"
time: "00:00"
labels:
- "dependencies"
- "javascript"

30
.github/workflows/cancel.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: Cancel runs
on:
delete:
pull_request:
types:
- closed
permissions:
actions: write
jobs:
cancel:
name: Cancel the runs of a closed branch
runs-on: ubuntu-latest
if: github.event_name == 'pull_request' || github.event.ref_type == 'branch'
steps:
- name: Cancel every queued or running workflow of the branch
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
BRANCH: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.ref || github.event.ref }}
run: |
set -euo pipefail
gh run list --branch "${BRANCH}" --limit 100 \
--json databaseId,status \
--jq '.[] | select(.status != "completed") | .databaseId' \
| sed "/^${GITHUB_RUN_ID}$/d" \
| xargs -r -n1 gh run cancel

View File

@@ -8,6 +8,10 @@ on:
tags-ignore:
- "**"
concurrency:
group: ci-${{ github.repository }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
permissions:
contents: read
@@ -31,8 +35,8 @@ jobs:
contents: read
security-events: write
publish:
name: Publish image
version:
name: Detect release version
runs-on: ubuntu-latest
needs:
- security
@@ -41,11 +45,14 @@ jobs:
if: github.event_name == 'push'
permissions:
contents: read
packages: write
outputs:
found: ${{ steps.semver.outputs.found }}
version: ${{ steps.semver.outputs.version }}
image: ${{ steps.image.outputs.name }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
with:
fetch-depth: 0
@@ -64,27 +71,77 @@ jobs:
fi
- name: Compute image name
if: steps.semver.outputs.found == 'true'
id: image
run: echo "name=ghcr.io/$(echo "${GITHUB_REPOSITORY}" | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT"
publish:
name: Publish image (${{ matrix.arch }})
runs-on: ${{ matrix.runner }}
needs:
- version
if: needs.version.outputs.found == 'true'
permissions:
contents: read
packages: write
strategy:
matrix:
include:
- arch: amd64
runner: ubuntu-latest
- arch: arm64
runner: ubuntu-24.04-arm
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Set up Docker Buildx
if: steps.semver.outputs.found == 'true'
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- name: Login to GHCR
if: steps.semver.outputs.found == 'true'
uses: docker/login-action@v3
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and publish image
if: steps.semver.outputs.found == 'true'
uses: docker/build-push-action@v6
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: .
file: ./Dockerfile
platforms: linux/${{ matrix.arch }}
push: true
tags: ${{ steps.image.outputs.name }}:${{ steps.semver.outputs.version }}
tags: ${{ needs.version.outputs.image }}:${{ needs.version.outputs.version }}-${{ matrix.arch }}
manifest:
name: Join architectures
runs-on: ubuntu-latest
needs:
- version
- publish
permissions:
contents: read
packages: write
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- name: Login to GHCR
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create the multi-arch manifest
env:
IMAGE: ${{ needs.version.outputs.image }}
VERSION: ${{ needs.version.outputs.version }}
run: |
set -euo pipefail
docker buildx imagetools create -t "${IMAGE}:${VERSION}" \
"${IMAGE}:${VERSION}-amd64" \
"${IMAGE}:${VERSION}-arm64"
docker buildx imagetools inspect "${IMAGE}:${VERSION}"

View File

@@ -14,7 +14,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Run actionlint
run: docker run --rm -v "$PWD:/repo" -w /repo rhysd/actionlint:latest
@@ -25,10 +25,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@v7
with:
python-version: "3.12"
@@ -46,12 +46,12 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
node-version: "24"
cache: npm
cache-dependency-path: app/package.json
@@ -69,7 +69,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Run shellcheck
run: docker run --rm -v "$PWD:/mnt" -w /mnt koalaman/shellcheck:stable scripts/*.sh
@@ -80,10 +80,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@v7
with:
python-version: "3.12"
@@ -107,12 +107,12 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Run hadolint
id: hadolint
continue-on-error: true
uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5
uses: hadolint/hadolint-action@06be81baf89a55ffd0e24b8f04a4185738dd3387
with:
dockerfile: ./Dockerfile
format: sarif

View File

@@ -27,7 +27,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Initialize CodeQL
uses: github/codeql-action/init@v4

View File

@@ -14,13 +14,18 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@v7
with:
python-version: "3.12"
- name: Install lint test dependencies
run: |
python -m pip install --upgrade pip
pip install --ignore-installed .
- name: Run lint test suite
run: python -m unittest discover -s tests/lint -t .
@@ -30,10 +35,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@v7
with:
python-version: "3.12"
@@ -51,10 +56,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@v7
with:
python-version: "3.12"
@@ -72,10 +77,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@v7
with:
python-version: "3.12"
@@ -99,10 +104,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@v7
with:
python-version: "3.12"
@@ -130,10 +135,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@v7
with:
python-version: "3.12"
@@ -148,7 +153,7 @@ jobs:
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
node-version: "24"
cache: npm
cache-dependency-path: app/package.json
@@ -185,7 +190,7 @@ jobs:
xvfb
- name: Run Cypress tests
uses: cypress-io/github-action@v6
uses: cypress-io/github-action@01e3b659a495b41649cdd0aa82e1d1624e26520b # v7.4.4
with:
working-directory: app
install: false

1
.gitignore vendored
View File

@@ -5,6 +5,7 @@ app/static/cache/*
.env
app/cypress/screenshots/*
.ruff_cache/
.venv/
app/node_modules/
app/static/vendor/
hadolint-results.sarif

View File

@@ -1,5 +1,37 @@
# Changelog
## [2.2.1] - 2026-09-23
* Images: releases ship arm64 next to amd64, for ARM servers and Apple Silicon
* CI: each architecture builds on its own native runner, no QEMU emulation
* CI: one run per branch, so two pushes stop racing through the same jobs
* CI: closing a pull request or deleting a branch cancels its pending runs
* Dependencies: Dependabot watches actions, images, compose, pip and npm daily
* Runtime: Python 3.14 and Node 25 base images
* Frontend: Bootstrap 5.3.8, jQuery 4, Font Awesome 7, marked 18, Cypress 16
## [2.2.0] - 2026-09-23
* Images: releases ship arm64 next to amd64, for ARM servers and Apple Silicon
* CI: each architecture builds on its own native runner, no QEMU emulation
## [2.1.3] - 2026-09-11
* CSP: UI strings ship as a JSON data block, not a CSP-blocked inline script
* Cards: broken icon images fall back to the icon font (*onerror* fixed)
* Iframe: a cross-origin iframe no longer throws a *SecurityError* on load
* Fullscreen: scroll recalculation stops when the header animation ends
* Fullscreen: a resize that keeps the fullscreen state triggers no recalc
* Test coverage: no executable inline scripts; recalc must stop (Cypress)
## [2.1.2] - 2026-09-10
* CI: lint tests install the project first, so the image publishes again
* Tooling: make test runs every local suite in .venv and keeps going
* Image: multi-stage build ships only runtime assets, no node or dev packages
* Security: CodeQL findings fixed; iframe links only open configured origins
* i18n: interface strings translated for all 184 languages, test-enforced
## [2.1.1] - 2026-09-10
* Accessibility: header icons are *aria-hidden*, links read by label alone

View File

@@ -1,12 +1,16 @@
FROM python:3.12-slim
FROM node:25-slim AS assets
WORKDIR /app
COPY app/package.json ./
COPY app/scripts ./scripts
RUN npm install --omit=dev --no-audit --no-fund
FROM python:3.14-slim AS base
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
FLASK_HOST=0.0.0.0
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends nodejs npm && rm -rf /var/lib/apt/lists/*
WORKDIR /tmp/build
COPY pyproject.toml README.md main.py ./
@@ -15,6 +19,14 @@ RUN python -m pip install --no-cache-dir .
WORKDIR /app
COPY app/ .
RUN npm install --prefix /app
CMD ["python", "app.py"]
FROM base AS dev
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends nodejs npm && rm -rf /var/lib/apt/lists/*
FROM base AS runtime
COPY --from=assets /app/static/vendor ./static/vendor

View File

@@ -7,6 +7,8 @@ endif
PYTHON ?= python3
ACT ?= act
TEST_VENV := $(CURDIR)/.venv
TEST_PYTHON ?= $(TEST_VENV)/bin/python
# Bootstrap the local .env from the checked-in env.example template.
# Idempotent: leaves an existing .env untouched.
@@ -185,7 +187,7 @@ lint-shell:
docker run --rm -v "$$PWD:/mnt" -w /mnt koalaman/shellcheck:stable scripts/*.sh
.PHONY: test-lint
test-lint:
test-lint: install
# Run lint guardrail tests.
$(PYTHON) -m unittest discover -s tests/lint -t .
@@ -252,5 +254,8 @@ ci: lint security test-unit test-integration test-e2e
# Run the local CI suite.
.PHONY: test
test: ci
# Run the full validation suite.
test:
# Run every local suite in a project virtualenv, since PEP 668 refuses pip on
# a system Python, and keep going so each failing suite reports.
@[ -x "$(TEST_PYTHON)" ] || python3 -m venv "$(TEST_VENV)"
$(MAKE) --keep-going ci PYTHON="$(TEST_PYTHON)"

View File

@@ -28,7 +28,6 @@ logging.basicConfig(level=logging.DEBUG)
FLASK_ENV = os.getenv("FLASK_ENV", "production")
FLASK_HOST = os.getenv("FLASK_HOST", "127.0.0.1")
FLASK_PORT = int(os.getenv("FLASK_PORT", os.getenv("PORT", 5000)))
print(f"Starting app on {FLASK_HOST}:{FLASK_PORT}, FLASK_ENV={FLASK_ENV}")
# Initialize the CacheManager
cache_manager = CacheManager()
@@ -190,6 +189,7 @@ def localized_index(lang):
if __name__ == "__main__":
print(f"Starting app on {FLASK_HOST}:{FLASK_PORT}, FLASK_ENV={FLASK_ENV}")
app.run(
debug=(FLASK_ENV == "development"),
host=FLASK_HOST,

View File

@@ -71,6 +71,18 @@ describe('Fullscreen Toggle', () => {
});
});
it('stops recalculating once the header has nothing left to animate', () => {
cy.window().then(win => {
cy.spy(win, 'adjustScrollContainerHeight').as('recalc');
win.exitFullscreen();
});
cy.wait(500);
cy.get('@recalc').then(spy => {
const settled = spy.callCount;
cy.wait(500).then(() => expect(spy.callCount).to.eq(settled));
});
});
it('toggleFullscreen() toggles into and out of fullscreen', () => {
// Toggle into fullscreen
cy.window().invoke('toggleFullscreen');

View File

@@ -0,0 +1,31 @@
describe('A page without an iframe parameter', () => {
beforeEach(() => {
cy.visit('/');
});
it('stays out of fullscreen', () => {
cy.get('body').should('not.have.class', 'fullscreen');
});
it('frames nothing', () => {
cy.get('#main').find('iframe').should('not.exist');
cy.url().should('not.include', 'iframe=');
});
it('never grows an iframe parameter out of its own URL', () => {
cy.wait(2000);
cy.url().then((url) => {
expect((url.match(/iframe/g) || []).length, 'iframe parameters').to.equal(0);
});
});
it('treats an absent URL as unsafe', () => {
cy.window().then((win) => {
expect(win.safeUrl(null), 'null').to.equal(null);
expect(win.safeUrl(''), 'empty string').to.equal(null);
expect(win.safeUrl('javascript:alert(1)'), 'script URL').to.equal(null);
expect(win.safeUrl('/de/'), 'relative path').to.equal(`${win.location.origin}/de/`);
});
});
});

View File

@@ -253,11 +253,33 @@ describe('Untrusted content reaching the iframe', () => {
cy.window().should('not.have.property', '__xss');
});
it('still opens an ordinary URL from the query string', () => {
it('still opens a configured iframe target from the query string', () => {
cy.visit('/');
cy.get('a.iframe-link').first().invoke('prop', 'href').then((href) => {
cy.visit(`/?iframe=${encodeURIComponent(href)}`);
cy.get('#main')
.find('iframe', { timeout: AFTER_THE_FADE })
.should('have.attr', 'src', href);
});
});
it('refuses a foreign origin supplied through the query string', () => {
cy.visit('/?iframe=https://example.com/');
cy.get('#main')
.find('iframe', { timeout: AFTER_THE_FADE })
.should('have.attr', 'src', 'https://example.com/');
cy.wait(AFTER_THE_FADE);
cy.get('#main').find('iframe').should('not.exist');
});
it('does not open a foreign query-string origin in a new tab', () => {
cy.visit('/?iframe=https://example.com/', {
onBeforeLoad(win) {
cy.stub(win, 'open').as('open');
cy.stub(win, 'alert');
},
});
cy.window().then((win) => win.openIframeInNewTab());
cy.get('@open').should('not.have.been.called');
});
});

View File

@@ -21,6 +21,7 @@ const SHARED = {
openDynamicPopup: 'readonly',
closeAllModals: 'readonly',
isSafeUrl: 'readonly',
safeUrl: 'readonly',
openIframe: 'readonly',
enterFullscreen: 'readonly',
exitFullscreen: 'readonly',

11
app/i18n/ui/aa.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Tan doorit
Close: Alif
Copy: Garraab
Identifier copied to clipboard!: Astooti tixi rakaakayih culte!
Imprint: Qaanuunih warsa
Information: Warsa
Language: Af
Open: Fak
Open Link: Tixi fak
Options: Doorit
Warning: Kassiisa

11
app/i18n/ui/ab.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Альтернативақәа
Close: Аркра
Copy: Акопиа ахыхра
Identifier copied to clipboard!: Аидентификатор абуфер ахь иқәыргылоуп!
Imprint: Азакәантә информациа
Information: Аинформациа
Language: Абызшәа
Open: Аартра
Open Link: Азхьарԥш аартра
Options: Апараметрқәа
Warning: Агәаҽанижьра

11
app/i18n/ui/ae.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Aniiā
Close: Pairi.dāraiia
Copy: Paitiš.kərənu
Identifier copied to clipboard!: Nāman paitiš.kərətəm!
Imprint: Dātō.xvarənah
Information: Vaēdiia
Language: Hizuuā
Open: Vīuuāraiia
Open Link: Paθō vīuuāraiia
Options: Vərəθra
Warning: Aiβi.saŋha

11
app/i18n/ui/af.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternatiewe
Close: Maak toe
Copy: Kopieer
Identifier copied to clipboard!: Identifiseerder na knipbord gekopieer!
Imprint: Regskennisgewing
Information: Inligting
Language: Taal
Open: Maak oop
Open Link: Maak skakel oop
Options: Opsies
Warning: Waarskuwing

11
app/i18n/ui/ak.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Nneɛma foforɔ
Close: To mu
Copy: Twa
Identifier copied to clipboard!: Wɔatwa nsɛnkyerɛnneɛ no akɔ clipboard so!
Imprint: Mmara ho nsɛm
Information: Nsɛm
Language: Kasa
Open: Bue
Open Link: Bue link no
Options: Nhyehyɛe
Warning: Kɔkɔbɔ

11
app/i18n/ui/am.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: አማራጮች
Close: ዝጋ
Copy: ቅዳ
Identifier copied to clipboard!: መለያው ወደ ቅንጥብ ሰሌዳ ተቀድቷል!
Imprint: ሕጋዊ መረጃ
Information: መረጃ
Language: ቋንቋ
Open: ክፈት
Open Link: ማገናኛውን ክፈት
Options: ምርጫዎች
Warning: ማስጠንቀቂያ

11
app/i18n/ui/an.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternativas
Close: Zarrar
Copy: Copiar
Identifier copied to clipboard!: Identificador copiau en o portafuellas!
Imprint: Aviso legal
Information: Información
Language: Idioma
Open: Ubrir
Open Link: Ubrir o vinclo
Options: Opcions
Warning: Alvertencia

11
app/i18n/ui/as.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: বিকল্পসমূহ
Close: বন্ধ কৰক
Copy: কপি কৰক
Identifier copied to clipboard!: চিনাক্তকাৰী ক্লিপবোৰ্ডলৈ কপি কৰা হ'ল!
Imprint: আইনী তথ্য
Information: তথ্য
Language: ভাষা
Open: খোলক
Open Link: লিংক খোলক
Options: বিকল্প
Warning: সতৰ্কবাণী

11
app/i18n/ui/av.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Альтернативаби
Close: Къазе
Copy: Копия гьабе
Identifier copied to clipboard!: Идентификатор буфералде копия гьабуна!
Imprint: Закон баян
Information: Хабар
Language: МацӀ
Open: Рагье
Open Link: Ссылка рагье
Options: Параметрал
Warning: ТӀаде кӀвар

11
app/i18n/ui/ay.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Yaqha ajlliwinaka
Close: Jist'antaña
Copy: Qillqaña
Identifier copied to clipboard!: Uñt'ayiri clipboard ukar qillqatawa!
Imprint: Kamachi yatiyawi
Information: Yatiyawi
Language: Aru
Open: Jist'araña
Open Link: Link jist'araña
Options: Ajlliwinaka
Warning: Iwxt'awi

11
app/i18n/ui/az.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternativlər
Close: Bağla
Copy: Kopyala
Identifier copied to clipboard!: İdentifikator mübadilə buferinə kopyalandı!
Imprint: Hüquqi məlumat
Information: Məlumat
Language: Dil
Open:
Open Link: Keçidi aç
Options: Seçimlər
Warning: Xəbərdarlıq

11
app/i18n/ui/ba.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Альтернативалар
Close: Ябырға
Copy: Күсерергә
Identifier copied to clipboard!: Идентификатор алмашыу буферына күсерелде!
Imprint: Хоҡуҡи мәғлүмәт
Information: Мәғлүмәт
Language: Тел
Open: Асырға
Open Link: Һылтанманы асырға
Options: Параметрҙар
Warning: Иҫкәртеү

11
app/i18n/ui/be.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Альтэрнатывы
Close: Закрыць
Copy: Капіяваць
Identifier copied to clipboard!: Ідэнтыфікатар скапіяваны ў буфер абмену!
Imprint: Прававая інфармацыя
Information: Інфармацыя
Language: Мова
Open: Адкрыць
Open Link: Адкрыць спасылку
Options: Параметры
Warning: Папярэджанне

11
app/i18n/ui/bg.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Алтернативи
Close: Затвори
Copy: Копирай
Identifier copied to clipboard!: Идентификаторът е копиран в клипборда!
Imprint: Правна информация
Information: Информация
Language: Език
Open: Отвори
Open Link: Отвори връзката
Options: Опции
Warning: Предупреждение

11
app/i18n/ui/bi.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Narafala jois
Close: Klosem
Copy: Kopi
Identifier copied to clipboard!: Namba blong aedentifikesen i kopi finis!
Imprint: Loa infomesen
Information: Infomesen
Language: Lanwis
Open: Openem
Open Link: Openem link
Options: Ol jois
Warning: Woning

11
app/i18n/ui/bm.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Sugandili wɛrɛw
Close: A datugu
Copy: A kopi
Identifier copied to clipboard!: Tɔgɔ taamasiyɛn kopilen don!
Imprint: Sariya kunnafoni
Information: Kunnafoni
Language: Kan
Open: A dayɛlɛ
Open Link: Jɛɲɔgɔnya dayɛlɛ
Options: Sugandiliw
Warning: Lasɔmini

11
app/i18n/ui/bo.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: གདམ་ག་གཞན།
Close: ཁ་རྒྱག
Copy: འདྲ་བཤུས།
Identifier copied to clipboard!: ངོས་འཛིན་རྟགས་སྦྱར་སྡེར་དུ་འདྲ་བཤུས་བྱས་ཟིན།
Imprint: ཁྲིམས་ཀྱི་གསལ་བསྒྲགས།
Information: ཆ་འཕྲིན།
Language: སྐད་ཡིག
Open: ཁ་ཕྱེ།
Open Link: སྦྲེལ་ཐག་ཁ་ཕྱེ།
Options: གདམ་ག
Warning: ཉེན་བརྡ།

11
app/i18n/ui/br.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Dibaboù all
Close: Serriñ
Copy: Eilañ
Identifier copied to clipboard!: Eilet eo bet an anaouder er golver!
Imprint: Titouroù lezennel
Information: Titouroù
Language: Yezh
Open: Digeriñ
Open Link: Digeriñ al liamm
Options: Dibarzhioù
Warning: Diwall

11
app/i18n/ui/bs.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternative
Close: Zatvori
Copy: Kopiraj
Identifier copied to clipboard!: Identifikator je kopiran u međuspremnik!
Imprint: Pravne informacije
Information: Informacije
Language: Jezik
Open: Otvori
Open Link: Otvori link
Options: Opcije
Warning: Upozorenje

11
app/i18n/ui/ca.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternatives
Close: Tanca
Copy: Copia
Identifier copied to clipboard!: S'ha copiat l'identificador al porta-retalls!
Imprint: Avís legal
Information: Informació
Language: Idioma
Open: Obre
Open Link: Obre l'enllaç
Options: Opcions
Warning: Advertiment

11
app/i18n/ui/ce.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Альтернативаш
Close: ДӀакъовла
Copy: Копи ян
Identifier copied to clipboard!: Идентификатор буфере копи йина!
Imprint: Бакъонан хаам
Information: Хаам
Language: Мотт
Open: ДӀаелла
Open Link: ТӀе хьажорг дӀаелла
Options: Параметраш
Warning: Кхайкхам

11
app/i18n/ui/ch.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Otro na ayek
Close: Huchom
Copy: Kopia
Identifier copied to clipboard!: Ma kopia i identifier gi clipboard!
Imprint: Infotmasion lai
Information: Infotmasion
Language: Lengguahi
Open: Baba
Open Link: Baba i link
Options: Ayek
Warning: Adbietensia

11
app/i18n/ui/co.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternative
Close: Chjode
Copy: Cupià
Identifier copied to clipboard!: L'identificatore hè statu cupiatu in u preme-papers!
Imprint: Menzioni legali
Information: Infurmazione
Language: Lingua
Open: Apre
Open Link: Apre u ligame
Options: Uzzione
Warning: Avertimentu

11
app/i18n/ui/cr.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: kotakak
Close: kipahamok
Copy: ayisinahikêwin
Identifier copied to clipboard!: kiskinowâcihcikan kî-ayisinahikâtêw!
Imprint: wiyasiwêwin kiskêyihtamowin
Information: kiskêyihtamowin
Language: pîkiskwêwin
Open: yôhtênamok
Open Link: yôhtêna mâmawikan
Options: nawasônamowina
Warning: kitahamâkêwin

11
app/i18n/ui/cu.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Инаѧ
Close: Затвори
Copy: Списати
Identifier copied to clipboard!: Именованїе списано бысть!
Imprint: Законное вѣдѣнїе
Information: Вѣдѣнїе
Language: Ѧзыкъ
Open: Отверзи
Open Link: Отверзи съвѧзь
Options: Изволенїѧ
Warning: Предостереженїе

11
app/i18n/ui/cv.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Альтернативӑсем
Close: Хуп
Copy: Копиле
Identifier copied to clipboard!: Идентификатор буфера копиленӗ!
Imprint: Саккун информацийӗ
Information: Информаци
Language: Чӗлхе
Open: Уҫ
Open Link: Каҫӑна уҫ
Options: Параметрсем
Warning: Асӑрхаттару

11
app/i18n/ui/cy.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Dewisiadau eraill
Close: Cau
Copy: Copïo
Identifier copied to clipboard!: Wedi copïo'r dynodwr i'r clipfwrdd!
Imprint: Gwybodaeth gyfreithiol
Information: Gwybodaeth
Language: Iaith
Open: Agor
Open Link: Agor y ddolen
Options: Opsiynau
Warning: Rhybudd

11
app/i18n/ui/dv.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: ބަދަލު އިޚްތިޔާރުތައް
Close: ބަންދުކުރޭ
Copy: ކޮޕީކުރޭ
Identifier copied to clipboard!: އައިޑެންޓިފަޔަރ ކްލިޕްބޯޑަށް ކޮޕީކުރެވިއްޖެ!
Imprint: ޤާނޫނީ މަޢުލޫމާތު
Information: މަޢުލޫމާތު
Language: ބަސް
Open: ހުޅުވާ
Open Link: ލިންކު ހުޅުވާ
Options: އިޚްތިޔާރުތައް
Warning: އިންޒާރު

11
app/i18n/ui/dz.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: གདམ་ཁ་གཞན།
Close: ཁ་བསྡམས།
Copy: འདྲ་བཤུས།
Identifier copied to clipboard!: ངོས་འཛིན་འདི་འདྲ་བཤུས་འབད་ཡི།
Imprint: ཁྲིམས་དོན་བརྡ་དོན།
Information: བརྡ་དོན།
Language: ཁ་སྐད།
Open: ཁ་ཕྱེ།
Open Link: འབྲེལ་མཐུད་ཁ་ཕྱེ།
Options: གདམ་ཁ།
Warning: ཉེན་བརྡ།

11
app/i18n/ui/ee.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Tiatia bubuwo
Close: Tu
Copy: Kɔpi
Identifier copied to clipboard!: Wokɔpi dzesidede ɖe clipboard dzi!
Imprint: Se ŋuti nyatakakawo
Information: Nyatakaka
Language: Gbe
Open: Ʋu
Open Link: Ʋu kadodoa
Options: Tiatiawo
Warning: Nuxlɔ̃ame

11
app/i18n/ui/eo.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternativoj
Close: Fermi
Copy: Kopii
Identifier copied to clipboard!: Identigilo kopiita al la tondujo!
Imprint: Jura informo
Information: Informo
Language: Lingvo
Open: Malfermi
Open Link: Malfermi ligilon
Options: Opcioj
Warning: Averto

11
app/i18n/ui/et.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternatiivid
Close: Sulge
Copy: Kopeeri
Identifier copied to clipboard!: Identifikaator kopeeriti lõikelauale!
Imprint: Õiguslik teave
Information: Teave
Language: Keel
Open: Ava
Open Link: Ava link
Options: Valikud
Warning: Hoiatus

11
app/i18n/ui/eu.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternatibak
Close: Itxi
Copy: Kopiatu
Identifier copied to clipboard!: Identifikatzailea arbelean kopiatu da!
Imprint: Lege-oharra
Information: Informazioa
Language: Hizkuntza
Open: Ireki
Open Link: Ireki esteka
Options: Aukerak
Warning: Abisua

11
app/i18n/ui/ff.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Suɓaaji goɗɗi
Close: Uddu
Copy: Natto
Identifier copied to clipboard!: Innde heɓtirde natta!
Imprint: Humpito laawol
Information: Humpito
Language: Ɗemngal
Open: Uddit
Open Link: Uddit jokkorde
Options: Suɓaaji
Warning: Reentino

11
app/i18n/ui/fj.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Na ka tale e so
Close: Sogota
Copy: Kopitaka
Identifier copied to clipboard!: Sa kopitaki na ivakatakilakila!
Imprint: iTukutuku vakalawa
Information: iTukutuku
Language: Vosa
Open: Dolava
Open Link: Dolava na isema
Options: Digidigi
Warning: iVakasala

11
app/i18n/ui/fo.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternativ
Close: Lat aftur
Copy: Avrita
Identifier copied to clipboard!: Eyðmerki avritað í setiborðið!
Imprint: Løgfrøðilig kunning
Information: Kunning
Language: Mál
Open: Lat upp
Open Link: Lat leinkju upp
Options: Valmøguleikar
Warning: Ávaring

11
app/i18n/ui/fy.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternativen
Close: Slute
Copy: Kopiearje
Identifier copied to clipboard!: Identifikaasje nei it klamboerd kopiearre!
Imprint: Kolofon
Information: Ynformaasje
Language: Taal
Open: Iepenje
Open Link: Keppeling iepenje
Options: Opsjes
Warning: Warskôging

11
app/i18n/ui/ga.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Roghanna eile
Close: Dún
Copy: Cóipeáil
Identifier copied to clipboard!: Cóipeáladh an t-aitheantóir chuig an ghearrthaisce!
Imprint: Fógra dlíthiúil
Information: Faisnéis
Language: Teanga
Open: Oscail
Open Link: Oscail an nasc
Options: Roghanna
Warning: Rabhadh

11
app/i18n/ui/gd.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Roghainnean eile
Close: Dùin
Copy: Dèan lethbhreac
Identifier copied to clipboard!: Chaidh lethbhreac dhen aithnichear a chur air an stòr-bhòrd!
Imprint: Fiosrachadh laghail
Information: Fiosrachadh
Language: Cànan
Open: Fosgail
Open Link: Fosgail an ceangal
Options: Roghainnean
Warning: Rabhadh

11
app/i18n/ui/gl.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternativas
Close: Pechar
Copy: Copiar
Identifier copied to clipboard!: Identificador copiado no portapapeis!
Imprint: Aviso legal
Information: Información
Language: Idioma
Open: Abrir
Open Link: Abrir ligazón
Options: Opcións
Warning: Advertencia

11
app/i18n/ui/gn.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Ambue jeporavorã
Close: Mboty
Copy: Monguatia
Identifier copied to clipboard!: Oñemonguatia pe mboheraguapy!
Imprint: Léi marandu
Information: Marandu
Language: Ñe'ẽ
Open: Mbojuruja
Open Link: Mbojuruja joajuha
Options: Jeporavorã
Warning: Ñemomarandu

11
app/i18n/ui/gu.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: અન્ય વિકલ્પો
Close: બંધ કરો
Copy: કૉપિ કરો
Identifier copied to clipboard!: ઓળખકર્તા ક્લિપબોર્ડ પર કૉપિ કર્યો!
Imprint: કાનૂની માહિતી
Information: માહિતી
Language: ભાષા
Open: ખોલો
Open Link: લિંક ખોલો
Options: વિકલ્પો
Warning: ચેતવણી

11
app/i18n/ui/gv.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Reihghyn elley
Close: Dooney
Copy: Jean lhiasaghey
Identifier copied to clipboard!: Ta'n enmyssagh er ny lhiasaghey!
Imprint: Fys leighoil
Information: Fys
Language: Çhengey
Open: Foshil
Open Link: Foshil y kiangley
Options: Reihghyn
Warning: Raaue

11
app/i18n/ui/ha.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Madadai
Close: Rufe
Copy: Kwafi
Identifier copied to clipboard!: An kwafi mai ganowa zuwa allon rubutu!
Imprint: Bayanin doka
Information: Bayani
Language: Harshe
Open: Buɗe
Open Link: Buɗe mahaɗi
Options: Zaɓuɓɓuka
Warning: Gargaɗi

11
app/i18n/ui/ho.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Ma haida
Close: Koua
Copy: Kopi
Identifier copied to clipboard!: Ladana ia kopi vadaeni!
Imprint: Taravatu sivaraina
Information: Sivaraina
Language: Gado
Open: Kehoa
Open Link: Link kehoa
Options: Abia hidi
Warning: Hadibaia

11
app/i18n/ui/hr.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternative
Close: Zatvori
Copy: Kopiraj
Identifier copied to clipboard!: Identifikator je kopiran u međuspremnik!
Imprint: Pravne informacije
Information: Informacije
Language: Jezik
Open: Otvori
Open Link: Otvori poveznicu
Options: Mogućnosti
Warning: Upozorenje

11
app/i18n/ui/ht.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Lòt chwa
Close: Fèmen
Copy: Kopye
Identifier copied to clipboard!: Idantifyan an kopye nan klipbòd la!
Imprint: Enfòmasyon legal
Information: Enfòmasyon
Language: Lang
Open: Louvri
Open Link: Louvri lyen an
Options: Opsyon
Warning: Avètisman

11
app/i18n/ui/hy.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Այլընտրանքներ
Close: Փակել
Copy: Պատճենել
Identifier copied to clipboard!: Նույնացուցիչը պատճենվեց սեղմատախտակին!
Imprint: Իրավական տեղեկություններ
Information: Տեղեկություն
Language: Լեզու
Open: Բացել
Open Link: Բացել հղումը
Options: Ընտրանքներ
Warning: Զգուշացում

11
app/i18n/ui/hz.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Ovikeṱa oviṱjaṱa
Close: Pata
Copy: Hiṱa
Identifier copied to clipboard!: Ondjiviro ya hiṱwa!
Imprint: Omambo woveta
Information: Omambo
Language: Ombango
Open: Paturura
Open Link: Paturura omukambo
Options: Ovikeṱa
Warning: Omaṱoororo

11
app/i18n/ui/ia.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternativas
Close: Clauder
Copy: Copiar
Identifier copied to clipboard!: Identificator copiate al area de transferentia!
Imprint: Information legal
Information: Information
Language: Lingua
Open: Aperir
Open Link: Aperir ligamine
Options: Optiones
Warning: Advertimento

11
app/i18n/ui/ie.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternatives
Close: Clúder
Copy: Copiar
Identifier copied to clipboard!: Identificator copiat al paperiere!
Imprint: Information legal
Information: Information
Language: Lingue
Open: Aperter
Open Link: Aperter li ligament
Options: Optiones
Warning: Avise

11
app/i18n/ui/ig.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Nhọrọ ndị ọzọ
Close: Mechie
Copy: Detuo
Identifier copied to clipboard!: Edepụtara njirimara na klipbọọdụ!
Imprint: Ozi gbasara iwu
Information: Ozi
Language: Asụsụ
Open: Mepee
Open Link: Mepee njikọ
Options: Nhọrọ
Warning: Ịdọ aka na ntị

11
app/i18n/ui/ii.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: ꀋꅉ
Close:
Copy:
Identifier copied to clipboard!: ꂓꂷ ꀕꀐ!
Imprint: ꃀꇖ ꌋꑍ
Information: ꌋꑍ
Language:
Open:
Open Link: ꇤꉈ
Options: ꀋꅉ
Warning: ꋍꅉ

11
app/i18n/ui/ik.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Allat piksrat
Close: Umiksiuŋ
Copy: Aglaakkaŋ
Identifier copied to clipboard!: Atiŋa aglaaksiruq!
Imprint: Maligutaq ilisimaaġutit
Information: Ilisimaaġutit
Language: Uqausiq
Open: Aŋmaġuŋ
Open Link: Aŋmaġuŋ link
Options: Piksrat
Warning: Kaŋiqsiġutit

11
app/i18n/ui/io.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternativi
Close: Klozar
Copy: Kopiar
Identifier copied to clipboard!: Identigilo kopiesis a la tondilo!
Imprint: Legala informo
Information: Informo
Language: Linguo
Open: Apertar
Open Link: Apertar ligilo
Options: Opcioni
Warning: Averto

11
app/i18n/ui/is.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Aðrir kostir
Close: Loka
Copy: Afrita
Identifier copied to clipboard!: Auðkenni afritað á klippispjald!
Imprint: Lagalegar upplýsingar
Information: Upplýsingar
Language: Tungumál
Open: Opna
Open Link: Opna tengil
Options: Valkostir
Warning: Viðvörun

11
app/i18n/ui/iu.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: ᐊᓯᖏᑦ ᓂᕈᐊᒐᒃᓴᐃᑦ
Close: ᒪᑐᐃᕐᓗᒍ
Copy: ᐊᔾᔨᓕᐅᕐᓗᒍ
Identifier copied to clipboard!: ᓇᓗᓇᐃᒃᑯᑕᖅ ᐊᔾᔨᓕᐅᖅᑕᐅᔪᖅ!
Imprint: ᒪᓕᒐᓕᕆᓂᕐᒧᑦ ᑐᓴᒐᒃᓴᖅ
Information: ᑐᓴᒐᒃᓴᖅ
Language: ᐅᖃᐅᓯᖅ
Open: ᐅᒃᑯᐃᓗᒍ
Open Link: ᐊᑐᕆᐊᖅ ᐅᒃᑯᐃᓗᒍ
Options: ᓂᕈᐊᒐᒃᓴᐃᑦ
Warning: ᖃᐅᔨᒋᐊᕐᓂᖅ

11
app/i18n/ui/jv.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternatif
Close: Tutup
Copy: Salin
Identifier copied to clipboard!: Pengenal disalin menyang papan klip!
Imprint: Informasi hukum
Information: Informasi
Language: Basa
Open: Bukak
Open Link: Bukak pranala
Options: Pilihan
Warning: Pèngetan

11
app/i18n/ui/ka.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: ალტერნატივები
Close: დახურვა
Copy: კოპირება
Identifier copied to clipboard!: იდენტიფიკატორი დაკოპირდა ბუფერში!
Imprint: იურიდიული ინფორმაცია
Information: ინფორმაცია
Language: ენა
Open: გახსნა
Open Link: ბმულის გახსნა
Options: პარამეტრები
Warning: გაფრთხილება

11
app/i18n/ui/kg.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Mapona ya nkaka
Close: Kanga
Copy: Kopia
Identifier copied to clipboard!: Kinsinsu me kopiama!
Imprint: Nsangu ya nsiku
Information: Nsangu
Language: Ndinga
Open: Kangula
Open Link: Kangula nkangu
Options: Mapona
Warning: Lukebisu

11
app/i18n/ui/ki.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Mathuura mangĩ
Close: Hinga
Copy: Kobia
Identifier copied to clipboard!: Kĩmenyithia nĩ kĩakobio!
Imprint: Ũhoro wa watho
Information: Ũhoro
Language: Rũthiomi
Open: Hingũra
Open Link: Hingũra kĩhoti
Options: Mathuura
Warning: Mũkaana

11
app/i18n/ui/kj.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Omahoololo vali
Close: Pata
Copy: Shanga
Identifier copied to clipboard!: Edina la shangwa!
Imprint: Omauyelele opaveta
Information: Omauyelele
Language: Elaka
Open: Yeulula
Open Link: Yeulula ekwatakanifo
Options: Omahoololo
Warning: Elondwelo

11
app/i18n/ui/kk.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Баламалар
Close: Жабу
Copy: Көшіру
Identifier copied to clipboard!: Идентификатор алмасу буферіне көшірілді!
Imprint: Құқықтық ақпарат
Information: Ақпарат
Language: Тіл
Open: Ашу
Open Link: Сілтемені ашу
Options: Параметрлер
Warning: Ескерту

11
app/i18n/ui/kl.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Allat periarfissat
Close: Matuguk
Copy: Assiliiguk
Identifier copied to clipboard!: Kinaassusersiut assilineqarpoq!
Imprint: Inatsisitigut paasissutissat
Information: Paasissutissat
Language: Oqaatsit
Open: Ammaruk
Open Link: Aqqutissiaq ammaruk
Options: Periarfissat
Warning: Mianersoqqussut

11
app/i18n/ui/km.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: ជម្រើសផ្សេងទៀត
Close: បិទ
Copy: ចម្លង
Identifier copied to clipboard!: បានចម្លងអត្តសញ្ញាណទៅក្ដារតម្បៀតខ្ទាស់!
Imprint: ព័ត៌មានផ្លូវច្បាប់
Information: ព័ត៌មាន
Language: ភាសា
Open: បើក
Open Link: បើកតំណ
Options: ជម្រើស
Warning: ការព្រមាន

11
app/i18n/ui/kn.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: ಪರ್ಯಾಯಗಳು
Close: ಮುಚ್ಚಿ
Copy: ನಕಲಿಸಿ
Identifier copied to clipboard!: ಗುರುತಿಸುವಿಕೆಯನ್ನು ಕ್ಲಿಪ್ಬೋರ್ಡ್ಗೆ ನಕಲಿಸಲಾಗಿದೆ!
Imprint: ಕಾನೂನು ಮಾಹಿತಿ
Information: ಮಾಹಿತಿ
Language: ಭಾಷೆ
Open: ತೆರೆಯಿರಿ
Open Link: ಲಿಂಕ್ ತೆರೆಯಿರಿ
Options: ಆಯ್ಕೆಗಳು
Warning: ಎಚ್ಚರಿಕೆ

11
app/i18n/ui/kr.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Kəla gade
Close: Kaltə
Copy: Kopi
Identifier copied to clipboard!: Suna kopi dəwo!
Imprint: Labar shariya
Information: Labar
Language: Təla
Open: Buwo
Open Link: Link buwo
Options: Kəla
Warning: Dəwo

11
app/i18n/ui/ks.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: مُتبادِل
Close: بنٛد کٔرِو
Copy: نقل کٔرِو
Identifier copied to clipboard!: شناخت کلپ بورڈس پیٹھ نقل کرنہٕ آمٕژ!
Imprint: قانوٗنی معلوٗمات
Information: معلوٗمات
Language: زبان
Open: کھولِو
Open Link: لِنک کھولِو
Options: اِختیار
Warning: خبردار

11
app/i18n/ui/ku.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternatîf
Close: Bigire
Copy: Kopî bike
Identifier copied to clipboard!: Nasname li panoyê hate kopîkirin!
Imprint: Agahiyên qanûnî
Information: Agahî
Language: Ziman
Open: Veke
Open Link: Girêdanê veke
Options: Vebijark
Warning: Hişyarî

11
app/i18n/ui/kv.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Мукӧд вариантъяс
Close: Пӧдлы
Copy: Копируйт
Identifier copied to clipboard!: Идентификатор копируйтӧма!
Imprint: Оланпас юӧр
Information: Юӧр
Language: Кыв
Open: Восьт
Open Link: Восьт ыстӧд
Options: Параметръяс
Warning: Висьтавлӧм

11
app/i18n/ui/kw.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Dewisyow erel
Close: Deges
Copy: Dasskrifa
Identifier copied to clipboard!: An aswonnyas re beu dasskrifys!
Imprint: Kedhlow laghel
Information: Kedhlow
Language: Yeth
Open: Ygeri
Open Link: Ygeri an kolm
Options: Dewisyow
Warning: Gwarnyans

11
app/i18n/ui/ky.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Альтернативалар
Close: Жабуу
Copy: Көчүрүү
Identifier copied to clipboard!: Идентификатор алмашуу буферине көчүрүлдү!
Imprint: Укуктук маалымат
Information: Маалымат
Language: Тил
Open: Ачуу
Open Link: Шилтемени ачуу
Options: Параметрлер
Warning: Эскертүү

11
app/i18n/ui/la.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternativae
Close: Claude
Copy: Exscribe
Identifier copied to clipboard!: Identificator in tabulam exscriptus est!
Imprint: Notitia legalis
Information: Informatio
Language: Lingua
Open: Aperi
Open Link: Aperi nexum
Options: Optiones
Warning: Monitum

11
app/i18n/ui/lb.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternativen
Close: Zoumaachen
Copy: Kopéieren
Identifier copied to clipboard!: Identifikateur an d'Tëschenoflag kopéiert!
Imprint: Impressum
Information: Informatioun
Language: Sprooch
Open: Opmaachen
Open Link: Link opmaachen
Options: Optiounen
Warning: Warnung

11
app/i18n/ui/lg.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Ebirala by'olondako
Close: Ggalawo
Copy: Koppa
Identifier copied to clipboard!: Akabonero kakoppeddwa!
Imprint: Ebikwata ku mateeka
Information: Ebikwata ku nsonga
Language: Olulimi
Open: Ggulawo
Open Link: Ggulawo link
Options: Eby'okulondako
Warning: Okulabula

11
app/i18n/ui/li.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternatieve
Close: Sloete
Copy: Kopiëre
Identifier copied to clipboard!: Identificatie nao 't klembord gekopieerd!
Imprint: Colofon
Information: Informatie
Language: Taal
Open: Opene
Open Link: Link opene
Options: Opties
Warning: Waorsjuwing

11
app/i18n/ui/ln.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Maponi mosusu
Close: Kanga
Copy: Kopi
Identifier copied to clipboard!: Elembo ekopiami!
Imprint: Makambo ya mibeko
Information: Makambo
Language: Lokota
Open: Fungola
Open Link: Fungola lyɛ́n
Options: Maponi
Warning: Likebisi

11
app/i18n/ui/lo.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: ທາງເລືອກອື່ນ
Close: ປິດ
Copy: ສຳເນົາ
Identifier copied to clipboard!: ສຳເນົາຕົວລະບຸໄປທີ່ຄລິບບອດແລ້ວ!
Imprint: ຂໍ້ມູນທາງກົດໝາຍ
Information: ຂໍ້ມູນ
Language: ພາສາ
Open: ເປີດ
Open Link: ເປີດລິ້ງ
Options: ຕົວເລືອກ
Warning: ຄຳເຕືອນ

11
app/i18n/ui/lt.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternatyvos
Close: Uždaryti
Copy: Kopijuoti
Identifier copied to clipboard!: Identifikatorius nukopijuotas į iškarpinę!
Imprint: Teisinė informacija
Information: Informacija
Language: Kalba
Open: Atidaryti
Open Link: Atidaryti nuorodą
Options: Parinktys
Warning: Įspėjimas

11
app/i18n/ui/lu.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Bisungula bikwabo
Close: Buikila
Copy: Kopia
Identifier copied to clipboard!: Tshimanyinu tshikopia!
Imprint: Malu a mikenji
Information: Malu
Language: Muakulu
Open: Bulula
Open Link: Bulula ditamba
Options: Bisungula
Warning: Dimanyisha

11
app/i18n/ui/lv.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Alternatīvas
Close: Aizvērt
Copy: Kopēt
Identifier copied to clipboard!: Identifikators nokopēts starpliktuvē!
Imprint: Juridiskā informācija
Information: Informācija
Language: Valoda
Open: Atvērt
Open Link: Atvērt saiti
Options: Opcijas
Warning: Brīdinājums

11
app/i18n/ui/mg.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Safidy hafa
Close: Hidio
Copy: Adikao
Identifier copied to clipboard!: Voadika tao amin'ny clipboard ny famantarana!
Imprint: Fampahafantarana ara-dalàna
Information: Fampahalalana
Language: Fiteny
Open: Sokafy
Open Link: Sokafy ny rohy
Options: Safidy
Warning: Fampitandremana

11
app/i18n/ui/mh.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Kōmelele ko jet
Close: Kilōk
Copy: Kappi
Identifier copied to clipboard!: Kakōlle eo emōj kappi!
Imprint: Melele in kien
Information: Melele
Language: Kajin
Open: Kōpeļļo
Open Link: Kōpeļļo link
Options: Kōmelele
Warning: Kakkōļ

11
app/i18n/ui/mi.yaml Normal file
View File

@@ -0,0 +1,11 @@
Alternatives: Kōwhiringa kē
Close: Katia
Copy: Tāruatia
Identifier copied to clipboard!: Kua tāruatia te tautuhi ki te papatopenga!
Imprint: Pārongo ā-ture
Information: Pārongo
Language: Reo
Open: Whakatuwhera
Open Link: Whakatuwhera hononga
Options: Kōwhiringa
Warning: Whakatūpato

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