diff --git a/CLAUDE.md b/CLAUDE.md index baa9cd5..9e41cf6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -112,8 +112,8 @@ Do not batch updates. The moment you finish editing a file, append the entry to - What was deleted and why — `file.js`, `file.css`, i18n keys ## i18n -- Added: `key1`, `key2` — 10 locales -- Removed: `oldKey1`, `oldKey2` — 10 locales +- Added: `key1`, `key2` — 11 locales +- Removed: `oldKey1`, `oldKey2` — 11 locales ``` Rules: @@ -649,7 +649,7 @@ Google real name (`user.displayName` from Firebase Auth) is saved to Firestore a --- ## i18n — workflow & key reference -All **10 locales** (en/fr/de/es/it/zh/pt/pt-pt/pl/ru) share the same key set. **Don't re-read the locale JSON files** — the full key list is in `docs/i18n-keys.md` (pointer below). The workflow (add keys, consistency check) stays here. +All **11 locales** (en/fr/de/es/it/zh/pt/pt-pt/pl/ru/nl) share the same key set. **Don't re-read the locale JSON files** — the full key list is in `docs/i18n-keys.md` (pointer below). The workflow (add keys, consistency check) stays here. ### Adding new keys — use the helper script **Never edit the 10 locale files by hand.** Use `npm run i18n:add` instead — it writes every locale in one shot, validates JSON, and falls back to the EN value when a translation is missing. @@ -690,7 +690,7 @@ a doc — or a file it describes — is staged. Run it by hand with `npm run doc | `llms.txt` "~N lines" | `renderer/inventory.js` | 15 % | | `llms.txt` CSS file count | `renderer/css/*.css` | exact | | `llms.txt` brand count **+ protocol table rows** | `renderer/printers/*/index.js` | exact | -| `llms.txt` "N keys × 10 locales" | `renderer/locales/en.json` | 2 % | +| `llms.txt` "N keys × 11 locales" | `renderer/locales/en.json` | 2 % | | `FEATURES.md` "current as of vX.Y.Z" | `package.json` | current, or previous patch | | Paths in README / llms.txt / CLAUDE.md / AGENT.md | the filesystem | must exist (templates + globs skipped) | | `llms.txt` Firestore map | `.collection("…")` calls in `renderer/inventory.js` | every collection written must be documented | @@ -705,7 +705,7 @@ A pre-commit hook runs `npm run i18n:check` automatically — the commit is bloc ```bash npm run i18n:check -# → "OK — 10 locales × N keys, all consistent." (exit 0) +# → "OK — 11 locales × N keys, all consistent." (exit 0) # or a per-file list of missing/extra/empty/type-mismatch issues (exit 1) ``` @@ -727,7 +727,7 @@ The full per-category key list (App/status, Settings, Account, Login, Credential - **UI/UX — be autonomous, apply these by default (don't wait to be told each tweak):** (1) **Declutter** — cut redundant chrome (a `»` tab AND an ✕; titles repeating visible context; obvious subtitles). (2) **Context over labels** — if a state is already visible (selected item highlighted), don't repeat it. (3) **Consistency** — matching components look/size/behave identically (same size collapsed vs expanded; side-cards stack + get `»` tabs like group/material; collapse animation mirrors expand). (4) **Smooth motion, never jumpy** — elements stay put and the container resizes around them (no `justify-content:center` snap); slide don't pop; on a swap the incoming card covers before the outgoing closes; animate labels (max-width/opacity), not `display:none`. (5) **Real icons sized with presence** — masked SVGs over dots/glyphs, consistent sizes, centred on both axes (mind flex `min-width:auto` + top-heavy SVGs). (6) **Show the active/selected state.** (7) **Help/secondary actions in context + light.** (8) **Tighten space** — kill dead gaps, stacked paddings, useless separators. (9) Prefer **shared/generic** CSS-JS over per-file repetition. Propose refinements proactively with a one-line rationale. *(Full version: memory `feedback-ui-ux-autonomy`.)* - **Language**: Conversation with the user is in French. All project content — code comments, commit messages, documentation, instructions — must be written in English. - **Brand voice (all user-facing copy)**: every string a user reads — UI labels, buttons, empty states, prompts, nudges, error messages, modals, AND the "What's New" notes (`data/whatsnew.json`) — uses a **playful, deadpan, second-degree voice, Discord-style** (witty, self-aware, talks to you like a mate) — **NOT** Burger-King-style (no aggressive/provocative/troll edge). Lead with the **user benefit** in plain words; **no technical jargon** (avoid "modal", "toggle", "side panel", "header", class names, "TestFlight"…); **never describe what doesn't exist** or our process ("no emoji", "we removed X", "fixed bug Y"). Keep the tone natural in **every locale**. This playful voice is **register 3** — for **in-app copy + What's New (`data/whatsnew.json`) ONLY**. It is one of **three distinct copy registers** (see [*Three copy registers*](#️-three-copy-registers--changelog--release-note--whats-new)): the **release note** (`data/release-notes/`, register 2) is BambuLab-style factual, and the **`CHANGELOG.md`** (register 1) is exhaustive & technical. Same change, three voices — never blur them, and never ship the technical changelog wording where the playful or the Bambu one belongs. *(Same rule applies to the mobile app — see its CLAUDE.md.)* -- **i18n**: always add all **10** translations (en/fr/de/es/it/zh/pt/pt-pt/pl/ru) in the same edit batch. **Use `npm run i18n:add` — do NOT hand-edit the locale JSON files.** See the *Adding new keys* section above for syntax. +- **i18n**: always add all **11** translations (en/fr/de/es/it/zh/pt/pt-pt/pl/ru/nl) in the same edit batch. **Use `npm run i18n:add` — do NOT hand-edit the locale JSON files.** See the *Adding new keys* section above for syntax. - **Commits**: no `Co-Authored-By` line. **Never commit without explicit user instruction** — make the change, then stop and wait for the order to commit. - **Naming — clear human semantics first**: every name you introduce (Firestore collection/field, function, variable, CSS class, IPC channel, config key) must read plainly to a human and say what it *is*, so the meaning is obvious without chasing the code. Prefer a self-describing name over a clever/encoded one — e.g. a collection `rfidList` over `rfidChips`, a boolean `rfidListed`/`rfidBackup` over a multi-state `rfidChip: 1|2`. **Avoid encoding several states into one cryptic value** (magic numbers, packed flags): split into separate, well-named booleans/fields. **Don't store what you can derive** — drop redundant fields when an existing one already implies the answer (e.g. no `startState`/type field when the presence of a `backup` already means "TigerTag+"). When a name turns out unclear, rename it (and its doc/schema) rather than letting it stand. Clear semantics now prevent compounding complexity later. - **JS**: all logic lives in `inventory.js`. Do not inline JS in `inventory.html`. diff --git a/README.md b/README.md index 0426eb9..7e7dafd 100644 --- a/README.md +++ b/README.md @@ -234,7 +234,7 @@ A QR code to download the mobile app is always accessible in the sidebar. ### 🌍 Accounts & i18n - Multi-account — switch between multiple TigerTag accounts -- **10 locales** — EN · FR · DE · ES · IT · PL · PT (Brasil) · PT (Portugal) · 中文 · RU +- **11 locales** — EN · FR · DE · ES · IT · PL · PT (Brasil) · PT (Portugal) · 中文 · RU · NL - Per-account language preference synced with Firestore - Google sign-in via loopback OAuth (RFC 8252 + PKCE) — Touch ID / passkey native support @@ -331,7 +331,7 @@ Built artifacts go to `dist/` (git-ignored). UI strings live in `renderer/locales/.json`. Never edit the 10 locale files by hand — use the helper instead: ```bash -# Add a new key across all 10 locales +# Add a new key across all 11 locales npm run i18n:add -- myKey en="Hello" fr="Bonjour" de="Hallo" \ es="Hola" it="Ciao" zh="你好" pt="Olá" pt-pt="Olá" pl="Cześć" ru="Привет" @@ -383,7 +383,7 @@ TigerTag-Studio-Manager/ │ ├── CODEMAP.md # Line-range index for inventory.js (read first, grep last) │ ├── firebase.js # Firebase init (public config) │ ├── css/ # 10 themed files, loaded in order (00-base → 10-settings → … → 70-detail-misc) -│ ├── locales/ # i18n JSON — en fr de es it zh pt pt-pt pl ru (10 locales, edit via npm run i18n:add) +│ ├── locales/ # i18n JSON — en fr de es it zh pt pt-pt pl ru nl (11 locales, edit via npm run i18n:add) │ ├── IoT/ # Extracted device modules (own CSS inside each) │ │ ├── tigerscale/ # TigerScale — Firestore subscription, panel, health tick │ │ └── td1s/ # TD1S color/TD sensor engine + TD/Color edit modals @@ -423,7 +423,7 @@ TigerTag-Studio-Manager/ 4. **Run**: `npm start` to test locally 5. **Open a Pull Request** -Guidelines: keep the renderer vanilla (no React/Vue), add i18n strings with `npm run i18n:add` (all 10 locales), don't commit `node_modules/` or `dist/`. +Guidelines: keep the renderer vanilla (no React/Vue), add i18n strings with `npm run i18n:add` (all 11 locales), don't commit `node_modules/` or `dist/`. **Reporting issues** — use [GitHub Issues](https://github.com/TigerTag-Project/TigerTag-Studio-Manager/issues). Use **Settings → Debug → Report a problem** in the app to copy a self-contained diagnostic report (version, platform, last 50 errors) to paste into your issue. diff --git a/docs/i18n-keys.md b/docs/i18n-keys.md index 35d2d75..dae3bb6 100644 --- a/docs/i18n-keys.md +++ b/docs/i18n-keys.md @@ -1,6 +1,6 @@ # i18n keys — complete reference (TigerTag Studio) -> Extracted from `CLAUDE.md` to keep the always-loaded instructions lean. **Read this on demand instead of re-reading the locale JSON files.** All **10 locales** (en/fr/de/es/it/zh/pt/pt-pt/pl/ru) have every key below. To add/change keys use `npm run i18n:add` (never hand-edit the locale files) — see CLAUDE.md → *i18n — workflow*. +> Extracted from `CLAUDE.md` to keep the always-loaded instructions lean. **Read this on demand instead of re-reading the locale JSON files.** All **11 locales** (en/fr/de/es/it/zh/pt/pt-pt/pl/ru/nl) have every key below. To add/change keys use `npm run i18n:add` (never hand-edit the locale files) — see CLAUDE.md → *i18n — workflow*. ### App / status | Key | Purpose | @@ -243,4 +243,4 @@ | `notifPaxxTitle` | Paxx firmware release notice title (Snapmaker owners) | | `notifPaxxText {{version}}` | Paxx release notice body — click opens the .bin download | -> ⚠️ This table is a snapshot and can drift as keys are added. The authoritative key set is the locale files themselves; `npm run i18n:check` is the source of truth for "do all 10 locales agree". When you add keys via `npm run i18n:add`, append them to the relevant section here too. +> ⚠️ This table is a snapshot and can drift as keys are added. The authoritative key set is the locale files themselves; `npm run i18n:check` is the source of truth for "do all 11 locales agree". When you add keys via `npm run i18n:add`, append them to the relevant section here too. diff --git a/llms.txt b/llms.txt index 8da8e8d..541ab64 100644 --- a/llms.txt +++ b/llms.txt @@ -21,7 +21,7 @@ Current version: **2.27.3** — macOS (Intel + Apple Silicon, signed & notarized - **Printer integrations**: `renderer/printers//index.js` — one file per brand, loaded dynamically - **IoT sensors**: `renderer/IoT/td1s/` (TD1S color sensor), `renderer/IoT/tigerscale/` (TigerScale ESP32) - **CSS**: `renderer/css/00-base.css` → `70-detail-misc.css` (10 files, loaded in numeric order via `` tags) -- **i18n**: `renderer/locales/` — 10 JSON files (en/fr/de/es/it/zh/pt/pt-pt/pl/ru), managed via `npm run i18n:add` +- **i18n**: `renderer/locales/` — 11 JSON files (en/fr/de/es/it/zh/pt/pt-pt/pl/ru/nl), managed via `npm run i18n:add` - **TigerTag SDK**: `@tigertag/sdk` npm package — parse, verify, encode TigerTag NTAG chips (pages 4–39, 144 bytes, blockSize=4) ## Key source files @@ -251,7 +251,7 @@ All brands: printer discovery (mDNS + port scan + manual IP), filament edit per npm run i18n:add -- myKey --after existingKey en="..." fr="..." de="..." es="..." it="..." zh="..." pt="..." pt-pt="..." pl="..." ru="..." npm run i18n:check # validates consistency (also runs as pre-commit hook) ``` -1523 keys × 10 locales as of v2.27.2. +1523 keys × 11 locales as of v2.27.4. ## CSS conventions @@ -298,7 +298,7 @@ npm run i18n:check # validates consistency (also runs as pre-commit hook) ```bash npm start # dev (no bundler) -npm run i18n:check # validate all 10 locales +npm run i18n:check # validate all 11 locales git tag v2.13.0 && git push --tags # triggers CI: parallel build macOS/Windows/Linux → GitHub Release ``` diff --git a/renderer/inventory.html b/renderer/inventory.html index 130291a..a89f183 100644 --- a/renderer/inventory.html +++ b/renderer/inventory.html @@ -2027,6 +2027,7 @@

Language & region

Português (PT) + diff --git a/renderer/inventory.js b/renderer/inventory.js index 6b26e35..e4e5f63 100644 --- a/renderer/inventory.js +++ b/renderer/inventory.js @@ -1445,7 +1445,7 @@ import { elgFanStep } from './printers/elegoo/widget_control.js'; /* ── lookups ── */ async function loadLocales() { - await Promise.all(["en", "fr", "de", "es", "it", "zh", "pt", "pt-pt", "pl", "ru"].map(async lang => { + await Promise.all(["en", "fr", "de", "es", "it", "zh", "pt", "pt-pt", "pl", "ru", "nl"].map(async lang => { try { const r = await fetch(`locales/${lang}.json`); if (r.ok) state.i18n[lang] = await r.json(); @@ -33929,7 +33929,7 @@ import { elgFanStep } from './printers/elegoo/widget_control.js'; ["en", "English"], ["fr", "Français"], ["de", "Deutsch"], ["es", "Español"], ["it", "Italiano"], ["zh", "中文"], ["pt", "Português (Brasil)"], ["pt-pt", "Português (Portugal)"], ["pl", "Polski"], - ["ru", "Русский"], + ["ru", "Русский"], ["nl", "Nederlands"], ]; // An imported photo ALWAYS wins as the avatar; the generated colour is only // the fallback shown when there is no photo. So shuffling a colour never hides diff --git a/renderer/locales/nl.json b/renderer/locales/nl.json new file mode 100644 index 0000000..4419b9e --- /dev/null +++ b/renderer/locales/nl.json @@ -0,0 +1,1606 @@ +{ + "appSubtitle": "Bekijk en beheer je filamentspoelen", + "backendIdle": "Server: inactief", + "backendOk": "Server: ok", + "backendErr": "Server: {{n}}", + "backendOffline": "Server: offline", + "rfidConnected": "NFC: {{name}}", + "rfidNoReader": "TigerPOD niet verbonden", + "rfidScanned": "NFC: {{uid}}", + "rfidNotFound": "NFC gescand: {{uid}} — spoel niet gevonden in huidige inventaris.", + "td1sConnected": "TD1S: {{name}}", + "td1sDisconnected": "TD1S: niet verbonden", + "td1sScanned": "TD1S: {{td}}", + "td1sNotFound": "TD1S-scan: {{td}} — spoel niet gevonden in inventaris.", + "welcomeBack": [ + "Welkom terug,", + "Leuk je te zien,", + "Zullen we,", + "Klaar om te printen,", + "✨ Hé, fijn dat je er bent," + ], + "githubBtn": "GitHub", + "makerWorldBtn": "3D-bestanden", + "discordBtn": "Discord", + "coffeeBtn": "Trakteer me op koffie", + "shopBtn": "Winkel", + "wikiBtn": "Wiki", + "mobileApp": "TigerTag mobiele apps", + "mobileAppShort": "Apps", + "mobileScan": "Scan om de app te krijgen", + "settingsOpenBtn": "Instellingen", + "settingsTitle": "Instellingen", + "stgUpdatesTitle": "Updates", + "stgThemeRow": "Thema", + "stgThemeDark": "Donker", + "stgThemeLight": "Licht", + "stgDataTitle": "Gegevens", + "stgDataHelp": "Exporteer je inventaris lokaal als JSON, of kopieer de openbare API-URL (met je toegangssleutel erin) zodat een script of ander apparaat hem op afstand kan ophalen.", + "stgResyncInv": "Inventaris opnieuw synchroniseren", + "stgGroupInvTitle": "Identieke spoelen groeperen", + "stgGroupInvSub": "Identieke spoelen samenvoegen tot één regel", + "stgToolsTitle": "Hulpmiddelen", + "stgToolsHelp": "Diagnose- en probleemoplossingstools.", + "stgCatalogResync": "Catalogus opnieuw synchroniseren", + "stgCatalogSyncedAgo": "{{n}} producten, bijgewerkt {{ago}}", + "stgCatalogNeverSynced": "Nog niet gedownload — komt binnen zodra je Zoeken opent.", + "stgCopyApiUrl": "API-URL kopiëren", + "stgCopyApiUrlOk": "Gekopieerd — houd deze URL privé; iedereen die hem heeft, kan je inventaris lezen.", + "stgCopyApiUrlNoKey": "Toegangssleutel nog niet geladen — probeer het zo nog eens.", + "stgCopyApiUrlErr": "Kopiëren mislukt", + "stgCopyApiUrlGenerating": "URL genereren…", + "settingsAccount": "Accounts", + "settingsData": "Gegevens & export", + "settingsLang": "Taal", + "settingsDebug": "Debug", + "btnManageProfiles": "Profielen beheren", + "changeAvatar": "Foto wijzigen", + "settingsColor": "Kleur", + "settingsSave": "Opslaan & herladen", + "addAccountSave": "Toevoegen & laden", + "addAccountLabel": "Account toevoegen", + "editAccountTitle": "Account bewerken", + "btnSignIn": "Inloggen", + "addAccountAuthError": "Ongeldig e-mailadres of wachtwoord. Controleer je gegevens.", + "loginGoogle": "Doorgaan met Google", + "loginOr": "of", + "loginEmailPlaceholder": "E-mailadres", + "loginPasswordPlaceholder": "Wachtwoord", + "settingsApiLink": "URL voor inventarisexport", + "settingsExport": "↓ JSON downloaden", + "settingsCopied": "Gekopieerd!", + "debugOpenBtn": "Debugpaneel openen", + "fsExplorerOpenBtn": "Firestore-verkenner openen", + "btnRefresh": "Vernieuwen", + "btnSwitchAccount": "Account wisselen", + "noAccounts": "Nog geen account. Zullen we er een maken?", + "accountActive": "Actief", + "btnActivate": "Wisselen", + "btnDeleteAccount": "Account verwijderen", + "btnEditAccount": "Account bewerken", + "btnDisconnect": "Loskoppelen", + "btnEditApiKey": "API-sleutel bewerken", + "btnUpdateApiKey": "Verifiëren & synchroniseren", + "cancelAddAccount": "Annuleren", + "otherAccounts": "Andere accounts", + "confirmDeleteAccount": "Dit account en alle lokale gegevens ervan verwijderen?", + "delModalTitle": "Dit account uitloggen?", + "delModalWarn": "Dit account verlaat dit apparaat — niets definitiefs, kom terug wanneer je wilt.", + "cancelLabel": "Annuleren", + "credTitle": "Inloggegevens", + "credEmail": "E-mail", + "credApiKey": "API-sleutel", + "credStatus": "Status", + "statusUntested": "niet getest", + "statusValid": "geldig", + "statusInvalid": "ongeldig", + "statusChecking": "controleren…", + "btnLoadInv": "Inventaris laden", + "btnTestKey": "API-sleutel testen", + "btnClearSaved": "Opgeslagen gegevens wissen", + "invTitle": "Inventaris", + "btnViewTable": "Tabel", + "btnViewGrid": "Raster", + "invGroupToggle": "Groeperen", + "invGroupCount": "{{n}} spoelen", + "invGroupOn": "Identieke spoelen gegroepeerd", + "invGroupOff": "Spoelen apart tonen", + "btnShowDeleted": "Verwijderde tonen", + "btnHideDeleted": "Verwijderde verbergen", + "btnExport": "↓ JSON", + "addProductBtn": "Materiaal", + "matSourceTitle": "Materiaal toevoegen", + "matSourceSub": "Twee manieren — kies wat je hebt.", + "matSourceCatalogue": "Uit catalogus", + "matSourceCatalogueHint": "Zoek het echte product — alles wordt voor je ingevuld", + "matSourceManual": "Handmatig", + "matSourceManualHint": "Niet in de catalogus? Vul het zelf in", + "addProductTitle": "Product toevoegen", + "addProductSub": "Dezelfde velden als op een TigerTag-chip — nu opgeslagen in de cloud, klaar om later op een chip te programmeren.", + "addProductBrandLbl": "Merk", + "addProductMaterialLbl": "Materiaal", + "addProductTypeLbl": "Type", + "addProductAspect1Lbl": "Uiterlijk 1", + "addProductAspect2Lbl": "Uiterlijk 2", + "addProductDiameterLbl": "Diameter (mm)", + "addProductWeightLbl": "Gewicht (g)", + "addProductUnitLbl": "Eenheid", + "addProductTdLbl": "TD (HueForge)", + "addProductMessageLbl": "Bericht (optioneel)", + "addProductPrintPresetsLbl": "Printvoorinstellingen", + "addProductNozzleMinLbl": "Min. nozzle (°C)", + "addProductNozzleMaxLbl": "Max. nozzle (°C)", + "addProductBedMinLbl": "Min. bed (°C)", + "addProductBedMaxLbl": "Max. bed (°C)", + "addProductDryTempLbl": "Droogtemp. (°C)", + "addProductDryTimeLbl": "Droogtijd (u)", + "addProductAdvancedLbl": "Geavanceerde instellingen", + "addProductRfidDataLbl": "TigerData", + "addProductColorCustom": "Aangepaste kleur", + "addProductColorPickTitle": "Kies een kleur", + "addProductColorHexLbl": "Hex", + "addProductColorOsPickerBtn": "Systeem-kleurkiezer openen", + "addProductColorApplyBtn": "Toepassen", + "addProductSelectColor": "Kleur selecteren", + "addProductDualLink": "Dubbele NFC", + "addProductNozzleTemp": "Nozzletemp.", + "addProductDrying": "Drogen", + "addProductBedTemp": "Bedtemp.", + "addProductNozzleMinShort": "Min", + "addProductNozzleMaxShort": "Max", + "addProductBedMinShort": "Min", + "addProductBedMaxShort": "Max", + "addProductDryTempShort": "Temp", + "addProductDryTimeShort": "Tijd", + "addProductMake": "Merk", + "addProductBrandSearchPh": "Merken zoeken…", + "addProductBrandFavorites": "Favorieten", + "addProductBrandAll": "Alle merken", + "addProductBrandFav": "Favoriet", + "addProductBrandUnfav": "Favoriet verwijderen", + "addProductBrandNoMatch": "Geen merk gevonden", + "addProductMaterialSearchPh": "Materialen zoeken…", + "addProductMaterialAll": "Alle materialen", + "addProductMaterialFav": "Favoriet", + "addProductMaterialUnfav": "Favoriet verwijderen", + "addProductMaterialNoMatch": "Geen materiaal gevonden", + "addProductColorLbl": "Kleur", + "addProductColorNamePh": "Kleurnaam (optioneel)", + "addProductCapacityLbl": "Capaciteit (g)", + "addProductSave": "Toevoegen", + "addProductOk": "Spoel toegevoegd", + "addProductErrMissing": "Kies een merk en materiaal.", + "addProductErrCapacity": "Capaciteit moet minstens 1 g zijn.", + "addProductErrMissingTemp": "Vul alle temperatuurvelden in.", + "addProductErrAspectSame": "Uiterlijk 1 en Uiterlijk 2 moeten verschillend zijn.", + "addProductErrSave": "Opslaan mislukt:", + "searchPlaceholder": "Zoek materiaal, merk, kleur, UID, SKU, streepjescode…", + "searchPlaceholderPrinter": "Zoek printer, merk, model, IP…", + "noInventory": "Hier valt nog niets te bikken…", + "noMatch": "Geen spoel komt overeen met je zoekopdracht. Ze verstoppen zich goed.", + "statActive": "Spoelen", + "statPlus": "TigerTag+", + "statDiy": "TigerTag", + "statTotal": "Voorraad", + "statValue": "Voorraadwaarde", + "statActiveMini": "Spoelen", + "statPlusMini": "TigerTag+", + "statDiyMini": "TigerTag", + "statTotalMini": "Voorraad", + "statValueMini": "Waarde", + "thUid": "UID", + "thType": "Type", + "thMaterial": "Materiaal", + "thBrand": "Merk", + "thSeries": "Serie", + "thColor": "Kleur", + "thPrice": "Prijs", + "thMinQty": "Min. aantal", + "thName": "Naam", + "thModel": "Model", + "thStatus": "Status", + "thJob": "Taak", + "thWeight": "Gewicht", + "thCapacity": "Capaciteit", + "thUpdated": "Bijgewerkt", + "debugLabel": "Debug", + "debugSubtitle": " — laatste API-verzoek & -antwoord", + "debugNoReqs": "Nog geen verzoeken.", + "sectionColors": { + "one": "Kleur", + "other": "Kleuren" + }, + "sectionPrint": "Printinstellingen", + "sectionWeight": "Gewicht", + "sectionLinks": "Documenten & links", + "customImgUrl": "URL van productafbeelding", + "customImgUrlPlaceholder": "https://…", + "customImgUrlSave": "Opslaan", + "sectionContainer": "Container / spoel", + "sectionDetails": "Details", + "sectionRaw": "Ruwe JSON — spoelgegevens", + "lbNozzle": "Nozzle", + "lbBed": "Bed", + "lbDryTemp": "Droogtemp.", + "lbDryTime": "Droogtijd", + "lbDensity": "Dichtheid", + "weightTotal": "{{cap}} g totaal", + "weightContainer": "Container: {{cw}} g", + "weightErr": "{{r}}", + "weightErrComputed": " · berekend: {{c}} g", + "loadedSpools": { + "one": "1 spoel geladen.", + "other": "{{n}} spoelen geladen." + }, + "invError": "Inventarisfout: {{r}}", + "invalidKey": "Ongeldig: {{r}}", + "networkError": "Netwerkfout", + "enterNumeric": "Voer een numeriek gewicht in.", + "btnUpdate": "Bijwerken", + "btnSave": "Opslaan", + "btnEditManually": "✎ Handmatig bewerken", + "wbModeNet": "Netto", + "wbModeGross": "Weegschaal", + "wbModeNetTitle": "Netto filamentgewicht", + "wbModeGrossTitle": "Weegschaalwaarde (filament + container)", + "wbModeHintGross": "= {{net}} g netto (container: {{cw}} g)", + "wbModeHintNoContainer": "Geen container ingesteld — netto = weegschaalwaarde", + "btnCloseManual": "✕ Sluiten", + "rawScaleLabel": "▸ Ruwe weegschaalwaarde gebruiken (met container)", + "rawScaleHint": "Weeg spoel + container op de weegschaal — de server trekt het containergewicht eraf.", + "linkYt": "▶ YouTube", + "linkVideo": "▶ Video bekijken", + "linkFood": "Voedselveilig", + "detUid": "UID", + "detProductId": "Product-ID", + "detType": "Type", + "detSeries": "Serie", + "detBrand": "Merk", + "detMaterial": "Materiaal", + "detDiameter": "Diameter", + "detColor": "Kleur", + "detMeasure": "Hoeveelheid", + "detTagType": "Type tag", + "detSku": "SKU", + "detBarcode": "Streepjescode", + "detContainer": "Container", + "detTwin": "Dubbele NFC", + "detUpdated": "Bijgewerkt", + "detManufactured": "Geproduceerd", + "badgeRefill": "♻ Navulling", + "badgeRecycled": "Gerecycled", + "badgeFilled": "◈ Gevuld", + "badgeDeleted": "Verwijderd", + "updateDownloading": "Update beschikbaar", + "updateDownloadingSub": "downloaden…", + "updateReady": "Update klaar!", + "updateReadySub": "Herstart om bij te werken.", + "btnRestartUpdate": "Herstarten", + "twinBadge": "2 x NFC", + "gpAdded": "Toegevoegd {{ago}}", + "twinTitle": "Spoel met 2 gekoppelde NFC-chips", + "twinTabThis": "Deze tag", + "twinTabTwin": "Gekoppelde tag", + "twinLinkAction": "Tweede NFC-chip koppelen", + "twinLinkPickerTitle": "Kies de bijpassende tag", + "twinLinkPickerSub": "Zelfde merk, materiaal, type en kleur als deze spoel.", + "twinLinkEmpty": "Geen geschikte spoel om te koppelen.", + "twinLinkAlready": "NFC-chips gekoppeld", + "twinLinkUnlink": "Ontkoppelen", + "twinLinkUnlinkHint": "Verbreekt de koppeling met de gekoppelde chip (alleen voor debug).", + "toolboxTitle": "Gereedschap", + "ttagExport": ".ttag exporteren", + "ttagExportTip": "Bewaar dit materiaal in een bestand dat je zelf beheert — werkt ook als de cloud even een dutje doet. Gekoppelde spoelen reizen samen.", + "ttagExportOk": "✓ Back-up gemaakt", + "ttagCloudBlocked": "Verbind opnieuw om af te ronden", + "ttagImportBtn": ".ttag importeren", + "ttagImportTitle": "TigerData importeren", + "ttagImportSub": "Bekijk wat erin zit voordat het in je inventaris terechtkomt", + "ttagAcceptRestore": "Herstellen naar mijn inventaris", + "ttagAcceptImport": "Toevoegen aan mijn inventaris", + "ttagWorking": "Bezig…", + "ttagDone": "Klaar", + "ttagClose": "Sluiten", + "ttagErrNotFile": "Dit is geen TigerTag-back-upbestand.", + "ttagErrNewer": "Dit .ttag-bestand is gemaakt met een nieuwere versie van de app. Werk bij om het te openen.", + "ttagErrEmpty": "Dit .ttag-bestand bevat geen materialen.", + "ttagModeRestore": "Je eigen back-up — alles komt precies terug zoals het was.", + "ttagModeImport": "Andermans back-up — deze komen binnen als nieuwe kopieën die van jou zijn, zonder chip te claimen.", + "ttagSummaryRecords": "{{n}} materialen · {{r}} records", + "ttagImportErr": "Kon niet alles wegschrijven — er is niets half opgeslagen. Probeer het opnieuw.", + "ttagSummary": { + "one": "{{n}} materiaal", + "other": "{{n}} materialen" + }, + "ttagImportOk": { + "one": "{{n}} materiaal toegevoegd", + "other": "{{n}} materialen toegevoegd" + }, + "burnRfidBtn": "NFC branden", + "toolRefreshApi": "Vernieuwen vanaf API", + "toolRefreshApiLoading": "Vernieuwen…", + "toolRefreshApiSuccess": "Gegevens bijgewerkt vanuit catalogus", + "toolRefreshApiError": "API-vernieuwing mislukt", + "toolRefreshApiNoChange": "Geen nieuwe gegevens van API", + "upgradeToPlusBanner": "Upgraden naar TigerTag+", + "upgradeToPlusAction": "Product-ID invoeren", + "upgradeToPlusInputPlaceholder": "Product-ID (bijv. 60)", + "upgradeToPlusCheck": "Controleren", + "upgradeToPlusChecking": "Controleren…", + "upgradeToPlusNotFound": "Product niet gevonden", + "upgradeToPlusConvert": "Omzetten naar TigerTag+", + "upgradeToPlusSuccess": "Spoel omgezet naar TigerTag+!", + "upgradeToPlusHelpTip": "Hoe vind je de product-ID", + "upgradeToPlusListTip": "Bekijk de TigerTag+-materiaallijst", + "encodeCloudBtn": "Chip programmeren", + "cloudNotEncoded": "NFC branden", + "tigerPodDiscover": "Bouw een TigerPOD →", + "encodeCloudInProgress": "Schrijven…", + "encodeCloudError": "Schrijven mislukt", + "burnRfidSuccess": "Geschreven naar {{n}} lezer(s) ✓", + "burnRfidError": "{{ok}}/{{total}} geschreven — controleer lezer", + "toolMeasureColor": "Kleur scannen", + "toolMeasureTd": "TD scannen", + "toolDuplicate": "Dupliceren", + "toolDuplicateTip": "Voegt nog een exemplaar van dit materiaal toe als TigerData — een digitale spoel, geen chip nodig.", + "toolDuplicateOk": "Gedupliceerd ×{{n}}", + "toolDuplicateCount": "Aantal kopieën", + "msgEditTip": "Klik om de notitie te bewerken", + "msgEditAdd": "Notitie toevoegen", + "toolClearTd": "TD-waarde wissen", + "toolRemoveFromRack": "Van rek verwijderen", + "agoNow": "zojuist", + "agoMin": { + "one": "{{n}} min geleden", + "other": "{{n}} min geleden" + }, + "agoHour": { + "one": "{{n}} u geleden", + "other": "{{n}} u geleden" + }, + "agoDay": { + "one": "{{n}} d geleden", + "other": "{{n}} d geleden" + }, + "agoMonth": { + "one": "{{n}} mnd geleden", + "other": "{{n}} mnd geleden" + }, + "agoYear": { + "one": "{{n}} j geleden", + "other": "{{n}} j geleden" + }, + "signinTagline": "Elke spoel die je hebt, gewogen, gesorteerd en onmogelijk om kwijt te raken.", + "signinFeatScan": "Tik een tag aan, de spoel registreert zichzelf", + "signinFeatPrinters": "Je printers melden zich live", + "signinFeatShare": "Deel je voorraad en verlanglijstjes met vrienden", + "loginForgotPassword": "Wachtwoord vergeten?", + "loginRememberMe": "Ingelogd blijven", + "loginNoAccount": "Nog geen account?", + "loginCreateAccount": "Account aanmaken", + "loginHaveAccount": "Al een account?", + "loginConfirmPasswordPlaceholder": "Bevestig wachtwoord", + "loginResetSent": "Controleer je inbox — resetlink verzonden!", + "loginPasswordMismatch": "Wachtwoorden komen niet overeen.", + "loginPasswordTooShort": "Wachtwoord moet minstens 6 tekens bevatten.", + "loginAccountCreated": "Account aangemaakt! Je wordt ingelogd…", + "loginVerifyEmailSent": "Bijna klaar! We hebben een link gestuurd naar {{email}} — tik erop om je account te activeren en log daarna opnieuw in.", + "loginEmailNotVerified": "Je e-mailadres is nog niet bevestigd. Open de link die we stuurden om je account te ontgrendelen.", + "loginResendVerif": "E-mail opnieuw versturen", + "loginEmailInUse": "Dit e-mailadres is al geregistreerd.", + "invLoading": "Je spoelen uitpakken…", + "loadingGeneric": "Momentje…", + "loadingFun1": "De spoelen wakker maken…", + "loadingFun2": "Het bed opwarmen…", + "loadingFun3": "Tijd voor koffie?", + "loadingFun4": "Bijna klaar, beloofd…", + "containerPickerTitle": "Kies een container", + "cpEditWeight": "Dit gewicht corrigeren", + "cpWeightEdited": "van jou", + "cpResetWeight": "Catalogusgewicht herstellen", + "cwModalTitle": "Containergewicht kalibreren", + "cwModalSub": "Zo weten we precies hoeveel filament er nog over is.", + "cwWeightLabel": "Gewicht van lege container", + "cwScaleHint": "Een precieze weegschaal geeft het beste resultaat", + "cwCatalogueLabel": "Catalogusaarde", + "cwCatalogueSub": "Standaard met de app meegeleverd", + "cwYoursLabel": "Jouw kalibratie", + "cwYoursSub": "Gebruikt voor elke spoel in deze container", + "cwSaveBtn": "Kalibratie opslaan", + "cwResetBtn": "Terug naar catalogus", + "cwHowTitle": "Hoe te meten", + "cwStepSpool": "Lege spoel", + "cwStepCore": "Houd de kartonnen kern erin", + "cwStepScale": "Leg alles op de weegschaal", + "cwStepScaleSolo": "Leg het op de weegschaal", + "btnChangeContainer": "Wijzigen", + "cwEditWeight": "Containergewicht bewerken", + "displayNameLabel": "Weergavenaam", + "eacPanelTitle": "Mijn profiel", + "eacGroupAppearance": "Weergave", + "eacGroupRegion": "Taal & regio", + "eacGroupAdvanced": "Geavanceerd", + "avatarPictureLabel": "Profielfoto", + "avatarChangeOpt": "Avatar wijzigen", + "avatarRemoveOpt": "Avatar verwijderen", + "avatarCropTitle": "Afbeelding bewerken", + "avatarCropReset": "Resetten", + "avatarCropCancel": "Annuleren", + "avatarCropApply": "Toepassen", + "avatarCropRotate": "90° draaien", + "avatarPickBtn": "Afbeelding importeren", + "avatarRemoveBtn": "Verwijderen", + "avatarUploading": "Uploaden…", + "avatarUploadOk": "Foto bijgewerkt", + "avatarUploadFailed": "Uploaden mislukt", + "avatarTooLarge": "Afbeelding te groot (max. 500 KB na verkleinen)", + "avatarRemoving": "Verwijderen…", + "avatarRemoveOk": "Foto verwijderd", + "avatarRemoveFailed": "Kon niet verwijderen", + "tdEditTitle": "TD bijwerken", + "tdEditConnectMsg": "Sluit je TD1S-sensor via USB aan en verwijder filament", + "tdEditWaitMsg": "Plaats filament in de TD1S-sensor…", + "tdEditSaveBtn": "Opslaan", + "tdNotSet": "Toevoegen", + "orLabel": "of", + "tdConnectTitle": "TD1S-sensor", + "tdConnectMsg": "Sluit je TD1S-sensor via USB aan", + "td1sNotDetected": "TD1S: niet gedetecteerd", + "td1sDetected": "TD1S: verbonden", + "tdEditScannedMsg": "✓ Scan voltooid", + "colorEditTitle": "Kleur & TD-waarde instellen", + "btnTdOnly": "Alleen TD", + "btnColorOnly": "Alleen kleur", + "btnSaveAll": "Alles", + "chipPendingHint": "NFC bijwerken", + "btnChipDone": "Bijgewerkt", + "invEmptyTitle": "Tijd om je filamentspoelen te scannen!", + "invEmptyText": "Pak de TigerTag-app, scan je spoelen en zie je inventaris tot leven komen. Kost 10 seconden per spoel — we hebben het gemeten.", + "invEmptyMobileSub": "Scan om de app te krijgen", + "invStorePublic": "Openbare release", + "invStoreBeta": "Ontdek nieuwe functies als eerste", + "setupStep1": "Stap 1 van 2", + "setupStep2": "Stap 2 van 2", + "setupWelcomeTitle": "Welkom in je werkplaats", + "setupLangSub": "In minder dan 20 seconden staat je werkplaats klaar.", + "setupLangHelper": "Je kunt dit later nog wijzigen.", + "setupContinue": "Doorgaan", + "setupBack": "Terug", + "setupNickSub": "Hoe mogen we je noemen?", + "setupNickLabel": "Je weergavenaam", + "setupNameLen": "3–20 tekens", + "setupAvatarShuffle": "Andere kleur genereren", + "setupAvatarImport": "Foto importeren", + "setupNameSub": "Je weergavenaam is zichtbaar in de app en voor je vrienden!", + "setupLangLabel": "Je taal", + "setupNamePlaceholder": "Je weergavenaam", + "setupNameSave": "Ga naar mijn werkplaats", + "setupNameSkip": "Later", + "invWelcomeTitle": "Scan & beheer je inventaris & 3D-printers vanaf je telefoon.", + "invWelcomeSub": "Scan je TigerTag-spoelen in 10 seconden. Je inventaris wordt in realtime bijgewerkt.", + "invQrScanHint": "Scan de QR-code om te installeren op je telefoon", + "friendsTitle": "Vrienden", + "friendsMyCode": "Mijn code", + "friendsShareLink": "Link delen", + "friendsPublicLabel": "Openbare inventaris", + "friendsPublicSub": "Zichtbaar voor iedereen", + "friendsList": "Mijn vrienden", + "friendReqsTitle": "In afwachting", + "notifsTitle": "Meldingen", + "notifMarkAllRead": "Alles als gelezen markeren", + "notifsEmptyTitle": "Geen meldingen", + "notifsEmptySub": "Vriendschapsverzoeken en updates verschijnen hier", + "notifAcceptedFriend": "{{name}} heeft je vriendschapsverzoek geaccepteerd", + "notifAddedFriend": "{{name}} heeft jou als vriend toegevoegd", + "notifUpdateCloudTitle": "Nieuwe versie beschikbaar", + "notifUpdateCloudText": "v{{version}} is er net — bekijk wat er nieuw is.", + "notifPaxxTitle": "Nieuwe firmware voor {{name}}", + "notifPaxxText": "Paxx {{version}} is uit — één klik en je bent bij.", + "friendsEmpty": "Nog geen vrienden hier.", + "friendsAdd": "Vriend toevoegen", + "friendsShopTitle": "Haal wat leuks", + "friendsShopSub": "Steun het project", + "friendsRegen": "Sleutel vernieuwen", + "friendRemove": "Verwijderen", + "friendReqSub": "wil je inventaris bekijken", + "friendReqBlock": "Blokkeren", + "friendReqRefuse": "Weigeren", + "friendReqAccept": "Accepteren", + "addFriendTitle": "Vriend toevoegen", + "addFriendSub": "Voer de TigerTag-code van je vriend in", + "addFriendSend": "Verzoek versturen", + "friendSearching": "Zoeken…", + "friendNotFound": "Geen gebruiker gevonden met deze code.", + "friendSelf": "Dat is je eigen code.", + "friendRequestSent": "Verzoek verzonden!", + "friendRegenConfirm": "Privésleutel vernieuwen? Huidige vrienden behouden hun toegang. Oude links worden ingetrokken.", + "friendViewFriend": "Vriend", + "friendCount": { + "one": "{{n}} vriend", + "other": "{{n}} vrienden" + }, + "followerCount": { + "one": "{{n}} volger", + "other": "{{n}} volgers" + }, + "friendViewPublic": "Openbaar", + "friendShareInvite": "Delen", + "friendViewBack": "Mijn inventaris", + "copyLabel": "Kopiëren", + "copiedFlash": "Gekopieerd!", + "regenLabel": "Nieuwe code", + "friendsSearch": "Vriend zoeken…", + "friendsEmptySub": "Voeg iemand toe met zijn code en snuffel door zijn voorraad.", + "friendAddedOn": "Toegevoegd op {{date}}", + "friendInvErrorBadge": "Toegang geweigerd", + "friendInvErrorTitle": "Kan inventaris niet lezen", + "friendInvErrorHint": "Je vriend heeft mogelijk zijn toegangssleutel gewijzigd. Vraag hem om je te verwijderen en opnieuw toe te voegen, of de openbare modus in te schakelen.", + "friendInvPermDenied": "Toestemming geweigerd", + "friendInvErrorRetry": "Opnieuw proberen", + "friendInvErrorRemove": "Deze vriend verwijderen", + "addFriendFound": "Gevonden", + "blacklistTitle": "Geblokkeerde gebruikers", + "unblockBtn": "Deblokkeren", + "blockedOn": "Geblokkeerd op {{date}}", + "friendNotSharing": "Deze gebruiker wil zijn inventaris niet delen.", + "racksTitle": "Opslag", + "racksEmpty": "Nog geen rek", + "racksEmptySub": "Maak een rek om je spoelopslag te organiseren.", + "racksEmptyFriendSub": "Deze gebruiker heeft nog geen rekken ingesteld.", + "rackNew": "Nieuw rek", + "rackEdit": "Rek bewerken", + "rackSecIdentity": "Identiteit", + "rackSecLayout": "Indeling", + "rackSecPreview": "Voorbeeld", + "rackLevelsShort": "Niveaus", + "rackSubtitleOpt": "Beschrijving (optioneel)", + "rackPreviewDims": "{{l}} niveaus × {{p}} plekken", + "rackPreviewDimsDeep": "{{l}} niveaus × {{p}} plekken × {{d}} diep", + "rackName": "Naam", + "rackSubtitle": "Beschrijving", + "rackSubtitlePlaceholder": "Details, locatie, inhoud…", + "rackLevels": "Aantal niveaus", + "rackPositions": "Plekken per niveau", + "rackDepth": "Rijen diep", + "rackDepthView": "Diepte", + "rackDepthSpacing": "Rijafstand", + "rackDepthSpacingV": "Verticale afstand tussen rijen", + "rackDepthSpacingH": "Horizontale afstand tussen rijen", + "rackDepthReset": "Resetten", + "rackDepthHint": "Verandert alleen hoe je schappen getekend worden — nooit wat erop staat. Wordt op dit apparaat bewaard.", + "rackHue": "Kleur", + "rackHueHues": "Kleuren", + "rackHueNeutrals": "Grijstinten", + "rackHueWhites": "Wit", + "rackHueGreys": "Grijs", + "rackHueBlacks": "Zwart", + "rackHueReset": "Alles tonen", + "rackHueCount": "{{n}} van {{total}} spoelen", + "rackHueIdle": "{{total}} spoelen · sleep het bereik of verbreed het", + "rackHueEdgeL": "Linkerrand van het bereik — verbreedt naar links", + "rackHueEdgeR": "Rechterrand van het bereik — verbreedt naar rechts", + "rackPlanEdit": "Indelen", + "rackPlanDone": "Klaar", + "rackPlanAuto": "Opruimen", + "rackPlanZoom": "Plattegrondzoom", + "rackPlanZoomOut": "Uitzoomen", + "rackPlanZoomIn": "Inzoomen", + "rackPlanShrinkConfirm": "Dit rek verkleinen laat {{n}} spoel(en) zonder plek — ze gaan terug naar Niet opgeslagen. Doorgaan?", + "rackSave": "Opslaan", + "rackDelete": "Rek verwijderen", + "rackDeleteConfirm": "Rek \"{{name}}\" verwijderen? Toegewezen spoelen worden losgekoppeld.", + "rackSlots": "plekken", + "rackNameRequired": "Naam is verplicht", + "rackLevelInvalid": "Schappen moeten tussen 1 en 15 liggen", + "rackPositionInvalid": "Plekken moeten tussen 1 en 20 liggen", + "rackUnrackedTitle": "Niet-opgeslagen spoelen", + "rackAllPlaced": "Al je spoelen zijn opgeslagen.", + "rackDropHereTitle": "Zet hier een spoel neer", + "rackUnrankedEmptyHint": "Spoelen die niet in een rek staan, worden hier bewaard.", + "rackUnstoreLockedTip": "Lege spoel — automatisch uitslaan zou hem direct hierheen terugsturen, dus opslaan kan niet.", + "rackAutoStoreNoDrop": "Zet hier neer om niet-opgeslagen te houden (schakelt automatisch opslaan uit)", + "btnViewRack": "Opslag", + "viewGroupInventory": "Inventaris", + "viewGroupFavorites": "Favorieten", + "btnViewOrder": "Te bestellen", + "btnViewCam": "Camera", + "btnViewPrinter": "Printers", + "printersActive": "Actief", + "printersUpdated": "Bijgewerkt", + "printersLastSeen": "Laatst gezien", + "printersEmptyTitle": "Voeg je eerste printer toe", + "printersEmptyBullet1": "Bambu Lab, Creality, Elegoo, FlashForge of Snapmaker", + "printersEmptyBullet2": "Synchroniseert via je lokale netwerk — inloggegevens verlaten je account nooit", + "printersEmptyBullet3": "Kies de actieve printer per spoel wanneer je een tag scant", + "printersFriendNATitle": "Printers zijn privé", + "printersFriendNASub": "De 3D-printers van een vriend zijn alleen voor de eigenaar zichtbaar — niet in deze weergave.", + "printerDragHint": "Sleep om te herschikken", + "printerEditHint": "Klik om te bewerken", + "printerEditSaving": "Opslaan…", + "printerEditError": "Opslaan mislukt", + "printerAddTitle": "Printer toevoegen", + "printerAddSub": "Sluit een nieuwe 3D-printer aan", + "printersSettingsTitle": "Printerinstellingen", + "printerAddPickTitle": "3D-printer toevoegen", + "printerAddPickSub": "Kies het merk van je 3D-printer", + "printerAddFormTitle": "Nieuwe printer", + "printerAddNamePh": "X1C in de woonkamer", + "printerAddModelPh": "(onbekend / later kiezen)", + "printerAddBack": "Terug", + "printerAddSave": "Printer toevoegen", + "printerEditSave": "Wijzigingen opslaan", + "printerCardSettings": "Instellingen", + "printerCardOpen": "Details openen", + "printerCardDelete": "Printer verwijderen", + "printerEditDeleteHint": "Houd 1,5 s ingedrukt om deze printer te verwijderen", + "printerDeleteErr": "Kon de printer niet verwijderen.", + "snapLiveTitle": "Livestatus", + "snapNoConnection": "Open deze weergave terwijl de printer op je netwerk zit om de livestatus te zien.", + "snapStatusConnecting": "Verbinden…", + "snapStatusOnline": "Online", + "snapStatusOffline": "Offline", + "snapBed": "Bed", + "snapTemperatureTitle": "Temperatuur", + "creControlTitle": "Bediening", + "creDisableMotors": "Motoren uitschakelen", + "creFanPart": "Onderdeel", + "creFanCase": "Behuizing", + "creFanSide": "Zij", + "creFilEdit": "Filament bewerken", + "creFeed": "Invoeren", + "creUnload": "Uitwerpen", + "creFilSelected": "Geselecteerd:", + "snapPrintPause": "Pauzeren", + "snapPrintResume": "Hervatten", + "snapPrintCancel": "Annuleren", + "snapTempEditTip": "Klik om de doeltemperatuur in te stellen", + "acuControlTitle": "Bediening", + "acuMotorsOff": "Motoren uitschakelen, klik om assen handmatig te bewegen", + "acuFanTitle": "Ventilator", + "snapFilamentTitle": "Filament", + "snapFilLoad": "Laden", + "snapFilUnload": "Uitwerpen", + "snapFilLoadTip": "Filament laden op geselecteerde extruders", + "snapFilUnloadTip": "Filament uitwerpen uit geselecteerde extruders", + "snapFilLoadTitle": "Kies extruders om te laden", + "snapFilUnloadTitle": "Kies extruders om uit te werpen", + "snapFilConfirm": "Bevestigen", + "snapFilLoadEmpty": "Alle extruders hebben al filament.", + "snapFilUnloadEmpty": "Geen extruders met filament om uit te werpen.", + "snapFilLoaded": "Geladen", + "snapFilNotLoaded": "Geen filament", + "snapLogTitle": "Verzoeklog", + "snapLogEmpty": "Nog geen verkeer — open het paneel terwijl de printer online is.", + "snapLogClickCopy": "Klik om de ruwe JSON te kopiëren", + "snapFilEditableTip": "Klik om dit filament handmatig te bewerken", + "snapFilLockedTip": "Alleen-lezen — NFC-tag gedetecteerd door de printer", + "snapLogPause": "Pauzeren", + "snapLogResume": "Hervatten", + "snapLogClear": "Wissen", + "snapLogPaused": "Gepauzeerd", + "snapPasteTitle": "Aangepaste JSON verzenden", + "snapPasteSend": "Verzenden", + "snapPasteNotConnected": "Printer niet verbonden.", + "snapPasteInvalidJson": "Ongeldige JSON:", + "snapPasteSendError": "Verzenden mislukt:", + "snapFilEditTitle": "Filament bewerken", + "snapFilEditTitleReadonly": "Alleen-lezen filament", + "snapFilEditColor": "Kleur", + "snapFilEditVendor": "Merk", + "snapFilEditMaterial": "Materiaal", + "snapFilEditSubtype": "Subtype", + "snapFilEditSend": "Naar printer verzenden", + "snapFilEditError": "Verzenden mislukt — controleer de WebSocket van de printer.", + "snapFilEditCustomBrand": "Aangepast merk…", + "snapFilEditCustomMaterial": "Aangepast materiaal…", + "snapFilEditPickFilament": "Filament", + "snapFilEditUseCustom": "Aangepast merk / materiaal gebruiken", + "snapFilEditApply": "Toepassen", + "snapFilEditCustomColor": "Aangepaste kleur", + "snapFilSelectFilament": "Filament selecteren", + "snapFilSelectColor": "Kleur selecteren", + "snapNoFilament": "Geen filament", + "snapOfficial": "Officieel", + "snapCamera": "Camera", + "snapJobElapsed": "Verstreken", + "snapJobNoActive": "Geen actieve print", + "snapState_standby": "Stand-by", + "snapState_idle": "Inactief", + "snapState_printing": "Aan het printen", + "snapState_paused": "Gepauzeerd", + "snapState_complete": "Voltooid", + "snapState_cancelled": "Geannuleerd", + "snapState_finished": "Klaar", + "snapState_preparing": "Voorbereiden", + "snapState_failed": "Mislukt", + "snapState_ready": "Gereed", + "snapState_error": "Fout", + "printerAddErrName": "Geef je printer een naam.", + "printerAddErrMissing": "Verplichte velden ontbreken: {{fields}}", + "printerAddErrSave": "Kon niet opslaan. Controleer je netwerk en probeer opnieuw.", + "printerLblName": "Printernaam", + "printerOptional": "(optioneel)", + "printerSecCredentialsOptional": "Inloggegevens (optioneel)", + "printerHelperDocsLink": "Bekijk de installatiehandleiding van het merk →", + "printerHelperBambuTitle": "Voordat je begint", + "printerHelperBambuBullets": [ + "Open Instellingen → Algemeen → Alleen-LAN-modus op je printer.", + "Noteer het IP-adres, serienummer en de 8-cijferige toegangscode op het scherm.", + "TigerTag maakt verbinding via MQTT op je lokale netwerk." + ], + "printerHelperCrealityTitle": "Voordat je begint", + "printerHelperCrealityBullets": [ + "Vind het IP-adres in Netwerk → Printerinformatie.", + "De gebruikersnaam is altijd 'Root'.", + "Gebruik je Klipper-/Moonraker-toegangswachtwoord." + ], + "printerHelperElegooTitle": "Elegoo instellen", + "printerHelperElegooBullets": "Vind je IP-adres in de netwerkinstellingen van de printer. Het serienummer staat op het printerlabel of in het instellingenmenu.", + "printerHelperFFGTitle": "Voordat je begint", + "printerHelperFFGBullets": [ + "Vind het IP-adres en serienummer bij Over → Netwerk.", + "Gebruik het wachtwoord dat je hebt ingesteld in FlashPrint of Orca-Flashforge." + ], + "printerHelperSnapTitle": "Voordat je begint", + "printerHelperSnapBullets": [ + "Voer gewoon het lokale IP-adres in dat op het Snapmaker-netwerkscherm staat.", + "Koppeling gebeurt automatisch via WebSocket." + ], + "printerHintBambuIP": "Lokaal IP-adres getoond in Alleen-LAN-modus.", + "printerHintBambuCode": "8-cijferige code van het scherm van Alleen-LAN-modus.", + "printerHintBambuSerial": "Staat onder de toegangscode op hetzelfde scherm.", + "printerHintCrealityIP": "Lokaal netwerk-IP.", + "printerHintCrealityAccount": "Altijd 'Root' op Creality K-serie.", + "printerHintCrealityPassword": "Klipper-/Moonraker-toegangswachtwoord.", + "printerHintElegooIP": "Lokaal netwerk-IP.", + "printerHintElegooSerial": "Serienummer van het Over-scherm van de printer.", + "printerHintElegooMqtt": "Toegangscode uit de netwerkinstellingen van de printer (standaard: 123456).", + "printerHintFFGIP": "Lokaal netwerk-IP.", + "printerHintFFGSerial": "Serienummer van het Over-scherm van de printer.", + "printerHintFFGPassword": "Hetzelfde wachtwoord dat je in FlashPrint gebruikt.", + "printerHintSnapIP": "Lokaal IP-adres getoond op het Snapmaker-netwerkscherm.", + "snapAddByIpLabel": "IP-adres", + "snapAddByIpButton": "Toevoegen via IP", + "snapAddByIpInvalid": "Ongeldig IP-adres", + "snapAddByIpValidate": "Valideren", + "printersLoading": "Printers laden…", + "snapScanTitle": "Netwerk scannen…", + "snapScanStarting": "Scan starten…", + "snapScanProgress": "Scannen…", + "snapScanDone": "Scan voltooid — {{n}} gevonden", + "snapScanEmpty": "Geen Snapmaker gevonden. Controleer of hij aanstaat en op dezelfde wifi zit.", + "snapScanRestart": "Scan herstarten", + "snapManualTitle": "Handmatig toevoegen", + "snapAddChoiceTitle": "Snapmaker-printer toevoegen", + "snapAddChoiceSub": "Hoe wil je hem vinden?", + "snapAddChoiceScan": "Netwerk scannen", + "snapAddChoiceScanHint": "Automatisch detecteren op je lokale netwerk", + "snapAddChoiceManual": "IP-adres invoeren", + "snapAddChoiceManualHint": "Als je het IP-adres al kent", + "bblCloudChoice": "Mijn Bambu Lab-account gebruiken", + "bblCloudChoiceHint": "Vindt al je printers vanzelf", + "bblCloudTitle": "Inloggen bij Bambu Lab", + "bblCloudSub": "Je e-mail, een code, en je printers verschijnen.", + "bblCloudEmailPh": "jij@voorbeeld.com", + "bblCloudSendCode": "Stuur me een code", + "bblCloudCodePh": "De code uit je inbox", + "bblCloudSignIn": "Inloggen", + "bblCloudChangeEmail": "Wijzigen", + "bblCloudCodeSent": "Code verzonden — 10 minuten geldig. Kijk uit naar een mail van Bambu Lab.", + "bblCloudErrCode": "Die code klopt niet. Controleer hem en probeer opnieuw.", + "bblCloudErrExpired": "Die code is verlopen. We hebben een nieuwe gestuurd.", + "bblCloudErrBlocked": "Bambu Lab weigert ons nu. Geef het een minuutje.", + "bblCloudErrGeneric": "Inloggen is niet gelukt. Probeer opnieuw.", + "bblCloudNoPrinters": "Nog geen printers op dit account.", + "bblCloudPick": "Vink aan wat je wilt", + "bblCloudAddSelected": { + "one": "Deze printer toevoegen", + "other": "Deze {{n}} printers toevoegen" + }, + "bblCloudAddFailed": "Kon die printer niet toevoegen.", + "ffgAddChoiceTitle": "FlashForge-printer toevoegen", + "creAddChoiceTitle": "Creality-printer toevoegen", + "bambuAddChoiceTitle": "Bambu Lab-printer toevoegen", + "elegooAddChoiceTitle": "Elegoo-printer toevoegen", + "ffgScanEmpty": "Geen FlashForge-printers gevonden op je lokale netwerk", + "ffgScanUnidentified": "FlashForge — tik om in te stellen", + "creScanEmpty": "Geen Creality-printers gevonden op je lokale netwerk", + "bambuScanEmpty": "Geen Bambu Lab-printers gevonden op je lokale netwerk", + "elegooScanEmpty": "Geen Elegoo-printers gevonden op je lokale netwerk", + "snapManualSub": "Typ het lokale IP-adres van de printer — we controleren het om de rest voor je in te vullen.", + "snapManualProbe": "Controleren + doorgaan", + "snapManualBadIp": "Ongeldig IP-adres.", + "snapManualProbing": "{{ip}} benaderen…", + "snapManualNoReply": "Geen reactie van {{ip}}.", + "snapManualContinueAnyway": "Toch doorgaan", + "snapScanScore": "Score: {{n}}", + "snapScanNoSubnets": "Geen netwerk gedetecteerd. Verbind met wifi.", + "snapScanLogTitle": "Scanlog", + "snapScanLogClear": "Wissen", + "snapScanLogCopy": "Klik om de ruwe JSON te kopiëren", + "snapScanExtraSubnetsLabel": "Andere netwerken om te scannen", + "snapScanExtraSubnetsHint": "Voeg een ander netwerk toe als je printer zich elders bevindt (bijv. 192.168.40).", + "snapScanExtraSubnetsAdd": "Toevoegen", + "snapScanExtraSubnetsRemove": "Verwijderen", + "snapScanExtraSubnetsBadFormat": "Gebruik het formaat: 192.168.40", + "snapScanCardBrandConfirmed": "Door de printer bevestigd als Snapmaker", + "snapScanLogExport": "Exporteren", + "snapScanLogExported": "Gekopieerd!", + "snapScanLogExportFailed": "Kopiëren mislukt", + "snapScanEmptyFirewall": "Geen reactie op {{p}}. Gebruik \"Toevoegen via IP\" met het exacte adres.", + "printerPanelTitle": "Printerdetails", + "printerSecIdentity": "Identiteit", + "printerSecConnection": "Verbinding", + "printerSecCredentials": "Inloggegevens", + "printerSecRaw": "Ruwe gegevens", + "printerSecretWarn": "Deze geheimen geven toegang tot je printer op LAN-niveau. Deel ze niet en plak ze niet in onbetrouwbare apps.", + "printerSecretShow": "Tonen", + "printerSecretHide": "Verbergen", + "printerLblId": "ID", + "printerLblBrand": "Merk", + "printerLblModel": "Model", + "printerLblModelId": "Model-ID", + "printerLblActive": "Actief", + "printerLblSortIndex": "Sorteervolgorde", + "printerLblUpdatedAt": "Laatst bijgewerkt", + "printerLblConnection": "Type", + "printerLblBroker": "MQTT-broker", + "printerLblIP": "IP-adres", + "printerLblSerial": "Serienummer", + "printerLblAccount": "Account", + "printerLblAccessCode": "Toegangscode", + "printerLblPassword": "Wachtwoord", + "printerLblMqttPassword": "MQTT-wachtwoord", + "yesLabel": "Ja", + "noLabel": "Nee", + "errReportBtn": "Probleem melden", + "errReportTitle": "Diagnoserapport", + "errReportSub": "Kopieer dit rapport en stuur het naar support, zodat we kunnen helpen.", + "errReportCopy": "Rapport kopiëren", + "errReportCopied": "Gekopieerd!", + "errReportClear": "Log wissen", + "errDetailsLink": "Details", + "errReportDownload": "↓ Downloaden", + "rackAutoFill": "Automatisch vullen", + "rackAutoFillTip": "Niet-opgeslagen spoelen in lege, ontgrendelde plekken plaatsen", + "rackLockedTip": "Vergrendeld · rechtsklik op een plek om te (ont)grendelen", + "rackUnusableTip": "Geblokkeerde plek — onbruikbaar voor opslag", + "rackPinnedTip": "Vastgezet — materiaal blijft op zijn plek", + "rackStatsRacks": { + "one": "rek", + "other": "rekken" + }, + "rackStatsSlots": "plekken", + "rackStatsEmpty": "vrij", + "rackStatsLocked": "vergrendeld", + "rackStatsDepleted": "leeg", + "sectionStorageLoc": "Opslaglocatie", + "storageNotPlaced": "Niet opgeslagen", + "storageAutoAssign": "Automatisch toewijzen", + "storageAutoAssignTip": "Plaats in de eerste beschikbare plek", + "storageAutoAssignFull": "Alle rekken zijn vol.", + "storageLocateTip": "Tonen in Opslag-weergave", + "autoStorageTitle": "Automatisch opslaan", + "autoStorageSub": "Nieuwe spoelen automatisch plaatsen", + "autoUnstorageTitle": "Automatisch uitslaan", + "autoUnstorageSub": "Rekplek vrijgeven zodra een spoel 0 g bereikt", + "autoOrganizeTitle": "Automatisch organiseren", + "autoOrganizeSub": "Plaatst nieuwe spoelen automatisch en maakt de plek vrij zodra een spoel leeg is. Vergrendel een plek voor een uitzondering.", + "rackStatsDepletedTip": "Actieve spoelen zonder filament (gewicht 0 g)", + "rackStatsUnranked": "niet opgeslagen", + "rackActionMore": "Meer acties", + "actionMove": "Verplaatsen", + "boardTempTitle": "Temperatuur", + "boardJobTitle": "Print", + "boardCamTitle": "Camera", + "boardCamPlay": "Beeld tonen", + "boardUnitsTitle": "Filamentopslag", + "boardWidgets": "Widgets", + "unitsSplit": "Eenheden splitsen", + "unitsGroup": "Eenheden groeperen", + "planClusterMake": "Kaarten groeperen", + "planClusterBreak": "Kaarten degroeperen", + "planClusterHint": "Selecteer eerst minstens twee kaarten — dan reizen ze als één geheel.", + "rackActionEdit": "Bewerken", + "rackActionAutofill": "Automatisch vullen", + "rackActionLockAll": "Alles vergrendelen", + "rackActionUnlockAll": "Alles ontgrendelen", + "rackActionEmpty": "Alles legen", + "rackActionDelete": "Verwijderen", + "dbgDeletedTab": "Verwijderd", + "dbgDeletedSub": "Zacht verwijderde spoelen — klik op ↺ om te herstellen", + "dbgDeletedEmpty": "Geen verwijderde spoelen.", + "dbgDeletedRestore": "Herstellen", + "dbgDeletedPurge": "Definitief verwijderen (onomkeerbaar)", + "dbgDeletedPurgeConfirm": "\"{{name}}\" definitief uit de database verwijderen? Dit kan niet ongedaan worden gemaakt.", + "dbgDeletedPurgeConfirmTwin": "\"{{name}}\" EN de gekoppelde tag definitief uit de database verwijderen? Dit kan niet ongedaan worden gemaakt.", + "aboutTitle": "Over", + "aboutCopy": "Kopiëren", + "aboutAutoUpdate": "Automatisch bijwerken", + "aboutAutoUpdateSub": "Controleren op nieuwe versies bij opstarten", + "aboutCheckUpdate": "Controleren op updates", + "aboutCheckUpdateChecking": "Controleren op updates…", + "aboutCheckUpdateUpToDate": "Je hebt de nieuwste versie.", + "aboutCheckUpdateAvailable": "Nieuwe versie beschikbaar", + "aboutCheckUpdateReady": "Update klaar — herstart om te installeren", + "aboutCheckUpdateErr": "Kon niet controleren", + "filterAllBrands": "Alle", + "filterShortBrand": "Merk", + "rackCreate": "Aanmaken", + "filterAllMaterials": "Alle", + "filterAllSeries": "Alle", + "filterShortMaterial": "Materiaal", + "filterAllAspects": "Alle", + "filterShortAspect": "Uiterlijk", + "filterAllTypes": "Alle types", + "rackEmpty": "Rek leegmaken", + "rackEmptyConfirm": "Rek \"{{name}}\" leegmaken? Alle toegewezen spoelen worden losgekoppeld (het rek zelf blijft bestaan).", + "scalesPanelTitle": "Tiger Scales", + "scaleHealthOnline": "{{n}}/{{total}} weegschaal/schalen online", + "scaleHealthOffline": "{{n}} weegschaal/schalen — allemaal offline", + "scaleHealthStandby": "{{n}} weegschaal/schalen in stand-by", + "scaleHealthRow": "Weegschaal #{{n}}", + "scaleHealthNone": "TigerScale niet verbonden", + "scaleStatusOnline": "online", + "scaleStatusOffline": "offline", + "scaleStatusStandby": "stand-by", + "scaleChipPower": "Voeding", + "scaleChipPowerUsb": "USB", + "scaleChipPowerBattery": "Batterij", + "scaleChipCharging": "Opladen", + "scaleChipWifiQualityExcellent": "Uitstekend", + "scaleChipWifiQualityGood": "Goed", + "scaleChipWifiQualityFair": "Redelijk", + "scaleChipWifiQualityWeak": "Zwak", + "scaleChipLastSeen": "Laatst gezien", + "scaleChipFwTooltip": "Firmwareversie", + "scaleNoActivity": "Nog geen spoel gewogen", + "scaleRemove": "Deze weegschaal verwijderen", + "scaleRefresh": "Signaal vernieuwen", + "scaleLocalLive": "LIVE", + "scaleLocalOff": "LOKAAL UIT", + "scaleTareBtn": "TARREREN", + "scaleStatusReady": "Klaar", + "scaleStatusScanning": "Scannen", + "scaleStatusStable": "Stabiel", + "scaleStatusSending": "Verzenden", + "scaleStatusSuccess": "Gelukt", + "scaleBadgeSendIn": "Verzenden over {{n}}s", + "scaleBadgeError": "Fout", + "scaleBadgeRemoveSpool": "Spoel verwijderen", + "scaleRemoveConfirm": "\"{{name}}\" van de lijst verwijderen? Verschijnt automatisch weer bij de volgende hartslag.", + "scaleEmptyTitle": "Voeg een TigerScale toe aan je opstelling", + "scaleEmptySub": "Zet een spoel neer. Hij bepaalt zelf welke het is, weegt wat er echt nog over is, en werkt je inventaris zelf bij.", + "scaleEmptyBullet1": "Twee lezers — je spoel wordt herkend hoe je hem ook neerzet", + "scaleEmptyBullet2": "Trekt het gewicht van de lege spoel eraf, zodat je het echte filament ziet", + "scaleEmptyBullet3": "Groot touchscreen aan boord: wifi, kalibratiewizard en updates, allemaal op de weegschaal", + "scaleEmptyBullet4": "Synchroniseert met je TigerTag-account, zodat elk scherm dat je hebt dezelfde cijfers toont", + "scaleEmptyBullet5": "Herkent merk en materiaal uit eigen geheugen — geen internet nodig", + "scaleEmptyBullet6": "Werkt volledig zelfstandig — geen computer om aan te zetten, geen app om te openen (batterij optioneel)", + "scaleEmptyCta": "Bekijk op GitHub", + "scaleEmptyCtaModel": "Haal het op MakerWorld", + "scaleEmptyLicense": "100% open source — bouw je eigen exemplaar", + "searchShort": "Zoeken…", + "clearSearch": "Zoekopdracht wissen", + "rackClearAll": "Alles legen", + "rackClearAllConfirm": "Alle spoelen uit \"{{name}}\" halen? Ze gaan terug naar \"Niet-opgeslagen spoelen\" (het rek blijft bestaan).", + "spoolMarkDeleted": "Verwijderen", + "spoolMarkDeletedTip": "Verwijdert dit materiaal definitief uit je inventaris. De chip behoudt zijn gegevens — wis of recycle hem om opnieuw te beginnen.", + "uidMigrConfirmTitle": "Update van inventarisformaat beschikbaar", + "uidMigrConfirmMsg": "{{count}} spoelen in je inventaris gebruiken het oude opslagformaat. Bijwerken zet ze om naar het nieuwe formaat. Geschatte tijd: ongeveer {{duration}} — sluit de app niet af terwijl dit loopt.", + "uidMigrConfirmRemind": "Later herinneren", + "uidMigrConfirmAccept": "Nu bijwerken", + "uidMigrProgressTitle": "Update van inventarisformaat bezig", + "uidMigrProgressMsg": "Je inventaris wordt bijgewerkt naar een nieuw, efficiënter opslagformaat. Sluit de app niet af tot dit klaar is. Elke spoel kost slechts een fractie van een seconde.", + "uidMigrProgressWarn": "⚠ De app nu sluiten hervat gewoon bij de volgende start — maar laat het liever afmaken voor de beste ervaring.", + "uidMigrDurationSeconds": { + "one": "{{n}} seconde", + "other": "{{n}} seconden" + }, + "uidMigrDurationMinutes": { + "one": "{{n}} minuut", + "other": "{{n}} minuten" + }, + "rackMigrConfirmTitle": "Update van opslaggegevens beschikbaar", + "rackMigrConfirmMsg": "We vonden {{count}} spoel(en) die de oude opslagindeling gebruiken. Bijwerken groepeert de rekplek in één overzichtelijk veld — duurt {{duration}}, draait op de achtergrond, en je spoelen blijven waar ze zijn.", + "rackMigrProgressTitle": "Update van opslaggegevens bezig", + "rackMigrProgressMsg": "Je opslagtoewijzingen worden opnieuw verpakt. Sluit de app niet af — elke spoel kost slechts een fractie van een seconde.", + "rackMigrProgressWarn": "⚠ De app nu sluiten hervat gewoon bij de volgende start — maar laat het liever afmaken voor de beste ervaring.", + "migrationConfirmTitle": "Kleine update beschikbaar", + "migrationConfirmMsg": "Een kleine gegevensupdate staat klaar voor {{count}} item(s). Draait op de achtergrond en duurt {{duration}}. Je gegevens blijven precies waar ze zijn — er verplaatst of verdwijnt niets.", + "uidMigrConfirmMobileWarn": "Zorg dat je mobiele app is bijgewerkt naar versie 1.0.3 of hoger voordat je doorgaat.", + "migrationProgressTitle": "Update bezig", + "migrationProgressMsg": "Je gegevens worden opgeruimd — sluit de app niet af. Elk item kost slechts een fractie van een seconde.", + "migrationProgressWarn": "⚠ Nu sluiten hervat gewoon bij de volgende start — maar laat het liever afmaken voor de beste ervaring.", + "ffgErrSnMismatch": "Onjuist serienummer — controleer de printerinstellingen", + "ffgErrBadPassword": "Onjuist wachtwoord — controleer de printerinstellingen", + "ffgState_ready": "Gereed", + "ffgState_preparing": "Voorbereiden", + "ffgState_heating": "Opwarmen", + "ffgState_busy": "Bezig", + "elgState_busy": "Bezig", + "elgState_preparing": "Voorbereiden", + "elgState_heating": "Opwarmen", + "elgPauseTitle": "Print pauzeren", + "elgResumeTitle": "Print hervatten", + "elgCancelTitle": "Print annuleren", + "elgTimelapseDl": "Timelapse downloaden", + "elgFsTimelapse": "Timelapse", + "elgTimelapseEmpty": "Geen timelapse-video's", + "tlpDownload": "Downloaden", + "tlpDownloading": "Downloaden…", + "tlpDownloaded": "Opgeslagen!", + "elgSetTempTip": "Klik om de doeltemperatuur in te stellen", + "ffgSlotEmpty": "Leeg", + "ffgCameraAlt": "FlashForge-camerastream", + "ffgCamFailMsg": "Cameraverbinding mislukt — er mag maar één kijker tegelijk zijn.", + "ffgCamRetry": "Opnieuw proberen", + "ffgFilEditTitle": "Filament wijzigen", + "elgFilEditTitle": "Filament wijzigen", + "elgFilEditApply": "Toepassen", + "ffgFilEditApply": "Toepassen", + "ffgErrNetwork": "Kan de printer niet bereiken — controleer IP en netwerk.", + "ffgConnConnecting": "Verbinden…", + "ffgConnConnected": "Verbonden", + "ffgConnOffline": "Offline", + "ffgConnReconnecting": "Opnieuw verbinden…", + "statCloud": "TigerData", + "statCloudMini": "Cloud", + "statCloudPlusMini": "Data+", + "colorCountMono": "Mono", + "colorCountDual": "Dual", + "colorCountTri": "Tri", + "colorCountRainbow": "Regenboog", + "filterAllVersions": "Alle", + "filterShortProtocol": "Type", + "filterAllTags": "Alle", + "filterShortTag": "Tag", + "filterAllStates": "Alle", + "filterShortState": "Status", + "snapStateHeating": "Opwarmen", + "crePause": "Pauzeren", + "creResume": "Hervatten", + "creStop": "Annuleren", + "creStopConfirm": "Bevestigen?", + "creLedOnTip": "Led uitschakelen", + "creLedOffTip": "Led inschakelen", + "creFilesTitle": "Bestanden", + "crePrintFile": "Printen", + "creDeleteFile": "Verwijderen", + "creFilesEmpty": "Geen bestanden op de printer", + "creFilesLoading": "Bestanden laden…", + "scaleWsConnect": "Verbinden", + "scaleWsDisconnect": "Loskoppelen", + "scaleContainerLabel": "CONTAINER", + "scaleFilamentLabel": "FILAMENT", + "scaleReader": "Lezer", + "bblRtspLabel": "RTSP-stream", + "bblRtspHint": "Niet native ondersteund — open in VLC of een andere mediaspeler", + "bblRtspCopy": "URL kopiëren", + "bblRtspOpen": "Openen", + "addDeviceBtn": "Apparaat", + "addRackBtn": "Rek toevoegen", + "rackNoSpaceHint": "Geen vrije ruimte — voeg een rek toe om de resterende spoelen op te slaan.", + "printerConnect": "Verbinden", + "printerDisconnect": "Loskoppelen", + "printersSectionOnline": "Verbonden", + "printersSectionOffline": "Offline", + "elgCtrlTitle": "Bediening", + "elgCtrlSpeed": "Printsnelheid", + "elgCtrlSpeedNormal": "Normaal", + "elgCtrlSpeedBalanced": "Gebalanceerd", + "elgCtrlSpeedSport": "Sport", + "elgCtrlSpeedLudicrous": "Waanzinnig", + "elgCtrlFanModel": "Model", + "elgCtrlFanAux": "Hulp", + "bblFanChamber": "Behuizing", + "elgCtrlFanBox": "Behuizing", + "elgCtrlLed": "Bovenlicht", + "elgFilePrint": "Printen", + "elgCtrlStep": "Stap", + "elgCtrlFans": "Ventilatoren", + "snapCtrlSpeed": "Snelheid", + "snapCtrlFanPart": "Onderdeelkoeling", + "snapCtrlFanMain": "Hoofd", + "snapCtrlFanAssist": "Hulp", + "camSizeCompact": "Compact (½×)", + "camSizeNormal": "Normaal (1×)", + "camSizeWide": "Breed (2×)", + "camSizeFullscreen": "Volledig scherm", + "camSizeExitFullscreen": "Volledig scherm verlaten", + "tigerPodModalTitle": "Print nu je TigerPOD!", + "tigerPodModalDesc": "Een 3D-printbare houder om TigerTag-NFC-chips rechtstreeks op je filamentspoelen te branden.", + "tigerPodPrintBtn": "Download & print STL gratis", + "tigerPodPrintCta": "Print de TigerPOD", + "tigerPodPrintNormalBtn": "Standaard", + "tigerPodPrintMiniBtn": "Mini", + "tigerPodBoosts": "Boosts", + "tigerPodLikes": "Likes", + "tigerPodFree": "Gratis", + "tigerPodFeat1Title": "Dubbele NFC-lezer", + "tigerPodFeat1Desc": "1 of 2 lezers ACR122U", + "tigerPodFeat2Title": "Dubbele koppeling", + "tigerPodFeat2Desc": "2 TigerTags tegelijk", + "tigerPodFeat3Title": "Direct printen, geen montage", + "tigerPodFeat3Desc": "Geen support-optimalisatie nodig", + "tigerPodFeat4Title": "Standaard spoel van 1 kg", + "tigerPodFeat4Desc": "Verbeterde pasvorm voor 99% van de spoelen", + "tigerPodPrintSpec": "0,2 mm · 8% vulling · ~7 u", + "upgradeToPlusHelpBody": "De product-ID is het nummer dat in de URL van een TigerTag-productpagina staat. Blader door de materiaallijst, open een product en kopieer het nummer aan het einde van de URL.", + "tigerPodCta": "Geef een boost & like", + "encModalTitle": "Naar chip schrijven", + "encModalSub": "Plaats je chip op de lezer en start het branden.", + "encReady": "Klaar om te branden.", + "encPlaceChips": "Houd de NFC-tags voor de lezers", + "encBurning": "Schrijven… houd de chip(s) op de lezer(s).", + "encNoReader": "Geen lezer verbonden", + "encSameUid": "Beide lezers zien dezelfde chip — gebruik twee verschillende chips.", + "encFailed": "Reeks mislukt — herpositioneer en probeer opnieuw.", + "encBurn": "Branden", + "encUpdate": "Bijwerken", + "encUpdateTag": "Bijwerken", + "encErase": "Wissen", + "encRecycle": "Recyclen", + "encMismatch": "Dit is niet de chip van dit materiaal — leg de juiste erop.", + "encRetry": "Opnieuw proberen", + "encAbort": "Afbreken", + "encOverwriteWarn": "Een chip bevat al gegevens — deze worden gewist.", + "encOverwriteAccept": "Ik begrijp het, overschrijven", + "encSlotWaiting": "Wachten", + "encSlotReady": "Gereed", + "encSlotWriting": "Schrijven…", + "encSlotOk": "Klaar", + "encSlotFail": "Mislukt", + "camWallEmptyTitle": "Geen camera's online", + "camWallEmptySub": "Voeg een printer met camera toe om hier livebeelden te zien.", + "tutoStepXOfY": "Stap {{n}} van {{total}}", + "tutoPrev": "Vorige", + "tutoNext": "Volgende", + "tutoFinish": "Voltooien", + "tutoClose": "Sluiten", + "tutoOpenBtn": "Verbindingstutorial", + "tutoUnavailable": "Nog geen verbindingstutorial voor dit merk", + "tutoTitleFor": "Verbindingstutorial voor {{brand}}", + "tutoPickModel": "Kies je printermodel", + "tutoEstimatedMinutes": "~{{n}} min", + "tutoNone": "Er is nog geen verbindingstutorial beschikbaar voor deze printer.", + "tutoStuckLink": "Ik zit vast — open de officiële handleiding", + "tutoBambuX1Step1": "Stap 1: schakel Alleen-LAN-modus in aan de printerkant. Ga naar de Instellingenpagina links op het printerscherm en klik op Instellingen.", + "tutoBambuX1Step2": "Klik op \"Alleen LAN\".", + "tutoBambuX1Step3": "Schakel Alleen-LAN-modus in.", + "tutoBambuX1Step4": "Kies naar wens of je liveview in LAN-modus wilt inschakelen.", + "tutoBambuX1Step5": "Stap 2: schakel Ontwikkelaarsmodus in aan de printerkant. Schakel \"Ontwikkelaarsmodus\" in.", + "tutoBambuX1Step6": "Lees de belangrijke mededeling en risicowaarschuwing zorgvuldig. Als je alle bijbehorende risico's of gevolgen accepteert, vink dan \"Ik bevestig dat ik de bovenstaande belangrijke mededeling heb gelezen en begrepen\" aan en kies vervolgens \"Ontwikkelaarsmodus inschakelen\".", + "tutoBambuX1Step7": "Zodra deze functie is ingeschakeld, wordt de knop groen. Gebruik daarna het IP-adres, serienummer en de toegangscode van de printer in Tiger Studio.", + "tutoBambuP1Step1": "Stap 1: schakel Alleen-LAN-modus in aan de printerkant. Ga naar de Instellingenpagina en kies WLAN.", + "tutoBambuP1Step2": "Kies Alleen-LAN-modus.", + "tutoBambuP1Step3": "Kies Ja en schakel Alleen-LAN-modus in.", + "tutoBambuP1Step4": "Na het inschakelen van Alleen-LAN-modus verschijnt ON.", + "tutoBambuP1Step5": "Stap 2: schakel Ontwikkelaarsmodus in aan de printerkant. Klik na het inschakelen van Alleen-LAN-modus op de knop Naar beneden scrollen en zoek Ontwikkelaarsmodus.", + "tutoBambuP1Step6": "Kies Ontwikkelaarsmodus en lees de belangrijke mededeling zorgvuldig.", + "tutoBambuP1Step7": "Als je alle bijbehorende risico's of gevolgen accepteert, scroll dan helemaal naar beneden en klik op Inschakelen.", + "tutoBambuP1Step8": "Na het inschakelen van Ontwikkelaarsmodus verschijnt ON. Gebruik daarna het IP-adres, serienummer en de toegangscode van de printer in Tiger Studio.", + "tutoBambuA1Step1": "Stap 1: schakel Alleen-LAN-modus in aan de printerkant. Ga naar de Instellingenpagina vanaf het printerscherm door op Instellingen te klikken.", + "tutoBambuA1Step2": "Klik op \"Alleen-LAN-modus\".", + "tutoBambuA1Step3": "Schakel \"Alleen-LAN-modus\" in.", + "tutoBambuA1Step4": "Stap 2: schakel Ontwikkelaarsmodus in aan de printerkant. Schakel \"Ontwikkelaarsmodus\" in.", + "tutoBambuA1Step5": "Lees de belangrijke mededeling zorgvuldig. Als je alle bijbehorende risico's of gevolgen accepteert, vink dan \"Ik bevestig dat ik de bovenstaande belangrijke mededeling heb gelezen en begrepen\" aan en kies vervolgens \"Inschakelen\".", + "tutoBambuA1Step6": "Zodra deze functie is ingeschakeld, wordt de knop groen.", + "tutoBambuA1Step7": "Controleer het IP-adres en serienummer van de printer in de printerinstellingen.", + "tutoBambuA1Step8": "Gebruik het IP-adres, serienummer en de toegangscode van de printer in Tiger Studio.", + "tutoFlashforgeAd5xStep1": "Stap 1: tik op het hoofdscherm rechtsonder op de knop \"Basisinfo\".", + "tutoFlashforgeAd5xStep2": "Stap 2: haal op de pagina Basisinfo het serienummer en IP-adres op.", + "tutoFlashforgeAd5xStep3": "Stap 3: kies het tandwielpictogram, tik op \"Netwerkmodus\" en haal daarna de printer-ID op.", + "tutoElegooStep1": "Kies op het touchscreen Instellingen → Alleen LAN. Schakel Alleen LAN + toegangscode in en kies Bevestigen.", + "anycubicAddChoiceTitle": "Anycubic-printer toevoegen", + "anycubicScanEmpty": "Geen Anycubic-printers gevonden — zorg dat LAN-modus is ingeschakeld op de printer", + "acuImportChoice": "Importeren vanuit Anycubic Slicer", + "acuImportChoiceHint": "Leest gekoppelde printers en inloggegevens", + "acuImportTitle": "Importeren vanuit Anycubic Slicer", + "acuImportSub": "Gekoppelde LAN-printers gevonden in de configuratie van de slicer", + "acuImportErrNotFound": "AnycubicSlicerNext-configuratie niet gevonden. Installeer de slicer en koppel je printer (LAN-modus) één keer.", + "acuImportErrNoPrinters": "Geen gekoppelde LAN-printers in de slicerconfiguratie. Open AnycubicSlicerNext en koppel de printer één keer in LAN-modus.", + "acuImportErrBridge": "Verbindingsbrug ontbreekt — sluit de app volledig af en start opnieuw op.", + "acuNoLayout": "Verbonden — wachten op de ACE-indeling…", + "printerLblDeviceId": "Apparaat-ID", + "printerLblUsername": "Gebruikersnaam", + "printerHintAnycubicIP": "Lokaal IP-adres van de printer — LAN-modus moet AAN staan", + "printerHintAnycubicModelId": "Numerieke model-id (bijv. 20027) — ingevuld door de slicerimport", + "printerHintAnycubicDeviceId": "32-tekens apparaat-id — ingevuld door de slicerimport", + "printerHintAnycubicUsername": "Broker-gebruikersnaam — ingevuld door de slicerimport", + "printerHintAnycubicPassword": "Broker-wachtwoord — ingevuld door de slicerimport", + "printerHelperAnycubicTitle": "Voordat je begint", + "printerHelperAnycubicBullets": [ + "Koppel de printer één keer in AnycubicSlicerNext (LAN-modus AAN).", + "Gebruik 'Importeren vanuit Anycubic Slicer' om alle velden automatisch in te vullen.", + "Inloggegevens blijven bewaard — de slicer is daarna niet meer nodig." + ], + "acuCloudChoice": "Toevoegen vanuit Anycubic Cloud", + "acuCloudChoiceHint": "Voor printers in cloudmodus", + "recommendedBadge": "Aanbevolen", + "acuCloudTitle": "Toevoegen vanuit Anycubic Cloud", + "acuCloudSub": "Cloudprinters op je Anycubic-account", + "acuCloudConnect": "Inloggen bij Anycubic Cloud", + "acuCloudReload": "Herladen", + "acuCloudLoadingPrinters": "Je printers laden…", + "acuCloudHelpIntro": "Cloudprinters worden toegevoegd via AnycubicSlicerNext. Start hem met remote debugging, ingelogd, en open de Workbench:", + "acuCloudErrUnreachable": "Slicer niet bereikbaar. Start AnycubicSlicerNext in brugmodus (hieronder), ingelogd, met de Workbench open.", + "acuCloudErrNoWorkbench": "Workbench niet gevonden. Open het Workbench-tabblad in de slicer en log in.", + "acuCloudErrNoToken": "Niet ingelogd. Log in op je Anycubic-account in de slicer en probeer opnieuw.", + "acuCloudErrRest": "Kon de Anycubic-cloud niet bereiken. Controleer je verbinding en probeer opnieuw.", + "acuCloudErrNoPrinters": "Geen cloudprinters op je account.", + "acuCloudAddFailed": "Kon de cloudprinter niet toevoegen.", + "printerConnCloud": "Cloud", + "acuCloudTokenRefreshed": "Cloudverbinding vernieuwd", + "acuCloudTokenStale": "Cloud-inlogsessie verlopen — voeg de printer opnieuw toe met de slicer in brugmodus.", + "acuHomeXyz": "XYZ-assen homen", + "acuHomeXy": "XY-assen homen", + "acuHomeZ": "Z-as homen", + "acuSpeedMode": "Snelheid", + "acuSpeedSilent": "Stil", + "acuSpeedStandard": "Standaard", + "acuSpeedSport": "Sport", + "acuSpeedLudicrous": "Waanzinnig", + "acuFeedLoad": "Laden", + "acuFeedUnload": "Uitwerpen", + "acuFeedStop": "Stop", + "acuErrTitle": "Printerfout", + "acuErrDismiss": "OK", + "ffgFilesTitle": "Bestanden", + "ffgFilesLoad": "Bestanden laden", + "ffgFilesEmpty": "Geen bestanden op de printer", + "ffgFilePrint": "Printen", + "ffgPrintStarted": "Print gestart", + "ffgFanCooling": "Ventilator", + "ffgFanChamber": "Kamer", + "ffgFanInternal": "Intern", + "ffgFanExternal": "Hulp", + "ffgDoorOpen": "Deur open", + "ffgDoorClosed": "Deur dicht", + "ffgErrorBanner": "Printerfout: {{code}}", + "ffgInfoTitle": "Printerinfo", + "ffgInfoStatsSection": "Statistieken", + "ffgInfoMachineSection": "Machine", + "ffgInfoFilamentTotal": "Gebruikt filament", + "ffgInfoPrintTimeTotal": "Printtijd", + "ffgInfoDiskFree": "Vrije schijfruimte", + "ffgInfoModel": "Model", + "ffgInfoFirmware": "Firmware", + "ffgInfoNozzle": "Nozzle", + "ffgInfoVolume": "Bouwvolume", + "ffgInfoGroup": "Groep", + "ffgInfoAutoShutdown": "Automatisch uitschakelen", + "ffgInfoZComp": "Z-offset", + "acuFilesTitle": "Bestanden", + "acuFilesLoading": "Laden…", + "acuFilesEmpty": "Geen bestanden gevonden", + "acuFilesTabLocal": "Op printer", + "acuFilesTabUsb": "USB", + "acuFilesTabCloud": "Cloud", + "acuFilePrint": "Printen", + "acuFileDelete": "Verwijderen", + "acuFileIncompatible": "Gesliced voor een andere printer", + "whatsNewTitle": "Wat is er nieuw", + "whatsNewReleaseTitle": "Tiger Studio Manager {{v}} openbare releasenotitie", + "whatsNewGotIt": "Begrepen", + "whatsNewLater": "Later", + "whatsNewCoffee": "Beleef je plezier?", + "whatsNewEmpty": "Geen releasenotities voor deze versie.", + "viewGroupPrinters": "Printers", + "viewGroupCatalog": "Catalogus", + "catFilterSeriesPick": "Kies eerst een merk", + "catalogTypeUnsupported": "{{type}}-producten zijn voorlopig alleen om te bekijken — kijken kan, toevoegen nog niet.", + "camDetach": "Loskoppelen", + "friendViewInv": "Inventaris bekijken", + "avatarPromptTitle": "Je bent uniek. Laat het zien.", + "avatarPromptBody": "Nu ben je gewoon een letter in een cirkel — spannend, we weten het. Kies een avatar die onmiskenbaar jij is, zodat vrienden je in één oogopslag herkennen en je gedeelde inventaris eindelijk wat karakter krijgt. Kost tien seconden.", + "avatarPromptCta": "Kies mijn avatar", + "avatarPromptLater": "Later", + "notifAvatarText": "Je bent uniek — geef jezelf een avatar die daarbij past.", + "btnEditProfile": "Profiel bewerken", + "btnManageAccounts": "Accounts beheren", + "manageAccountsSub": "Wissel, log in, log uit, geniet ervan.", + "accountActiveLabel": "Actief account", + "btnSwitchHere": "Wisselen", + "friendRemoveTitle": "'{{name}}' verwijderen", + "friendRemoveConfirm": "Wil je {{name}} echt uit je vrienden verwijderen?", + "friendRemoveBtn": "Vriend verwijderen", + "notifDiscordText": "Kom even gedag zeggen op onze Discord — de community zit daar klaar.", + "discordJoinCta": "Word lid", + "notifDiscordTitle": "Word lid van onze Discord", + "notifAvatarTitle": "Voeg een profielfoto toe", + "notifGithubTitle": "Geef ons een ster op GitHub", + "notifGithubText": "Geef de repo een ster — het geeft ons echt een boost.", + "notifMakerworldTitle": "Gratis 3D-bestanden", + "notifMakerworldText": "Ontdek onze gratis printbare modellen op MakerWorld.", + "notifShopTitle": "Er wacht wat leuks", + "notifShopText": "NFC-makers, merch en meer — haal wat leuks en help TigerTag draaiende houden.", + "notifWikiTitle": "Vragen? Er is een wiki", + "notifWikiText": "Elke hoek van het ecosysteem, ergens daar uitgelegd.", + "notifCoffeeTitle": "Beleef je plezier met Tiger Studio?", + "notifCoffeeText": "Je gebruikt het nu al een paar dagen. Als het zijn geld waard is, mag je me best op een koffie trakteren — daar komen de updates van.", + "sectionTags": "Tags", + "tagAdd": "Tag toevoegen…", + "tagRemove": "Verwijderen", + "tagMax": "Tot {{n}} tags per spoel", + "tagsEdit": "Tags bewerken", + "tagsModalTitle": "Tags toevoegen", + "tagsSearchCreate": "Zoek om een tag te vinden of aan te maken", + "tagsCreate": "\"{{tag}}\" toevoegen", + "tagsToAdd": "Toe te voegen", + "tagsAvailable": "Beschikbaar", + "tagsFrequent": "Vaak gebruikt", + "tagsSave": "Opslaan", + "sortBy": "Sorteren op", + "sortDir": "Sorteerrichting", + "toolRepairPlus": "TigerTag+ herstellen", + "toolRepairPlusTip": "Zet je TigerTag+ terug naar fabrieksstaat — precies zoals op de dag dat je het materiaal kocht.", + "toolRepairNoChip": "Chip niet op een lezer", + "toolRepairNoBackup": "Nog geen back-up", + "toolRepairWriting": "Herstellen…", + "toolRepairDone": "Hersteld ✓", + "toolRepairAlready": "Al intact ✓", + "toolRepairFailed": "Herstellen mislukt", + "backupBadge": "Handtekening geback-upt", + "toolFormatRfid": "{{tier}} wissen", + "toolFormatRfid2": "Beide {{tier}}-chips wissen", + "toolFormatRfidTip": "Reset de TigerTag zodat hij herbruikbaar is, en verwijdert het materiaal uit je inventaris", + "toolEraseRfid": "Recyclen naar NFC", + "toolEraseRfid2": "Beide chips recyclen naar NFC", + "toolEraseRfidTip": "Recyclet de chip naar een gewone NFC-tag (leeg NDEF-formaat) — hij verlaat het TigerTag-formaat volledig. Het materiaal wordt uit je inventaris verwijderd.", + "toolMeasureColorTip": "Leest de echte kleur van je filament met een TD1S-sensor en slaat die hier op.", + "toolMeasureTdTip": "Meet hoe doorschijnend je filament is (TD) met een TD1S-sensor.", + "toolEditImgTip": "Wijzigt de afbeelding die voor dit materiaal wordt getoond.", + "twinLinkActionTip": "Koppelt deze spoel aan zijn tweeling — de tweede chip van dezelfde spoel — zodat beide gesynchroniseerd blijven.", + "toolRemoveFromRackTip": "Haalt deze spoel uit zijn opslagplek — hij blijft in je inventaris.", + "encodeCloudTip": "Schrijft dit cloudmateriaal op de lege chip op je lezer — het wordt een echte TigerTag.", + "burnRfidTip": "Schrijft dit materiaal op een chip die op je lezer ligt.", + "toolRefreshApiTip": "Haalt de nieuwste catalogusinfo op voor deze TigerTag+ (foto, specificaties…).", + "snapPaxxUpdate": "Er is nieuwe firmware beschikbaar — download hem hierboven.", + "snapPaxxUpToDate": "Deze printer heeft de nieuwste firmware. Niets te doen.", + "snapPaxxStep1Title": "Aanbevolen firmware", + "notifRemindLater": "Later herinneren", + "rackViewMode": "Plekweergave", + "rackViewColor": "Kleurvulling", + "rackViewPhoto": "Fotoweergave", + "bulkSelectMode": "Selecteren", + "bulkDelete": "Verwijderen", + "bulkTags": "Tags", + "bulkFavorite": "Favoriet", + "bulkLike": "Te bestellen", + "bulkTagsTitle": "Tags toevoegen ({{n}})", + "printerEndsAt": "Eindigt om", + "printerPreview": "Voorbeeld", + "snapPaxxDownload": "{{tag}}.bin downloaden", + "snapPaxxViewRelease": "Laatste release bekijken", + "snapPaxxWatchExplainer": "Uitleg bekijken", + "snapPaxxCoffeeTitle": "Steun Paxx op Buy Me a Coffee", + "snapPaxxStep2Title": "Installeer de firmware", + "snapPaxxStep2Sub": "Lokale update via USB", + "snapPaxxStep3Title": "TigerTag-lezing inschakelen", + "snapPaxxStep3Sub": "Kies OpenRFID bij Filament Detection", + "snapPaxxShowScreenshot": "Schermafbeelding tonen", + "snapPaxxTutoTitle": "Filament Detection → OpenRFID", + "snapPaxxOpenConfig": "Firmwareconfiguratie openen", + "snapPaxxDocs": "Documentatie", + "snapPaxxStep1Desc": "Installeer voor de beste ervaring met Tiger Studio op de Snapmaker U1 de door de community onderhouden Paxx U1 Extended Firmware. Deze ontgrendelt native NFC-chipherkenning voor filament, uitgebreide AMS-slotondersteuning en extra printbedieningsfuncties die niet in de standaardfirmware zitten.", + "snapPaxxStep2Li1": "Zet het .bin-bestand op een FAT32-geformatteerde USB-stick.", + "snapPaxxStep2Li2": "Op de printer: Instellingen → Over → Firmwareversie → Lokale update", + "snapPaxxStep2Li3": "Kies het .bin-bestand en bevestig.", + "snapPaxxStep3Desc": "Open op de firmwareconfiguratiepagina Filament Detection ↗ en kies OpenRFID.", + "vatCountryLabel": "Land", + "vatCountryHint": "Bepaalt het btw-tarief en de valuta voor je filamentprijzen.", + "vatCustomOption": "Aangepast tarief", + "vatCustomLabel": "Instellingen voor aangepast tarief", + "vatCustomRateLabel": "Belastingtarief", + "vatCustomRateHint": "bijv. 10 voor 10%", + "vatCustomCurrencyLabel": "Valuta (code)", + "vatCustomCurrencyHint": "bijv. EUR, USD, CHF", + "vatCustomSymbolLabel": "Symbool", + "vatCustomSymbolHint": "bijv. €, $, £", + "priceInputLabel": "Prijzen", + "reorderPanelTitle": "Productinfo", + "reorderOpenProductCard": "Productkaart openen", + "reorderInStock": "Op voorraad: {{n}}", + "reorderStockSection": "Voorraad", + "toolReorder": "Productinfo", + "toolReorderTip": "Alles over dit product — koopknop, prijs, voorraadmelding, notities en tags. Geldt voor elke identieke spoel.", + "toolReorderBuy": "Opnieuw bestellen", + "toolReorderBuyTip": "Direct naar de winkel om er meer van te halen.", + "reorderBuyLink": "Koop-link", + "reorderBuyLinkPlaceholder": "Plak de winkel-URL…", + "reorderOpenLink": "Winkel openen", + "reorderAddLink": "Koop-link toevoegen", + "reorderEditLink": "Link wijzigen", + "reorderPrice": "Prijs per spoel", + "reorderAddPrice": "Prijs toevoegen", + "reorderSaveLater": "Later kopen", + "reorderStopTracking": "Stoppen met volgen", + "reorderMoveToCart": "Aan winkelwagen toevoegen", + "reorderDragHint": "Sleep om te herschikken of te verplaatsen", + "reorderEditPrice": "Prijs wijzigen", + "reorderEditMin": "Minimum wijzigen", + "reorderEditRef": "Bewerken", + "reorderAddMin": "Minimum toevoegen", + "notifLowStockTitle": "Lage voorraad", + "notifLowStockText": "Bijna op — nog {{n}}/{{min}} spoelen over.", + "reorderHT": "excl. btw", + "reorderTTC": "incl. btw", + "reorderVat": "Btw {{rate}}%", + "reorderMinStock": "Minimumvoorraad", + "reorderMinStockHint": "We melden het zodra je onder dit aantal spoelen komt.", + "reorderNote": "Notitie", + "reorderNotePlaceholder": "Een notitie voor je toekomstige zelf…", + "reorderRefs": "Referenties", + "productWishlist": "Verlanglijst", + "productLike": "Te bestellen", + "productLikeTip": "Zet een filament in de winkelwagen en het komt bij « Te bestellen » terecht, zodat je nooit zonder zit.", + "productFavorite": "Favoriet", + "productInfoPage": "Productinfopagina", + "productFavoriteTip": "Geef je vaste producten een ster, als een bladwijzer — de producten waar je altijd naar teruggrijpt.", + "productImportedFrom": "Toegevoegd vanuit {{name}}", + "productFromUnlinked": "Niet meer bij je vrienden", + "productFromLabel": "Toegevoegd vanuit", + "productCreateCloud": "Materiaal", + "productCreateCloudTip": "Voegt een nieuwe spoel van precies dit filament toe aan je inventaris — geen NFC-chip nodig.", + "productCloudCreated": "TigerData aangemaakt — staat in je inventaris.", + "reorderRemove": "Verwijderen", + "reorderSaved": "Opgeslagen", + "reorderRemoved": "Verwijderd", + "pvCartTotal": "Geschat totaal", + "pvOrderEmpty": "Niets te bestellen — je zit vol voorraad.", + "pvCartTitle": "Winkelwagen", + "pvSavedTitle": "Bewaard voor later", + "pvSavedEmpty": "Sleep items hierheen om ze later te kopen", + "pvFavesEmpty": "Nog geen geliefde of favoriete producten.", + "pvFriendFavesEmpty": "Deze vriend heeft nog niets een ster gegeven", + "pcNoStock": "Momenteel niet in deze inventaris", + "pvStockRatio": "Voorraad: {{have}} / {{need}}", + "pvToOrder": "{{n}} te bestellen", + "pvPayment": "Betaling", + "pvSubtotal": "Subtotaal", + "pvItems": "{{n}} stuks", + "pvTax": "Geschatte belasting", + "pvOrderTotal": "Totaal", + "viewGroupLists": "Lijsten", + "listUntitled": "Naamloze lijst", + "listCreate": "Nieuwe lijst", + "listAddTo": "Aan een lijst toevoegen", + "listRemoveItem": "Van lijst verwijderen", + "listRename": "Hernoemen", + "listDelete": "Lijst verwijderen", + "listDeleteConfirm": "Deze lijst verwijderen?", + "listEmpty": "Hier staat nog niets — voeg filamenten toe vanaf een materiaal- of productkaart.", + "listEmptyFriend": "Deze lijst is momenteel leeg.", + "listNoneTitle": "Nog geen lijsten", + "listNoneSub": "Maak een lijst van de filamenten die je wilt, en deel hem daarna met vrienden of familie voor verjaardagen en meer.", + "listFriendEmpty": "{{name}} heeft nog geen lijsten gemaakt.", + "listModalTitle": "Lijst maken", + "listModalEditTitle": "Lijst beheren", + "listModalNameLabel": "Lijstnaam", + "listModalTypeLabel": "Lijsttype", + "listTypePrivateDesc": "Alleen jij", + "listTypeFriendsDesc": "Je vrienden", + "listTypePublicDesc": "Deelbare link", + "listTypeDropHint": "Zet hier een lijst neer", + "listModalNamePh": "Mijn lijst", + "listModalHelp": "Je lijsten blijven privé — deel er een met vrienden of via een openbare link wanneer je wilt.", + "listModalEventLabel": "Vier je een gebeurtenis? (optioneel)", + "listEventLabel": "Gebeurtenis", + "listMessageLabel": "Bericht", + "listDetailsTitle": "Details", + "listItemsLabel": "Items", + "listModalMessageLabel": "Bericht voor je vrienden", + "listModalMessageLabelSelf": "Een notitie voor je toekomstige zelf", + "listModalMessagePh": "Een klein berichtje voor wie er gaat winkelen — kleurtips, een bedankje, wat dan ook.", + "listModalVisibility": "Privacy", + "visPrivate": "Privé (alleen ik)", + "visFriends": "Vrienden", + "visPublic": "Openbaar", + "visPrivateShort": "Privé", + "listShareCopy": "Link kopiëren", + "listShareDownloadQr": "QR-code downloaden", + "qrCustomizeLabel": "QR-stijl", + "qrLogoToggle": "Logo tonen in de QR-code", + "listSharePublicHint": "Iedereen met deze link kan hem bekijken — geen account nodig.", + "listShareText": "Bekijk mijn verlanglijst «{{name}}»", + "listShareCopied": "Gekopieerd!", + "listModalOccasionPh": "Verjaardag, Kerst, Vaderdag…", + "listModalCreate": "Aanmaken", + "listModalSave": "Opslaan", + "listBuy": "Kopen", + "listSidebarTitle": "Jouw lijsten", + "listLayoutRows": "Lijst", + "sectionBuy": "Prijs & kopen", + "statValueTip": "Waarde van het resterende filament: prijs × (resterend gewicht ÷ capaciteit). Een deels gebruikte spoel is minder waard dan een volle.", + "editSocialsLabel": "Sociale links", + "editSocialsPublicNote": "Zichtbaar voor je vrienden en op je openbare profiel", + "editSocialsPlaceholder": "Plak een profiellink…", + "pvQty": "Aantal", + "reorderNoLink": "Geen koop-link", + "listModalMessageSelfPh": "Voorkeuren, een herinnering, waarom je het wilt…", + "ctxCut": "Knippen", + "ctxCopy": "Kopiëren", + "ctxPaste": "Plakken", + "ctxSelectAll": "Alles selecteren", + "cartAddNote": "Notitie toevoegen", + "cartNotePh": "bijv. ook 3 nozzles + een bedreiniger", + "attachTitle": "Aangepaste links", + "attachLabelPh": "Naam (optioneel)", + "attachAdd": "Link toevoegen", + "attachRemove": "Verwijderen", + "attachEmpty": "Voeg een datasheet, een tutorial, een video toe — dit blijft bij elke spoel van dit filament.", + "attachLocked": "+1 link — binnenkort te ontgrendelen", + "btnCancel": "Annuleren", + "attachModalTitle": "Link toevoegen", + "attachModalUrl": "Link", + "attachModalErr": "Voer een geldige link in", + "productAlreadyInCart": "Al in je winkelwagen", + "attachModalEditTitle": "Link bewerken", + "attachModalSave": "Opslaan", + "cwWhenSaving": "Bij opslaan", + "cwUsedBy": "Elke spoel houdt zijn eigen kopie van dit gewicht bij.", + "cwLinkedSpools": { + "one": "1 spoel gebruikt momenteel deze container.", + "other": "{{n}} spoelen gebruiken momenteel deze container." + }, + "cwApplyAll": { + "one": "De spoel met deze waarde bijwerken", + "other": "Alle {{n}} spoelen met deze waarde bijwerken" + }, + "cwKeepCurrent": "Huidige spoelwaarden behouden", + "usbScaleWeighing": "Wegen…", + "usbScaleApplied": "Opgeslagen", + "usbScaleConfirmTitle": "Is dit de spoel op de weegschaal?", + "usbScaleConfirmYes": "Ja, bijwerken", + "usbScaleConfirmNo": "Nee", + "usbScaleGrossNet": "{{g}} g op de weegschaal → {{net}} g filament", + "usbScaleNeedContainer": "Vertel me op welke lege spoel dit filament zit, zodat de rekensom klopt", + "usbScalePickContainer": "Kies de spoel", + "usbScaleUidMoved": "De tag is tijdens het wegen verplaatst — leg hem terug en we proberen het opnieuw", + "usbScaleTwoSpools": "Twee verschillende spoelen gedetecteerd — één tegelijk, graag", + "usbScaleUnknownChip": "Deze tag staat nog niet in je inventaris", + "usbScaleOver": "Te zwaar voor de weegschaal", + "usbScaleError": "Kon het gewicht niet opslaan — probeer opnieuw", + "usbScaleAsleep": "De weegschaal is in slaap gevallen — tik op de knop om hem te wekken", + "ttagDropHint": "Sleep je .ttag hierheen om te importeren", + "ttagExportShort": "Exporteren", + "ttagImportShort": "Importeren", + "ttagExportEmpty": "Niets om te exporteren", + "ttagModeMixed": "Een mix — je eigen back-ups komen ongewijzigd terug, de rest komt binnen als nieuwe kopieën.", + "ttagFilesCount": "{{n}} bestanden", + "ttagSkipped": "{{n}} genegeerd — geen geldig .ttag-bestand", + "ttagRejected": { + "one": "{{n}} materiaal geweigerd — onvolledige gegevens", + "other": "{{n}} materialen geweigerd — onvolledige gegevens" + }, + "ttagDropzoneTitle": "Sleep je .ttag-bestanden hierheen", + "ttagBrowse": "Bestanden uploaden", + "ttagOr": "of", + "ttagUrlPlaceholder": "https://", + "ttagFetch": "Ophalen", + "ttagUrlInvalid": "Dat lijkt geen geldige link.", + "ttagUrlFetchErr": "Kon die link niet ophalen. Controleer of het een directe .ttag-URL is.", + "ttagFromLink": "Uploaden via URL", + "ttagAdd": "Toevoegen", + "ttagUploadPreview": "Voorbeeld", + "ttagChooseMode": "Hoe wil je deze toevoegen?", + "ttagModeRestoreLabel": "Herstellen", + "ttagModeRestoreHint": "Een volledige import, precies zoals geëxporteerd — elk veld identiek hersteld.", + "ttagModeImportLabel": "Importeren", + "ttagModeImportHint": "Elk materiaal wordt opnieuw aangemaakt als nieuwe TigerData, gereset naar een volledig nieuwe spoel — geen chip geclaimd.", + "ttagSummarySel": "{{n}} van {{total}} materialen geselecteerd", + "catalogSearchPh": "Merk, naam, kleur, gewicht, SKU, streepjescode…", + "catalogSyncing": "Catalogus ophalen…", + "catalogSyncError": "Kon de catalogus niet bereiken. Probeer het zo nog eens.", + "catalogCount": "{{n}} van {{total}} producten", + "catalogCreateOk": "Toegevoegd — {{name}}. Niets meer te typen.", + "catalogCreateError": "Dat product is niet gelukt. Probeer het nog eens.", + "catalogAdd": "Aan mijn inventaris toevoegen", + "bulkHiddenWarn": { + "one": "1 geselecteerd item is verborgen door het huidige filter.", + "other": "{{n}} geselecteerde items zijn verborgen door het huidige filter." + }, + "printerCloudMode": "Bereikt via de cloud", + "holdToConfirmTip": "Houd {{s}} s ingedrukt om te bevestigen" +} diff --git a/scripts/check-i18n-consistency.mjs b/scripts/check-i18n-consistency.mjs index 2819232..f3f9116 100755 --- a/scripts/check-i18n-consistency.mjs +++ b/scripts/check-i18n-consistency.mjs @@ -24,7 +24,7 @@ import { fileURLToPath } from "node:url"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const LOCALES_DIR = path.join(__dirname, "..", "renderer", "locales"); const REFERENCE = "en"; -const LOCALES = ["en", "fr", "de", "es", "it", "zh", "pt", "pt-pt", "pl", "ru"]; +const LOCALES = ["en", "fr", "de", "es", "it", "zh", "pt", "pt-pt", "pl", "ru", "nl"]; // ───────────────────────────────────────────────────────────────────── // helpers diff --git a/scripts/i18n-add.mjs b/scripts/i18n-add.mjs index d60eebb..b5d2bb5 100644 --- a/scripts/i18n-add.mjs +++ b/scripts/i18n-add.mjs @@ -51,7 +51,7 @@ const LOCALES_DIR = path.join(__dirname, "..", "renderer", "locales"); // Hard-coded list — same set the renderer ships with. Adding a new // locale to the renderer = update this array and ship a new file. -const LOCALES = ["en", "fr", "de", "es", "it", "zh", "pt", "pt-pt", "pl", "ru"]; +const LOCALES = ["en", "fr", "de", "es", "it", "zh", "pt", "pt-pt", "pl", "ru", "nl"]; // ── CLI parsing ─────────────────────────────────────────────────────── function parseArgs(argv) { @@ -109,7 +109,7 @@ Examples: node scripts/i18n-add.mjs toolboxNew \\ fr="Nouveau" en="New" de="Neu" \\ es="Nuevo" it="Nuovo" zh="新建" \\ - pt="Novo" pt-pt="Novo" pl="Nowy" ru="Новый" + pt="Novo" pt-pt="Novo" pl="Nowy" ru="Новый" nl="Nieuw" node scripts/i18n-add.mjs toolboxNew --after toolboxTitle \\ --json '{"fr":"Nouveau","en":"New"}'