v0.255.0 — the globe on the sign-in-flow pages: styled, and inside the card
gates / gates (push) Successful in 23s
gates / gates (push) Successful in 23s
Two defects in v0.254.0's globe, both plain on a browser and neither catchable by anything that existed — every test read the MARKUP, and the fault was in which CSS file the browser fetched. The shells requested /static/style.css with NO ?v=, while layout.html has carried one since v0.166.0. A browser holding a copy from before v0.254.0 kept serving CSS with no .lang-globe rules, so the globe came out as a bare unstyled <details> — a stray triangle and two plain words at the edge of the window. It was FIVE shells, not the three named: both guest share pages have the same fault for any CSS change, and their visitor is the likeliest of all to be holding an old copy. And .Version was missing from three of those five data maps, which is exactly how the next one would be forgotten — it is now filled at the one choke point every shell renders through. The globe also floated outside the card, pinned to the corner of the VIEWPORT, reading as part of the browser rather than the page. It now sits inside the card, centred under the footer, with the menu opening upward via the shared rule — so the dashboard and the shells cannot drift. AND A THIRD, caught by a test that already existed: putting the version on the guest share pages would have printed the controller build onto a page a stranger with a capability URL can open. TestShareGuest_HeadersTilesNoAdminChrome refused it. Those two now take an opaque per-build tag — same cache-busting, no disclosure. The fill is ONE function shared with the parity harness, because a fixture rendered through a different data path is a picture of a page nobody serves, which the previous release got wrong twice. 15 shell fixtures re-captured; 91 identical, every dashboard page among them. MinAgent: 0.131.0 (unchanged). No hub release needed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -1,3 +1,43 @@
|
||||
## v0.255.0 — The globe on the sign-in-flow pages: styled, and inside the card (2026-09-18, fixes v0.254.0)
|
||||
|
||||
**MinAgent: 0.131.0** (unchanged). **No hub release needed.** Nothing on the wire moved. One Hungarian
|
||||
block changes, on the pages outside the dashboard chrome only — **zero dashboard fixtures were
|
||||
re-captured**.
|
||||
|
||||
Two defects in v0.254.0's globe, both visible on a real browser and neither catchable by any test that
|
||||
existed:
|
||||
|
||||
**1. The stylesheet was requested with no cache-buster, so the globe rendered UNSTYLED.** `layout.html`
|
||||
has always used `/static/style.css?v={{.Version}}`; the shells did not. A browser that had the file
|
||||
cached from before v0.254.0 kept serving a copy with no `.lang-globe` rules in it, and the globe came
|
||||
out as a bare `<details>` — a stray triangle and two plain words, floating at the edge of the window.
|
||||
**It was not three shells but FIVE**: `login`, `claim`, `recovery`, **and both guest share pages**. The
|
||||
two share pages have no globe, but they have the same stale-stylesheet problem for any CSS change, and
|
||||
their visitor is the likeliest of all to be holding an old copy. All five fixed.
|
||||
|
||||
**And `.Version` was not in the data of three of them** — which is exactly how the next shell would
|
||||
have been missed. It is now set in `executeTemplateLang`, the single choke point every shell renders
|
||||
through, so a new shell cannot forget it.
|
||||
|
||||
**2. The globe floated outside the card.** `.shell-lang` was pinned to the corner of the VIEWPORT, so
|
||||
it read as part of the browser rather than part of the page. It now sits **inside the card, centred
|
||||
under the footer**, with the menu opening upward — which is the shared `.lang-globe-menu` rule, so the
|
||||
block adds no positioning of its own and the dashboard and the shells cannot drift apart.
|
||||
|
||||
**A third defect, found by an existing test while fixing the first two.** Putting `?v={{.Version}}`
|
||||
on the guest share pages would have printed the controller version onto a page **a stranger holding a
|
||||
capability URL can open** — `TestShareGuest_HeadersTilesNoAdminChrome` refuses exactly that, and
|
||||
refused it. Those two pages now take an **opaque per-build tag** (`AssetTag`, four bytes of a hash of
|
||||
the version): it busts a cache just as well and tells a visitor nothing about which build is running.
|
||||
The fill lives in one function, `addShellAssetData`, called by `executeTemplateLang` **and** by the
|
||||
parity harness — because a fixture rendered through a different data path is a picture of a page
|
||||
nobody serves, which this release's predecessor got wrong twice.
|
||||
|
||||
`TestGlobeOnAnonymousShells` gained both halves — the stylesheet carries a non-empty `?v=`, and the
|
||||
globe is inside the card and below the footer. Each was red-proofed by restoring the defect's exact
|
||||
shape. The test server gained a version, because an empty `?v=` busts a cache exactly once and never
|
||||
again, and baking that into a fixture would have hidden it.
|
||||
|
||||
## v0.254.0 — The saved notes follow the language, and the switch becomes a globe (2026-09-18, R-557 slice 2 release C — SLICE 2 CLOSED)
|
||||
|
||||
**MinAgent: 0.131.0** (unchanged). **No hub release needed.** Nothing on the wire moved.
|
||||
|
||||
+3
-1
@@ -7,7 +7,9 @@
|
||||
>
|
||||
> Ask Claude Code: "Please update CONTEXT.md with what we did today"
|
||||
|
||||
Last updated: 2026-09-18 (v0.254.0 — localisation slice 2 CLOSED: saved notes follow the language, the switch is a globe)
|
||||
Last updated: 2026-09-18 (v0.255.0 — the globe on the sign-in-flow pages: styled, and inside the card)
|
||||
|
||||
> **2026-09-18 — v0.255.0 (fixes the v0.254.0 globe).** The sign-in-flow pages requested `style.css` with **no `?v=`**, so a browser holding a pre-0.254.0 copy served CSS with no `.lang-globe` rules and the globe rendered as a bare unstyled `<details>` — **invisible to every test, because they all read markup and the fault was in which CSS file the browser fetched**. It was FIVE shells, not three (both guest share pages too), and `.Version` was missing from three of their data maps — now set once in `executeTemplateLang`. The globe also moved INSIDE the card, centred under the footer, menu opening upward via the shared rule. 15 shell fixtures re-captured, **zero dashboard ones**. R-579.
|
||||
|
||||
> **2026-09-18 — FLEET FLOOR RAISED to 0.254.0** (operator asked), `min_agent` 0.131.0 declared — above the vouched golden 0.246.0, so the declaration carries it (R-472). Hub: `managed floor SERVED … from declared`; demo-felhom went 0.253.0 -> 0.254.0 **by itself in ~40 s**, healthy, four other containers up, own log `settle-gate: GO — at/above floor 0.254.0`, and its sign-in page shows **one globe, zero old text links**. **Peti Proxmox (DOWN 65 d, 0.115.0) and Tester 1 (DOWN 1 d, 0.245.0) did NOT get it** and take it unattended when they return — untested on this version. Evidence: `felhom.eu/documentation/audits/i18n-slice2-2026-09-18/floor-raise-0.254.0.md`.
|
||||
|
||||
|
||||
@@ -1,274 +1,70 @@
|
||||
# REPORT — localisation slice 2, COMPLETE (controller v0.252.0 + v0.253.0 + v0.254.0, R-557)
|
||||
# REPORT — the globe on the sign-in-flow pages, fixed (controller v0.255.0)
|
||||
|
||||
**2026-09-18 · base commit `736f54b49610` (v0.251.0) · MinAgent 0.131.0, unchanged · no hub release.**
|
||||
**Three releases: A (the sentences shown now), B (the 179 error messages), C (the saved notes + the globe).**
|
||||
Architecture read first and named: `felhom.eu/documentation/architecture/10-localisation.md` §1
|
||||
(parity), §2 (mechanism), §5 (gates), §9 (the R-553 signals), §10 (this slice); `07-backup-architecture.md`
|
||||
for what the hub reads from a box; `05-hub-architecture.md` for what the hub composes itself.
|
||||
|
||||
---
|
||||
|
||||
## 1. Claims in the task that live source disproved — named first
|
||||
|
||||
| the task said | source says |
|
||||
|---|---|
|
||||
| "`cloudflare/countries.go` is used by `report/types.go` (on the wire)" | **No.** `report/builder.go` puts country **CODES** on the wire (`AllowedCountries []string`); no country NAME leaves the box. `CountryName()` has no caller at all. So the names are display-only and were free to translate — which is what this release did. |
|
||||
| "the hub's dispatcher composes its own customer mail from event kinds (grep of `dispatcher.go` for `.Message`: nothing)" | **Wrong in substance.** `.Message` finds nothing because the message arrives as a PARAMETER, not a field. `FormatCustomerEmail` (hub `notify/templates.go` L167-210) uses `customerMessages[eventType]` when it has one and **falls back to the controller's message** when it does not — and appends it as „- Üzenet: %s" whenever the two differ. Several event types deliberately carry no entry so the controller's sentence IS the mail (hub `api/handler.go`, the notes at L2034/L2045/L2066). The conclusion (do not translate them) was right; the reason was not. |
|
||||
| "5 flash readers / 8 writers" | 8 writers, **8 read sites** — the three named plus `auth.go:100` (login), `server.go:498` (claim) and the `flash_error` twins. All eight converted. |
|
||||
| per-file counts (`handlers.go` 121, `offbox_handlers.go` 72, `storage_handlers.go` 48, `handler_debug.go` 40, `offbox_reconstitute.go` 41, `notify/notifier.go` 30, `api/router.go` 19) | measured at `736f54b49610`: **120 / 70 / 45 / 39 / 38 / 31 / 18**. Totals: **1 120** Hungarian literals, not 1 141. |
|
||||
| "`scripts/i18n_inventory.py`" (as a controller script) | it lives in **`felhom.eu/scripts/`**. Its Go-literal walker was copied into the new gate rather than imported — a controller clone need not sit beside felhom.eu, and a gate that can fail to import its scanner can silently skip. |
|
||||
|
||||
## 2. What shipped
|
||||
|
||||
**226 Go literals converted**, plus 237 country names now available in English. 426 keys, each
|
||||
recorded in `scripts/i18n_go_keys.json` against the literal it replaced.
|
||||
|
||||
| file | before | after | converted | of the rest, `fmt.Errorf` (release B) |
|
||||
|---|---|---|---|---|
|
||||
| `internal/web/handlers.go` | 120 | 44 | 76 | 0 |
|
||||
| `internal/web/offbox_handlers.go` | 70 | 22 | 48 | 0 |
|
||||
| `internal/web/storage_handlers.go` | 45 | 19 | 26 | 16 |
|
||||
| `internal/api/router.go` | 18 | 0 | 18 | 0 |
|
||||
| `internal/web/share_handlers.go` | 22 | 5 | 17 | 0 |
|
||||
| `internal/web/sharing_handlers.go` | 18 | 3 | 15 | 1 |
|
||||
| `internal/web/alerts.go` | 13 | 0 | 13 | 0 |
|
||||
| `internal/web/tier2_config_handler.go` | 8 | 3 | 5 | 0 |
|
||||
| `internal/api/geo.go` | 5 | 0 | 5 | 0 |
|
||||
| `internal/web/backup_handlers.go` | 12 | 9 | 3 | 0 |
|
||||
| `internal/cloudflare/countries.go` | 113 | 113 | 0 (the TABLE stays — it validates codes) | 0 |
|
||||
|
||||
Mechanism: `i18n.Bundle.Msgf`; `web.(*Server).msg/msgLang/msgN`; `api.(*Router).msg/msgLang/langFor/countryName`;
|
||||
`flashQuery`/`flashText`/`flashFrom`; `Alert.MessageKey`/`MessageArgs`/`LinkTextKey` + `Alert.rendered(lang)`;
|
||||
`TitleArgs` for the four app-named titles (R-566, closed).
|
||||
|
||||
**Word order without a second syntax.** The task asked for a named-parameter (`{{.Name}}`) form for
|
||||
multi-parameter messages. It is not here, deliberately: English reorders with Go's own explicit
|
||||
argument indexes (`%[2]s`), which `fmt` already understands. The Hungarian value then stays the format
|
||||
string the code always had, byte for byte — which is exactly what the parity gate compares, so the
|
||||
measurement needs no exception. `TestBundleParametersMatchAcrossLanguages` counts an indexed verb as
|
||||
one verb, so a reordered English still has to use the same verbs on the same values.
|
||||
|
||||
## 3. The wire — surveyed, frozen, not translated (A.1)
|
||||
|
||||
Everything a HUB reads keeps its bytes. Filed against **R-558** (slice 3 owns it):
|
||||
|
||||
| producer | where it lands | why it stays |
|
||||
|---|---|---|
|
||||
| `internal/monitor/healthcheck.go` — 5 storage sentences | report `health.warnings` / `health.issues` | the hub stores and shows them to the operator |
|
||||
| `internal/notify/notifier.go` — 31 event messages | event `message` → `FormatCustomerEmail` | **the household reads these in an e-mail**; several types have no `customerMessages` entry precisely so this sentence is the mail |
|
||||
| `internal/cloudflare/countries.go` — the table | nothing (codes only) | it validates codes; the DISPLAY name is what follows the language |
|
||||
|
||||
Pinned by `TestStorageWarningWireTextIsFrozen`, `TestStorageWarningFormatsAreFrozen`,
|
||||
`TestEventMessageWireTextIsFrozen`, `TestEventMessagesCarryNoBundleKey`. Both goldens were captured
|
||||
from the producers at the base commit, before any change, and both were seen to fail.
|
||||
|
||||
The **persisted** text found by the same survey is listed in §6 for release C.
|
||||
|
||||
## 4. Tests and their red-proofs
|
||||
|
||||
Every one was run against a planted break and watched to convict; the planted change was then
|
||||
reverted and the suite re-run green. Full log: `audits/i18n-slice2-2026-09-18/redproofs.txt`.
|
||||
|
||||
| test / gate | what was planted | what convicted |
|
||||
|---|---|---|
|
||||
| `i18n_go_parity.py` | one byte added to a hu.json value | `CHANGED`, naming the key and the base literal |
|
||||
| `i18n_go_parity.py` | a key citing text no literal has | `INVENTED`, naming the text |
|
||||
| `i18n_go_parity.py` | a joined key with reworded fragments | `INVENTED`, naming the fragment |
|
||||
| `test_gate_decoys.py` go-parity ×3 | reworded / invented / unlisted | all three rejected |
|
||||
| `TestEventMessageWireTextIsFrozen` | „telepítve" → „telepitve" | got/want printed |
|
||||
| `TestStorageWarning*IsFrozen` | a wire warning translated | both tests |
|
||||
| `TestFlashOnAServerWithNoBundleField` | `s.bundle()` without the `i18n.Shared` fallback | the page showed `flash.share.enabled` |
|
||||
| `TestFlashKeyRoundTrip` | — | legacy prose, unknown key, `<script>`, empty: all six rows |
|
||||
| `TestParameterisedPageTitles` | — | the four app-named titles equal the old concatenation |
|
||||
| `TestAPIMessagesFollowTheHouseholdLanguage` | — | hu byte-identical, en different, per key |
|
||||
|
||||
**The gate caught a live defect in itself, not a decoy.** Its first capture filtered literals through
|
||||
an ASCII-Hungarian word list and missed seven real ones („Naponta", „5 percenkent", „Eletjel
|
||||
(Heartbeat)", „Adatbazis mentes", „Biztonsagi mentes", „Mentes integritas", „Rendszer allapot") — the
|
||||
R-565 class exactly. It refused the keys that cited them. The filter is gone: every literal is
|
||||
indexed, because the only question this index answers is "did the base commit contain this text?".
|
||||
|
||||
## 5. Green gate
|
||||
|
||||
`go build ./... && go vet ./... && go test ./...` — all green.
|
||||
`python3 scripts/controller_gates.py` — 16 blocking gates OK + golden-notice advisory, **including the
|
||||
new `go-parity`**. `python3 scripts/test_gate_decoys.py` — all 23 decoys behaved.
|
||||
`HU_FORMAL_CEILING` 16 → 18, the measured number, no word changed (R-516 owns the words).
|
||||
|
||||
## 6. What is NOT in this release — each is a row, not prose
|
||||
|
||||
- **894 Hungarian literals remain**, of which **176 are `fmt.Errorf`/`errors.New`** — release B.
|
||||
- **Persisted text** (release C): `settings.OffboxTarget.LastError/LastWarning/LastProofReason`,
|
||||
`LastSyncError`, `RestoreOpResult`, the `unitRestore*MsgFmt` and `tier2*Msg` family in
|
||||
`handlers.go`, and `backup/offbox_reconstitute.go`. Written by a background run, read days later.
|
||||
**The §16 decision stands as its default: option 1** — written in the box's language at the time,
|
||||
with a household that switches seeing the old language until the next run.
|
||||
- **R-570's producer is untouched**, as its row requires.
|
||||
- New rows: **R-572** (`pruneLabel`/`fmtDuration` in `funcmap.go` are copy-producing helpers that
|
||||
`localeFuncs` does not override — „vasárnap" renders on an English page), **R-573** (the
|
||||
agent-channel and endpoint-drift banner text is composed by the channel-health checker and reaches
|
||||
`Alert.Message` as finished Hungarian), **R-574** (`handler_debug.go`, 39 literals, page copy and
|
||||
JSON payload not yet separated).
|
||||
|
||||
## 7. Live validation
|
||||
|
||||
Endpoint-level on demo-hp guest 9201 (no browser on DooPlex — `claude-in-chrome` is not available
|
||||
here). Evidence: `felhom.eu/documentation/audits/i18n-slice2-2026-09-18/A/live/`.
|
||||
|
||||
|
||||
---
|
||||
|
||||
# Release B — v0.253.0: errors carry a key
|
||||
|
||||
**179 Hungarian error literals converted; ZERO remain.** `util.MsgError` carries the key from the
|
||||
package that makes the error to the handler that prints it.
|
||||
|
||||
## 1. The mechanism, and the three things it had to do at once
|
||||
|
||||
| property | why it is not optional | pinned by |
|
||||
|---|---|---|
|
||||
| `Error()` is the Hungarian, byte for byte | every un-converted printer (a log line, a `%v`, a third-party wrapper) keeps printing what it printed. Without it, 179 producers could not be converted before all their printers were. | `TestMsgErrorKeepsKindAndHuText` |
|
||||
| `errors.Is` answers for the kind **and** for a wrapped cause | `KindErrorf` returned the kind alone and dropped the cause; a converted producer usually wraps one | `TestMsgErrorUnwrapsTheCauseToo` |
|
||||
| an error ARGUMENT renders recursively | `„formázás sikertelen: %w"` is a sentence wrapping a sentence; both halves are ours | `TestErrTextRendersAWrappedMessageErrorToo` |
|
||||
| a FOREIGN error prints verbatim | restic, docker, ssh and the stdlib are not ours to translate (R-553's rule) | `TestErrTextFallsBackVerbatim` |
|
||||
|
||||
76 display sites in `internal/web` and `internal/api` now go through `errText`;
|
||||
`TestNoErrErrorInPageOutput` examines 316 display-sink lines and convicts any that do not. A
|
||||
`strings.Contains(err.Error(), …)` is a COMPARISON and stays untouched — the four English ones are
|
||||
R-569.
|
||||
|
||||
`memoryVerdict` returns an ERROR rather than a sentence, so the deploy's 409 and the household's
|
||||
language come from one value; `UpdateRefusal` gained a `Cause` so that error survives the update path
|
||||
to the API.
|
||||
|
||||
## 2. Plurals — one rule, stated once
|
||||
|
||||
**A key that carries `.one`/`.other` forms in a language is a plural key, and its FIRST parameter is
|
||||
the count** (`i18n.Bundle.form`). Hungarian never carries them, so a Hungarian render is unchanged at
|
||||
every count. Deliberately NOT a per-call-site flag: the producer somebody forgot would read „3 app is
|
||||
not running" with nothing to catch it, and the bundle is where a translator works.
|
||||
|
||||
`TestPluralFirstArgIsNumeric` pins that every plural value really takes its count first.
|
||||
`TestNoOrdinaryKeyEndsInAPluralSuffix` pins that the two suffixes stay reserved — **it caught a real
|
||||
collision the day the rule landed** (`alert.deadapp.one`, the ONE dead app, would have been read as
|
||||
the singular of a key that does not exist). Renamed to `alert.deadapp.single`.
|
||||
|
||||
## 3. Two defects release B found in its OWN tooling
|
||||
|
||||
Both are recorded here rather than quietly fixed, because each is a shape that will recur.
|
||||
|
||||
**(a) The bulk converter silently dropped a multi-line concatenation.**
|
||||
`fmt.Errorf("a: "+ "b: %s", x)` kept only `"a: "` and lost the rest with its arguments — 7 producers
|
||||
damaged. **The parity gate did NOT catch it**, and the reason matters: every surviving fragment WAS a
|
||||
real base-commit literal, so the gate's question ("is this text real?") was answered *yes* while the
|
||||
CALL had lost text. What caught it was two behaviour tests that assert the sentence a customer reads
|
||||
(`TestR356_ScenarioC_UndeployedAppIsStillRefused`, `TestR379_ScenarioA_RollbackSucceeds_AppComesBack`).
|
||||
All 7 were rebuilt as joined keys and the six wrong keys pruned from both bundles. **The lesson: a
|
||||
structural gate over the TEXT cannot see a defect in the CALL; only a test that renders the sentence
|
||||
can.**
|
||||
|
||||
**(b) My own counting script was case-sensitive**, so it reported "0 error literals left" while five
|
||||
remained („occ parancs sikertelen", „hub hiba", „OnlyOffice aldomain nem ismert" ×2). That is the
|
||||
R-565 shape inside the measuring instrument. Re-measured with `re.I`; the five are converted. The
|
||||
ASCII-fragment search that found them is in §5 below, with its controls.
|
||||
|
||||
## 4. Red-proofs
|
||||
|
||||
Seven planted breaks, each seen to convict and then reverted (full log:
|
||||
`audits/i18n-slice2-2026-09-18/redproofs.txt`, entries 8–14). Plus the two live catches above, which
|
||||
are not red-proofs — nobody planted them.
|
||||
|
||||
## 5. The "no Hungarian error left" claim, with controls
|
||||
|
||||
- **Negative control:** `fmt.Errorf("…qzxvkjq` → 0 hits (the fragment is in no file).
|
||||
- **Instrument works:** the same ASCII search run against the release-B BASE commit finds
|
||||
`sikertelen` 12× in `migrate.go` and `nincs` 7× in `offbox_restore.go`.
|
||||
- **The claim, now:** an ASCII search for `sikertelen|sikeres|telepitve|mentes|nincs|kotelezo|hiba|folyamatban`
|
||||
inside `fmt.Errorf`/`errors.New`, **case-insensitively**, and a separate accented-letter search:
|
||||
**0 hits each**, outside a comment in `internal/util/msgerr.go` that quotes an example.
|
||||
|
||||
## 6. What is left after B
|
||||
|
||||
**705 Hungarian literals**, none of them errors: the country TABLE (113, not on the wire and not
|
||||
translated on purpose), `handler_debug.go` (R-574), the notifier's 27 wire messages (R-558),
|
||||
`funcmap.go`'s two un-overridden helpers (R-572), the text a background run PERSISTS (release C), and
|
||||
the R-570 producer. Release C's default stands: written in the box's language at write time.
|
||||
|
||||
|
||||
---
|
||||
|
||||
# Release C — v0.254.0: the saved notes, and a globe for the switch. SLICE 2 CLOSED.
|
||||
**2026-09-18 · base `2e9d402` (v0.254.0) · MinAgent 0.131.0, unchanged · no hub release.**
|
||||
Architecture named: `felhom.eu/documentation/architecture/10-localisation.md` §3 (who picks the
|
||||
language, and where the switch lives).
|
||||
|
||||
## 1. Claims in the prompt that live source disproved — named first
|
||||
|
||||
| the prompt said | source says |
|
||||
|---|---|
|
||||
| "Release A's survey (persisted list, wire list)" is in `audits/i18n-slice2-2026-09-18/A/` | That folder holds only `live/`. The persisted list is in this REPORT's §6 for release A. Derived again from source here, which is the stronger reading — and it found the largest persisted group (`EndRestoreOp`'s outcome family, ~40 literals in two files) that a list would have had to remember. |
|
||||
| "the three shells share no layout" | **True, and confirmed by reading**: `login.html`, `claim.html`, `recovery.html` each open their own `<html lang="{{T "layout.html_lang"}}">`. But the consequence was missed: the icon SPRITE lives only in `layout.html`, so a `<use href="#i-globe">` would render nothing on those three. The globe is drawn INLINE in the partial instead — one definition, four places, no sprite coupling. No dead symbol was added. |
|
||||
| "no cookie is read anywhere for language" | Confirmed by grep: no language cookie existed. |
|
||||
| the `<details>` menu "working without script in the browsers the guide names" | **Cannot be confirmed here.** `claude-in-chrome` is not available on DooPlex, so no browser rendered this page. `<details>`/`<summary>` is a plain HTML element with no script, and the markup is asserted; whether it LOOKS right is an operator click-through. Said plainly rather than implied. |
|
||||
| "only the three shells lack `?v=`" | **FIVE do**: `login`, `claim`, `recovery`, **and both guest share pages** (`launcher_shared`, `launcher_share_password`). The share pages carry no globe, but the stale-stylesheet fault is the same for any CSS change and their visitor is the likeliest to hold an old copy. All five fixed — which is why 3 fixtures outside the named three changed, against the prompt's "zero re-captures outside the three shells". (8 first-boot wizard templates also lack it; out of scope, R-554 deletes them.) |
|
||||
| "`.Version` is already in their data" | **Only in two.** `login` (auth.go:343) and `claim` (claim.go:289) set it; `recovery` and both share pages did not. Rather than add it three times, it is set once in `executeTemplateLang` — the choke point every shell renders through — so the next shell cannot miss it. |
|
||||
| "`login.html` L11 … `style.css` L3683-3684" | Confirmed, line for line. |
|
||||
|
||||
## 2. What shipped
|
||||
## 2. What was wrong, and why no test saw it
|
||||
|
||||
**The saved notes.** ~70 producers across `internal/backup` (off-site classes and quota, tier-2
|
||||
reasons and warnings, undo phrases, the reconstitute hold, the restore record) and `internal/web`
|
||||
(the whole `EndRestoreOp` outcome family). Each renders through `util.Text(boxLang(), key, …)`.
|
||||
**`EndRestoreOp` no longer receives a Hungarian literal from anywhere** (grep, with the negative
|
||||
control). `s.noteErr`/`m.noteErr` render release B's errors into a note in the same language.
|
||||
**The globe rendered unstyled** for anyone whose browser had `style.css` cached from before v0.254.0:
|
||||
the shells requested it with no `?v=`, so the cached copy — which has no `.lang-globe` rules — kept
|
||||
being served. The markup was correct, which is why every existing test passed: **they all read the
|
||||
HTML, and the fault was in which CSS file the browser fetched.** It took a screenshot to see it.
|
||||
|
||||
**The globe.** One partial (`lang_globe.html`), used by the dashboard footer and the three visitor
|
||||
shells; drawn inline in the same stroke style as the sprite. `langFor` gained one step, and the order
|
||||
is now fixed: `?lang=` → **household setting when a session exists** → visitor cookie when none →
|
||||
setting → `hu`. A signed-in household never reads the cookie, which is the row that protects them.
|
||||
**And the globe floated outside the card**, pinned to the corner of the viewport, reading as a stray
|
||||
browser control rather than part of the page.
|
||||
|
||||
**`POST /lang`** — CSRF-exempt for a narrow, checkable reason written at the exemption: the only
|
||||
achievable effect is changing the language of the page the victim's own browser shows them. It writes
|
||||
one cookie, reads nothing, and `safeBackPath` refuses `//evil.example` as well as `https://…` —
|
||||
"starts with /" alone is not the test, and that is the mistake the function exists to not make.
|
||||
## 3. The fix
|
||||
|
||||
**§16 taken (the operator's stated default): a claim carries the visitor's language**, on success
|
||||
only, at the one moment an anonymous visitor becomes the household.
|
||||
- `?v={{.Version}}` on all five shells; `Version` set in `executeTemplateLang`.
|
||||
- `.shell-lang` is now `display:flex; justify-content:center; margin-top:1.5rem` — a plain block inside
|
||||
the card. The absolute positioning and the menu-direction override are **deleted**, so the shared
|
||||
`.lang-globe-menu` rule applies and the dashboard and the shells cannot drift apart.
|
||||
- The div moved to the end of each card: under the footer on `login` and `claim`, last in the card on
|
||||
`recovery` (which has no footer paragraph).
|
||||
|
||||
## 3. The two parity exceptions, measured
|
||||
## 3b. A third defect, caught by an existing test
|
||||
|
||||
106 fixtures rendered and compared with a **real (LCS) diff**: exactly **two change shapes** — the
|
||||
dashboard footer (89 fixtures) and the globe in the shells (12) — and **5 byte-identical**, which are
|
||||
precisely the two guest share pages and the catch-all, the three that must not change. Full diff:
|
||||
`audits/i18n-slice2-2026-09-18/C/parity-exception-diff.txt`.
|
||||
Putting the version on the guest share pages would have printed the controller build onto a page **a
|
||||
stranger with a capability URL can open**. `TestShareGuest_HeadersTilesNoAdminChrome` already refused
|
||||
that, and refused it here — a good test earning its keep. Those two pages now take an **opaque
|
||||
per-build tag** instead (`AssetTag`): same cache-busting, no disclosure.
|
||||
|
||||
**Deviation, named:** the prompt asked for one commit per re-capture. This is one commit, because
|
||||
splitting them leaves an intermediate commit whose suite is red — and a commit that does not pass is
|
||||
worse than a commit whose EVIDENCE separates the two blocks, which this one does explicitly.
|
||||
The fill is one function, `addShellAssetData`, called by `executeTemplateLang` **and** by the parity
|
||||
harness. Slice 2 release C got the fixture/production split wrong twice; sharing the function is what
|
||||
makes a third time impossible rather than merely unlikely.
|
||||
|
||||
## 4. Two defects release C found in its own work
|
||||
## 4. Tests, red-proofed
|
||||
|
||||
**(a) A DEADLOCK I introduced, caught by the suite hanging.** `UpdateOffboxStatus` holds the settings
|
||||
WRITE lock while it runs its callback; `boxLang()` reads the language through the settings READ lock.
|
||||
`sync.RWMutex` is not reentrant. The first draft rendered a note inside that callback — on a real box
|
||||
an off-site run would have hung **forever, holding the settings lock**, wedging everything else that
|
||||
touches `settings.json`. The only symptom was `go test` timing out at 25 minutes instead of 8.
|
||||
Fixed by resolving the language before the callback; `TestNoteHelpersAreNotCalledUnderTheSettingsLock`
|
||||
now names the file and line in a second instead. **A hang is the worst kind of failure to diagnose,
|
||||
and the lesson is: a helper that takes a lock must never be called from inside a callback that holds
|
||||
one.**
|
||||
`TestGlobeOnAnonymousShells` gained: the stylesheet carries a **non-empty** `?v=`; the globe is inside
|
||||
the card; the globe is below the footer where one exists. Each was red-proofed by restoring the
|
||||
defect's exact shape — the unversioned link (convicts, naming the stylesheet) and the globe put back
|
||||
before the card (convicts, "floats outside it").
|
||||
|
||||
**(b) The first "only two blocks changed?" measurement compared LINE BY INDEX.** An insertion shifts
|
||||
every line below it, so it reported 60 520 changed lines and measured nothing. **A line-index compare
|
||||
is not a diff.** Redone with difflib.
|
||||
`testServer` gained `version: "test"`: an empty `?v=` busts a cache exactly once and never again, and
|
||||
baking that into a fixture would have hidden it. The test now refuses an empty one.
|
||||
|
||||
Also caught before it shipped: the parity HARNESS rendered the three shells through the DASHBOARD
|
||||
path, which would have baked a form the real page never serves. Found by reading the diff before
|
||||
re-capturing, and independently by `TestI18nDirectRenderPagesFollowLanguage`.
|
||||
## 5. Parity
|
||||
|
||||
## 5. Green gate
|
||||
15 fixtures re-captured — 1 login, 4 claim, 7 recovery, 3 guest share — and **91 identical, including
|
||||
every dashboard page**. Four change shapes: the three shells gained the moved globe AND the buster;
|
||||
the two guest pages gained only the buster, as an opaque tag. The whole diff is the `?v=` attribute and the moved block, nothing else:
|
||||
`felhom.eu/documentation/audits/i18n-slice2-2026-09-18/D/parity-diff.txt`.
|
||||
|
||||
`go build ./... && go vet ./... && go test ./...` green; all controller gates OK. Red-proofs 15–19 in
|
||||
`audits/i18n-slice2-2026-09-18/redproofs.txt`, each seen to convict.
|
||||
## 6. Green gate
|
||||
|
||||
## 6. What is left after slice 2
|
||||
`go build ./... && go vet ./... && go test ./...` green; all controller gates OK.
|
||||
|
||||
**629 Hungarian literals**, none of them errors and none of them saved notes: the country TABLE (113,
|
||||
not on the wire, not translated on purpose), the page-title literals slice 1 handles through
|
||||
`TitleKey`, `handler_debug.go` (R-574), the notifier's 27 wire messages (R-558), `funcmap.go`'s two
|
||||
un-overridden helpers (R-572), the R-570 producer, and the soft memory warning (R-575).
|
||||
**R-557 is CLOSED.** New row: **R-577**, the guest-share visitor's language.
|
||||
## 7. Row
|
||||
|
||||
**R-579** — the cache-buster gap: found, fixed and closed in this session, with the general form
|
||||
recorded (a template that loads a versioned asset without the version is invisible to every test that
|
||||
reads markup).
|
||||
|
||||
@@ -306,6 +306,9 @@ func renderI18nCase(t *testing.T, s *Server, lang string, c i18nCase) string {
|
||||
// is exactly what the first attempt at this release did, and what the diff caught.
|
||||
if i18nDirectTemplates[c.tmpl] {
|
||||
data["Lang"] = lang
|
||||
// The same asset data executeTemplateLang fills — one function, so the fixture cannot be a
|
||||
// picture of a page nobody serves (v0.255.0).
|
||||
s.addShellAssetData(data)
|
||||
// And WITHIN the direct-render set, two shapes again: /recovery is an AUTHENTICATED route, so
|
||||
// its globe writes the household's setting; /login and /claim are met with no session, so
|
||||
// theirs writes the visitor's cookie. The fixture has to be the one the real page serves.
|
||||
|
||||
@@ -220,6 +220,33 @@ func TestGlobeOnAnonymousShells(t *testing.T) {
|
||||
if !strings.Contains(got, `<html lang="en"`) {
|
||||
t.Error("the visitor's cookie did not decide the language")
|
||||
}
|
||||
// v0.255.0 — WHERE the globe sits, and whether the page can be styled at all.
|
||||
//
|
||||
// Both halves were real defects, seen on a browser: the stylesheet was requested with no
|
||||
// `?v=`, so a browser that had it cached from before v0.254.0 kept serving a file with no
|
||||
// .lang-globe rules in it and the globe rendered as a bare, unstyled <details> — a stray
|
||||
// triangle and two plain words. And even styled, it was pinned to the corner of the
|
||||
// VIEWPORT, outside the card, which reads as part of the browser rather than the page.
|
||||
if !strings.Contains(got, `href="/static/style.css?v=`) {
|
||||
t.Error("the stylesheet is requested without a version, so a cached copy from before " +
|
||||
"the globe existed keeps being served and the globe renders unstyled")
|
||||
}
|
||||
if strings.Contains(got, `href="/static/style.css?v="`) {
|
||||
t.Error("the cache-buster is EMPTY — that busts a cache once and never again")
|
||||
}
|
||||
cardAt := strings.Index(got, `class="login-card"`)
|
||||
globeAt := strings.Index(got, `class="shell-lang"`)
|
||||
if cardAt < 0 || globeAt < 0 {
|
||||
t.Fatal("card or globe missing from the page")
|
||||
}
|
||||
if globeAt < cardAt {
|
||||
t.Error("the globe is rendered BEFORE the card, so it floats outside it")
|
||||
}
|
||||
// …and at the END of the card: after the footer where one exists, last in the card where
|
||||
// none does (the recovery page has no footer paragraph).
|
||||
if foot := strings.Index(got, `class="login-footer"`); foot >= 0 && globeAt < foot {
|
||||
t.Error("the globe is above the footer; it belongs under it")
|
||||
}
|
||||
if got := s.settings.GetLanguage(); got != "hu" {
|
||||
t.Errorf("rendering the page changed the household's language to %q", got)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package web
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
@@ -412,6 +414,35 @@ func (s *Server) hasSession(r *http.Request) bool {
|
||||
return err == nil && s.isValidSession(c.Value)
|
||||
}
|
||||
|
||||
// addShellAssetData fills the cache-buster fields every page shell's stylesheet link uses.
|
||||
//
|
||||
// ONE function, called by executeTemplateLang AND by the parity harness, because a fixture rendered
|
||||
// through a different data path is a picture of a page nobody serves — which this release's own
|
||||
// predecessor got wrong twice. Idempotent: an existing Version is left alone, so a fixture case that
|
||||
// pins its own version keeps it.
|
||||
//
|
||||
// `AssetTag` is the buster for a page a STRANGER may open — the two guest share pages, reached by a
|
||||
// capability URL. `TestShareGuest_HeadersTilesNoAdminChrome` refuses the version string on those for a
|
||||
// reason worth keeping: telling anyone holding the link exactly which build is running is a gift to
|
||||
// somebody looking for a known fault. An opaque per-build tag busts the cache just as well.
|
||||
func (s *Server) addShellAssetData(data map[string]interface{}) {
|
||||
if data == nil {
|
||||
return
|
||||
}
|
||||
if _, ok := data["Version"]; !ok {
|
||||
data["Version"] = s.version
|
||||
}
|
||||
data["AssetTag"] = s.assetTag()
|
||||
}
|
||||
|
||||
// assetTag is an opaque per-build cache-buster: it changes when the version changes and discloses
|
||||
// nothing about it. Used by the pages a stranger can open; everywhere else the version itself is
|
||||
// already on the page and the tag would only be indirection.
|
||||
func (s *Server) assetTag() string {
|
||||
sum := sha256.Sum256([]byte("felhom-asset-tag-v1:" + s.version))
|
||||
return hex.EncodeToString(sum[:4])
|
||||
}
|
||||
|
||||
// HubPushStatusData holds hub push status for the monitoring page.
|
||||
type HubPushStatusData struct {
|
||||
LastAttempt time.Time
|
||||
@@ -915,6 +946,14 @@ func (s *Server) executeTemplateLang(w io.Writer, r *http.Request, name string,
|
||||
lang := s.langFor(r)
|
||||
if data != nil {
|
||||
data["Lang"] = lang
|
||||
// v0.255.0: the stylesheet cache-buster, set HERE rather than in each handler.
|
||||
//
|
||||
// Five shells loaded /static/style.css with no `?v=`, so a browser that had the file cached
|
||||
// kept serving the old one — and the v0.254.0 globe rendered as a bare, unstyled <details>
|
||||
// for anyone who had visited before. Three of the five did not carry `Version` in their data
|
||||
// at all, which is exactly how the next one would be forgotten: setting it at the single choke
|
||||
// point every shell renders through means a new shell cannot miss it.
|
||||
s.addShellAssetData(data)
|
||||
// v0.254.0: the globe, on a page rendered outside the dashboard chrome. WHICH FORM it posts to
|
||||
// depends on WHO is reading, and getting that wrong makes the globe do nothing:
|
||||
//
|
||||
|
||||
@@ -117,7 +117,10 @@ func testServer(t *testing.T) *Server {
|
||||
if err != nil {
|
||||
t.Fatalf("settings: %v", err)
|
||||
}
|
||||
return &Server{settings: sett, logger: lg, cfg: &config.Config{}}
|
||||
// A version, because v0.255.0 renders the stylesheet cache-buster from it and an empty `?v=`
|
||||
// would bake into a fixture as a URL that busts a cache exactly once and never again. Production
|
||||
// passes the real version to NewServer; this is the fixture's stand-in for it.
|
||||
return &Server{settings: sett, logger: lg, cfg: &config.Config{}, version: "test"}
|
||||
}
|
||||
|
||||
// SECURITY: a SYSTEM/BACKUP data-bearing refusal must surface the opsign command and perform NO
|
||||
|
||||
@@ -5,10 +5,9 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{if .IsReset}}{{T "claim.jelszo_visszaallitasa"}}{{else}}{{T "claim.a_szerver_beallitasa"}}{{end}} — Felhom</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v={{.Version}}">
|
||||
</head>
|
||||
<body class="login-body">
|
||||
<div class="shell-lang">{{template "lang_globe" .}}</div>
|
||||
<div class="login-card">
|
||||
<img src="/static/felhom-logo.svg" alt="Felhom.eu" class="login-logo">
|
||||
<h1 class="login-title">{{if .IsReset}}{{T "claim.jelszo"}} <span class="title-accent">{{T "claim.visszaallitasa"}}</span>{{else}}{{T "claim.a_szerver"}} <span class="title-accent">{{T "claim.beallitasa"}}</span>{{end}}</h1>
|
||||
@@ -59,6 +58,7 @@
|
||||
</form>
|
||||
|
||||
<p class="login-footer">{{T "claim.felhom_otthoni_szerver_kezeles_felhom"}}</p>
|
||||
<div class="shell-lang">{{template "lang_globe" .}}</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>{{T "launcher_share_password.inditopult"}}</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v={{.AssetTag}}">
|
||||
</head>
|
||||
<body class="guest-body guest-gate-body">
|
||||
<main class="guest-gate">
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>{{T "launcher_shared.inditopult"}}</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v={{.AssetTag}}">
|
||||
</head>
|
||||
<body class="guest-body">
|
||||
<main class="guest-content">
|
||||
|
||||
@@ -5,10 +5,9 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{T "login.bejelentkezes_felhom"}}</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v={{.Version}}">
|
||||
</head>
|
||||
<body class="login-body">
|
||||
<div class="shell-lang">{{template "lang_globe" .}}</div>
|
||||
<div class="login-card">
|
||||
<img src="/static/felhom-logo.svg?v={{.Version}}" alt="Felhom.eu" class="login-logo">
|
||||
<h1 class="login-title">{{T "login.otthoni"}} <span class="title-accent">{{T "login.vezerlopult"}}</span></h1>
|
||||
@@ -26,6 +25,7 @@
|
||||
</form>
|
||||
<p style="text-align:center;margin:0.75rem 0 0;font-size:0.85rem"><a href="/claim">{{T "login.elfelejtett_jelszo"}}</a></p>
|
||||
<p class="login-footer">{{T "login.felhom_otthoni_szerver_kezeles_felhom"}}</p>
|
||||
<div class="shell-lang">{{template "lang_globe" .}}</div>
|
||||
</div>
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>{{T "recovery.adatok_visszaszerzese_felhom"}}</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v={{.Version}}">
|
||||
</head>
|
||||
<body class="login-body">
|
||||
<div class="shell-lang">{{template "lang_globe" .}}</div>
|
||||
<div class="login-card" style="max-width:46rem">
|
||||
<img src="/static/felhom-logo.svg" alt="Felhom.eu" class="login-logo">
|
||||
|
||||
@@ -189,6 +188,7 @@
|
||||
</p>
|
||||
{{end}}
|
||||
{{end}}
|
||||
<div class="shell-lang">{{template "lang_globe" .}}</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -3676,9 +3676,9 @@ html::-webkit-scrollbar-track { background: var(--bg-0); }
|
||||
border-left: 2px solid var(--crit);
|
||||
}
|
||||
|
||||
/* i18n (v0.254.0): the globe on the pages a VISITOR meets — sign-in, claim, recovery. Those pages have
|
||||
their own shell and no sidebar, so the globe is pinned to the top-right corner of the viewport, the
|
||||
same place on all three. It posts to /lang, which sets a display-only cookie in that visitor's own
|
||||
browser and never the household's setting. */
|
||||
.shell-lang { position: absolute; top: 1rem; right: 1rem; z-index: 30; }
|
||||
.shell-lang .lang-globe-menu { bottom: auto; top: calc(100% + .35rem); left: auto; right: 0; transform: none; }
|
||||
/* i18n (v0.254.0, placed properly in v0.255.0): the globe on the pages outside the dashboard chrome —
|
||||
sign-in, claim, recovery. Those pages have their own shell and no sidebar.
|
||||
v0.255.0: it lives INSIDE the card, centred under the footer, and the menu opens UPWARD — which is
|
||||
the shared .lang-globe-menu rule, so this block adds no positioning of its own. It floated in the
|
||||
top-left of the viewport before, outside the card, which read as a stray browser control. */
|
||||
.shell-lang { display: flex; justify-content: center; margin-top: 1.5rem; }
|
||||
|
||||
@@ -5,16 +5,9 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Jelszó visszaállítása — Felhom</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v=test">
|
||||
</head>
|
||||
<body class="login-body">
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
<div class="login-card">
|
||||
<img src="/static/felhom-logo.svg" alt="Felhom.eu" class="login-logo">
|
||||
<h1 class="login-title">Jelszó <span class="title-accent">visszaállítása</span></h1>
|
||||
@@ -56,6 +49,13 @@
|
||||
|
||||
<p class="login-footer">Felhom — Otthoni szerver kezelés<br>
|
||||
<a href="https://felhom.eu" target="_blank">felhom.eu</a></p>
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -5,16 +5,9 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Jelszó visszaállítása — Felhom</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v=test">
|
||||
</head>
|
||||
<body class="login-body">
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
<div class="login-card">
|
||||
<img src="/static/felhom-logo.svg" alt="Felhom.eu" class="login-logo">
|
||||
<h1 class="login-title">Jelszó <span class="title-accent">visszaállítása</span></h1>
|
||||
@@ -35,6 +28,13 @@
|
||||
|
||||
<p class="login-footer">Felhom — Otthoni szerver kezelés<br>
|
||||
<a href="https://felhom.eu" target="_blank">felhom.eu</a></p>
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -5,16 +5,9 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>A szerver beállítása — Felhom</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v=test">
|
||||
</head>
|
||||
<body class="login-body">
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
<div class="login-card">
|
||||
<img src="/static/felhom-logo.svg" alt="Felhom.eu" class="login-logo">
|
||||
<h1 class="login-title">A szerver <span class="title-accent">beállítása</span></h1>
|
||||
@@ -56,6 +49,13 @@
|
||||
|
||||
<p class="login-footer">Felhom — Otthoni szerver kezelés<br>
|
||||
<a href="https://felhom.eu" target="_blank">felhom.eu</a></p>
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -5,16 +5,9 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>A szerver beállítása — Felhom</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v=test">
|
||||
</head>
|
||||
<body class="login-body">
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
<div class="login-card">
|
||||
<img src="/static/felhom-logo.svg" alt="Felhom.eu" class="login-logo">
|
||||
<h1 class="login-title">A szerver <span class="title-accent">beállítása</span></h1>
|
||||
@@ -35,6 +28,13 @@
|
||||
|
||||
<p class="login-footer">Felhom — Otthoni szerver kezelés<br>
|
||||
<a href="https://felhom.eu" target="_blank">felhom.eu</a></p>
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>Indítópult</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v=7da11d7a">
|
||||
</head>
|
||||
<body class="guest-body guest-gate-body">
|
||||
<main class="guest-gate">
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>Indítópult</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v=7da11d7a">
|
||||
</head>
|
||||
<body class="guest-body">
|
||||
<main class="guest-content">
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>Indítópult</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v=7da11d7a">
|
||||
</head>
|
||||
<body class="guest-body">
|
||||
<main class="guest-content">
|
||||
|
||||
+8
-8
@@ -5,16 +5,9 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Bejelentkezés — Felhom</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v=0.250.0">
|
||||
</head>
|
||||
<body class="login-body">
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
<div class="login-card">
|
||||
<img src="/static/felhom-logo.svg?v=0.250.0" alt="Felhom.eu" class="login-logo">
|
||||
<h1 class="login-title">Otthoni <span class="title-accent">vezérlőpult</span></h1>
|
||||
@@ -33,6 +26,13 @@
|
||||
<p style="text-align:center;margin:0.75rem 0 0;font-size:0.85rem"><a href="/claim">Elfelejtett jelszó</a></p>
|
||||
<p class="login-footer">Felhom — Otthoni szerver kezelés<br>
|
||||
<a href="https://felhom.eu" target="_blank">felhom.eu</a></p>
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/lang"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
</div>
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
@@ -6,16 +6,9 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>Adatok visszaszerzése — Felhom</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v=0.247.0">
|
||||
</head>
|
||||
<body class="login-body">
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
<div class="login-card" style="max-width:46rem">
|
||||
<img src="/static/felhom-logo.svg" alt="Felhom.eu" class="login-logo">
|
||||
|
||||
@@ -114,6 +107,13 @@
|
||||
</p>
|
||||
|
||||
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -6,16 +6,9 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>Adatok visszaszerzése — Felhom</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v=0.247.0">
|
||||
</head>
|
||||
<body class="login-body">
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
<div class="login-card" style="max-width:46rem">
|
||||
<img src="/static/felhom-logo.svg" alt="Felhom.eu" class="login-logo">
|
||||
|
||||
@@ -115,6 +108,13 @@
|
||||
</p>
|
||||
|
||||
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -6,16 +6,9 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>Adatok visszaszerzése — Felhom</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v=0.247.0">
|
||||
</head>
|
||||
<body class="login-body">
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
<div class="login-card" style="max-width:46rem">
|
||||
<img src="/static/felhom-logo.svg" alt="Felhom.eu" class="login-logo">
|
||||
|
||||
@@ -129,6 +122,13 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -6,16 +6,9 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>Adatok visszaszerzése — Felhom</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v=0.247.0">
|
||||
</head>
|
||||
<body class="login-body">
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
<div class="login-card" style="max-width:46rem">
|
||||
<img src="/static/felhom-logo.svg" alt="Felhom.eu" class="login-logo">
|
||||
|
||||
@@ -60,6 +53,13 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -6,16 +6,9 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>Adatok visszaszerzése — Felhom</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v=0.247.0">
|
||||
</head>
|
||||
<body class="login-body">
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
<div class="login-card" style="max-width:46rem">
|
||||
<img src="/static/felhom-logo.svg" alt="Felhom.eu" class="login-logo">
|
||||
|
||||
@@ -43,6 +36,13 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+8
-8
@@ -6,16 +6,9 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>Adatok visszaszerzése — Felhom</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v=0.247.0">
|
||||
</head>
|
||||
<body class="login-body">
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
<div class="login-card" style="max-width:46rem">
|
||||
<img src="/static/felhom-logo.svg" alt="Felhom.eu" class="login-logo">
|
||||
|
||||
@@ -39,6 +32,13 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+8
-8
@@ -6,16 +6,9 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>Adatok visszaszerzése — Felhom</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v=0.247.0">
|
||||
</head>
|
||||
<body class="login-body">
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
<div class="login-card" style="max-width:46rem">
|
||||
<img src="/static/felhom-logo.svg" alt="Felhom.eu" class="login-logo">
|
||||
|
||||
@@ -42,6 +35,13 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div class="shell-lang"><details class="lang-globe">
|
||||
<summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M2 12h20" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg></summary>
|
||||
<ul class="lang-globe-menu">
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="hu" lang="hu" class="lang-globe-item current" aria-current="true">Magyar</button></form></li>
|
||||
<li><form method="POST" action="/settings/language"><input type="hidden" name="_csrf" value="CSRF"><input type="hidden" name="back" value="/i18n-fixture"><button type="submit" name="lang" value="en" lang="en" class="lang-globe-item">English</button></form></li>
|
||||
</ul>
|
||||
</details></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user