186 files

This commit is contained in:
Home Assistant Version Control
2026-09-14 12:56:59 +00:00
parent 6be1e92941
commit bd8280defe
186 changed files with 14904 additions and 1087 deletions
+1 -1
View File
@@ -1 +1 @@
{"pid": 71, "version": 1, "ha_version": "2026.9.2", "start_ts": 1789331676.107018} {"pid": 71, "version": 1, "ha_version": "2026.9.2", "start_ts": 1789390417.876061}
+5 -5
View File
@@ -206,7 +206,7 @@
}, },
{ {
"id": "d3c3e144a91247ce8ac524814737d7f8", "id": "d3c3e144a91247ce8ac524814737d7f8",
"url": "/hacsfiles/lovelace-wallpanel/wallpanel.js?hacstag=3095064164662", "url": "/hacsfiles/lovelace-wallpanel/wallpanel.js?hacstag=3095064164663",
"type": "module" "type": "module"
}, },
{ {
@@ -315,13 +315,13 @@
"type": "module" "type": "module"
}, },
{ {
"id": "01719b0125f941f38ea1e62eead86a94", "id": "1a4939ce1d2b47f89502176d3c5ac6e7",
"url": "/climate_scheduler/static/climate-scheduler-card.js?v=1.15.1", "url": "/taskmate/taskmate-sounds.js?v=5.6.0",
"type": "module" "type": "module"
}, },
{ {
"id": "1a4939ce1d2b47f89502176d3c5ac6e7", "id": "e74d5108a99f4ffbbb445c9c41a17282",
"url": "/taskmate/taskmate-sounds.js?v=5.6.0", "url": "/climate_scheduler/static/climate-scheduler-card.js?v=1.15.1",
"type": "module" "type": "module"
} }
] ]
+37 -3
View File
@@ -8,6 +8,7 @@ https://community.home-assistant.io/t/echo-devices-alexa-as-media-player-testers
""" """
import asyncio import asyncio
import contextlib
from datetime import datetime, timedelta from datetime import datetime, timedelta
from json import JSONDecodeError, loads from json import JSONDecodeError, loads
import logging import logging
@@ -92,6 +93,7 @@ from .const import (
LAST_CALLED_SUCCESS_PACE_S, LAST_CALLED_SUCCESS_PACE_S,
LAST_PING_MAX_AGE_SECONDS, LAST_PING_MAX_AGE_SECONDS,
LAST_PUSH_INACTIVITY_SECONDS, LAST_PUSH_INACTIVITY_SECONDS,
LOGIN_MAX_WAIT_S,
MIN_TIME_BETWEEN_FORCED_SCANS, MIN_TIME_BETWEEN_FORCED_SCANS,
MIN_TIME_BETWEEN_SCANS, MIN_TIME_BETWEEN_SCANS,
NOTIFICATION_COOLDOWN, NOTIFICATION_COOLDOWN,
@@ -691,6 +693,14 @@ async def async_setup_entry(hass, config_entry):
hass.data[DATA_ALEXAMEDIA].setdefault("accounts", {}) hass.data[DATA_ALEXAMEDIA].setdefault("accounts", {})
hass.data[DATA_ALEXAMEDIA].setdefault("config_flows", {}) hass.data[DATA_ALEXAMEDIA].setdefault("config_flows", {})
hass.data[DATA_ALEXAMEDIA].setdefault("notify_service", None) hass.data[DATA_ALEXAMEDIA].setdefault("notify_service", None)
# The collector is removed when the last account unloads, so recreating it
# here re-arms boot tracking at the domain lifecycle boundary: a reload
# measures its own setup instead of the async_setup of this Home Assistant
# run. Tracking is deliberately not re-armed for an additional account,
# which would discard the stages already recorded for the loaded ones.
if not isinstance(hass.data[DATA_ALEXAMEDIA].get("metrics"), AlexaMetrics):
hass.data[DATA_ALEXAMEDIA]["metrics"] = AlexaMetrics(hass)
hass.data[DATA_ALEXAMEDIA]["metrics"].start_boot_tracking()
account = config_entry.data account = config_entry.data
email = account.get(CONF_EMAIL) email = account.get(CONF_EMAIL)
password = account.get(CONF_PASSWORD) password = account.get(CONF_PASSWORD)
@@ -824,7 +834,22 @@ async def async_setup_entry(hass, config_entry):
except (JSONDecodeError, ValueError, aiohttp.ClientError) as ex: except (JSONDecodeError, ValueError, aiohttp.ClientError) as ex:
_LOGGER.debug("[BOOT] Bootstrap cookie auth check failed: %s", ex) _LOGGER.debug("[BOOT] Bootstrap cookie auth check failed: %s", ex)
if not cookie_login_ok: if not cookie_login_ok:
await login.login(cookies=cookies) try:
async with async_timeout.timeout(LOGIN_MAX_WAIT_S):
await login.login(cookies=cookies)
except asyncio.TimeoutError as err:
# An interrupted login can leave partial request state on the
# client, which alexapy resumes from on the next attempt. Both
# hass.data and runtime_data would hand that same client to the
# retry, so drop it and let the retry build a fresh one; the
# saved cookie is left in place.
with contextlib.suppress(Exception):
await login.close()
hass.data[DATA_ALEXAMEDIA]["accounts"][email].pop("login_obj", None)
config_entry.runtime_data = None
raise ConfigEntryNotReady(
f"Login did not complete within {LOGIN_MAX_WAIT_S:.0f}s"
) from err
_LOGGER.debug("[BOOT] login completed in %.2fs", time.monotonic() - _t) _LOGGER.debug("[BOOT] login completed in %.2fs", time.monotonic() - _t)
_t = time.monotonic() _t = time.monotonic()
if await test_login_status(hass, config_entry, login): if await test_login_status(hass, config_entry, login):
@@ -973,8 +998,12 @@ async def setup_alexa(hass, config_entry, login_obj: AlexaLogin):
for binary_sensor in hass.data[DATA_ALEXAMEDIA]["accounts"][email][ for binary_sensor in hass.data[DATA_ALEXAMEDIA]["accounts"][email][
"entities" "entities"
].get("binary_sensor", []): ].get("binary_sensor", []):
if binary_sensor.enabled: # AmazonKidsSensor is stored alongside the coordinator-backed
entities_to_monitor.add(binary_sensor.alexa_entity_id) # AlexaContact sensors but is not derived from an Alexa entity: it
# polls the Echo on its own interval and has no alexa_entity_id.
alexa_entity_id = getattr(binary_sensor, "alexa_entity_id", None)
if alexa_entity_id and binary_sensor.enabled:
entities_to_monitor.add(alexa_entity_id)
for guard in ( for guard in (
hass.data[DATA_ALEXAMEDIA]["accounts"][email]["entities"] hass.data[DATA_ALEXAMEDIA]["accounts"][email]["entities"]
@@ -3123,6 +3152,11 @@ async def async_unload_entry(hass, entry) -> bool:
if alexa_services: if alexa_services:
await alexa_services.unregister() await alexa_services.unregister()
hass.data[DATA_ALEXAMEDIA].pop("services") hass.data[DATA_ALEXAMEDIA].pop("services")
# Per-run collectors recreated by the next setup. Leaving them behind
# keeps DATA_ALEXAMEDIA truthy, so the data structure below is never
# removed and stale boot metrics survive into the next setup.
hass.data[DATA_ALEXAMEDIA].pop("metrics", None)
hass.data[DATA_ALEXAMEDIA].pop("notify_service", None)
if hass.data[DATA_ALEXAMEDIA].get("config_flows") == {}: if hass.data[DATA_ALEXAMEDIA].get("config_flows") == {}:
_LOGGER.debug("Removing config_flows data") _LOGGER.debug("Removing config_flows data")
async_dismiss_persistent_notification( async_dismiss_persistent_notification(
@@ -202,7 +202,6 @@ class AmazonKidsSensor(BinarySensorEntity):
"""Attach to the Echo device.""" """Attach to the Echo device."""
return { return {
"identifiers": {(DATA_ALEXAMEDIA, self._client.unique_id)}, "identifiers": {(DATA_ALEXAMEDIA, self._client.unique_id)},
"via_device": (DATA_ALEXAMEDIA, self._client.unique_id),
} }
async def async_added_to_hass(self): async def async_added_to_hass(self):
+3
View File
@@ -99,6 +99,9 @@ LAST_CALLED_429_BACKOFF_MAX_S = 15 * 60.0
LAST_CALLED_CONN_BACKOFF_S = 10.0 LAST_CALLED_CONN_BACKOFF_S = 10.0
LAST_CALLED_LOGIN_BACKOFF_S = 30.0 LAST_CALLED_LOGIN_BACKOFF_S = 30.0
# Deadlock guard for AlexaLogin.login() during config entry setup.
LOGIN_MAX_WAIT_S = 600.0
# Tuning constants for the per-account last-called probe worker # Tuning constants for the per-account last-called probe worker
LAST_CALLED_DEBOUNCE_S = 3.5 # coalesce bursty pushes, but stay snappy LAST_CALLED_DEBOUNCE_S = 3.5 # coalesce bursty pushes, but stay snappy
LAST_CALLED_RETRY_DELAY_S = 4.0 # wider retry cadence for delayed routine history LAST_CALLED_RETRY_DELAY_S = 4.0 # wider retry cadence for delayed routine history
+2 -2
View File
@@ -9,10 +9,10 @@
"issue_tracker": "https://github.com/alandtse/alexa_media_player/issues", "issue_tracker": "https://github.com/alandtse/alexa_media_player/issues",
"loggers": ["alexapy", "authcaptureproxy"], "loggers": ["alexapy", "authcaptureproxy"],
"requirements": [ "requirements": [
"alexapy==1.30.0", "alexapy==1.30.1",
"packaging>=20.3", "packaging>=20.3",
"wrapt>=1.14.0", "wrapt>=1.14.0",
"dictor>=0.1.12,<0.2" "dictor>=0.1.12,<0.2"
], ],
"version": "5.16.0" "version": "5.16.1"
} }
-1
View File
@@ -315,7 +315,6 @@ class AlexaMediaSwitch(SwitchDevice, AlexaMedia):
"""Return device_info for device registry.""" """Return device_info for device registry."""
return { return {
"identifiers": {(ALEXA_DOMAIN, self._client.unique_id)}, "identifiers": {(ALEXA_DOMAIN, self._client.unique_id)},
"via_device": (ALEXA_DOMAIN, self._client.unique_id),
} }
@property @property
@@ -1426,6 +1426,15 @@ async def async_setup_entry(hass: HomeAssistant, entry: MaintenanceSupporterConf
await shopping_sync.async_setup() await shopping_sync.async_setup()
hass.data[DOMAIN][SHOPPING_SYNC_KEY] = shopping_sync hass.data[DOMAIN][SHOPPING_SYNC_KEY] = shopping_sync
# D#183: per-task mirror into external to-do lists — same lifecycle
# as the shopping sync (global entry owns it).
from .helpers.todo_mirror import TODO_MIRROR_KEY, TodoMirror
if TODO_MIRROR_KEY not in hass.data[DOMAIN]:
todo_mirror = TodoMirror(hass)
await todo_mirror.async_setup()
hass.data[DOMAIN][TODO_MIRROR_KEY] = todo_mirror
# One-time migration: auto-enable advanced feature flags for existing users # One-time migration: auto-enable advanced feature flags for existing users
options = dict(entry.options or entry.data) options = dict(entry.options or entry.data)
if CONF_ADVANCED_ADAPTIVE not in options: if CONF_ADVANCED_ADAPTIVE not in options:
@@ -2000,6 +2009,11 @@ async def async_unload_entry(hass: HomeAssistant, entry: MaintenanceSupporterCon
shopping_sync = hass.data.get(DOMAIN, {}).pop(SHOPPING_SYNC_KEY, None) shopping_sync = hass.data.get(DOMAIN, {}).pop(SHOPPING_SYNC_KEY, None)
if shopping_sync is not None: if shopping_sync is not None:
shopping_sync.async_teardown() shopping_sync.async_teardown()
from .helpers.todo_mirror import TODO_MIRROR_KEY
todo_mirror = hass.data.get(DOMAIN, {}).pop(TODO_MIRROR_KEY, None)
if todo_mirror is not None:
todo_mirror.async_teardown()
text_index = hass.data.get(DOMAIN, {}).get(DOCUMENT_TEXT_INDEX_KEY) text_index = hass.data.get(DOMAIN, {}).get(DOCUMENT_TEXT_INDEX_KEY)
if text_index is not None: if text_index is not None:
text_index.cancel() text_index.cancel()
@@ -30,6 +30,8 @@ from .const import (
CONF_ADVANCED_PREDICTIONS, CONF_ADVANCED_PREDICTIONS,
CONF_ADVANCED_SCHEDULE_TIME, CONF_ADVANCED_SCHEDULE_TIME,
CONF_ADVANCED_SEASONAL, CONF_ADVANCED_SEASONAL,
CONF_BATTERY_LOW_PERCENT,
CONF_BATTERY_RECOVERED_PERCENT,
CONF_BUDGET_ALERT_THRESHOLD, CONF_BUDGET_ALERT_THRESHOLD,
CONF_BUDGET_ALERTS_ENABLED, CONF_BUDGET_ALERTS_ENABLED,
CONF_BUDGET_CURRENCY, CONF_BUDGET_CURRENCY,
@@ -55,6 +57,7 @@ from .const import (
CONF_OPERATOR_WRITE_ENABLED, CONF_OPERATOR_WRITE_ENABLED,
CONF_PANEL_ENABLED, CONF_PANEL_ENABLED,
CONF_PANEL_TITLE, CONF_PANEL_TITLE,
CONF_PART_SEARCH_URL_TEMPLATE,
CONF_QUIET_HOURS_ENABLED, CONF_QUIET_HOURS_ENABLED,
CONF_QUIET_HOURS_END, CONF_QUIET_HOURS_END,
CONF_QUIET_HOURS_START, CONF_QUIET_HOURS_START,
@@ -620,6 +623,15 @@ class GlobalOptionsFlow(OptionsFlow):
if isinstance(raw_title, str): if isinstance(raw_title, str):
user_input[CONF_PANEL_TITLE] = raw_title.strip()[:MAX_PANEL_TITLE_LENGTH] user_input[CONF_PANEL_TITLE] = raw_title.strip()[:MAX_PANEL_TITLE_LENGTH]
# D#182: shopping-search template — blank = automatic (country,
# then UI language); otherwise an http(s) URL with {q}.
from .helpers.parts import valid_search_template
raw_tpl = (user_input.get(CONF_PART_SEARCH_URL_TEMPLATE) or "").strip()
if raw_tpl and not valid_search_template(raw_tpl):
errors[CONF_PART_SEARCH_URL_TEMPLATE] = "invalid_search_template"
user_input[CONF_PART_SEARCH_URL_TEMPLATE] = raw_tpl
if not errors: if not errors:
return self._save_and_return(user_input) return self._save_and_return(user_input)
@@ -667,6 +679,30 @@ class GlobalOptionsFlow(OptionsFlow):
mode=selector.NumberSelectorMode.BOX, mode=selector.NumberSelectorMode.BOX,
) )
), ),
# #146 / #180: the battery fleet's low floor and the level a
# low battery must rise above to count as replaced.
vol.Optional(
CONF_BATTERY_LOW_PERCENT,
default=self._opt(CONF_BATTERY_LOW_PERCENT),
): selector.NumberSelector(
selector.NumberSelectorConfig(
min=int_range(CONF_BATTERY_LOW_PERCENT)[0],
max=int_range(CONF_BATTERY_LOW_PERCENT)[1],
step=1,
mode=selector.NumberSelectorMode.BOX,
)
),
vol.Optional(
CONF_BATTERY_RECOVERED_PERCENT,
default=self._opt(CONF_BATTERY_RECOVERED_PERCENT),
): selector.NumberSelector(
selector.NumberSelectorConfig(
min=int_range(CONF_BATTERY_RECOVERED_PERCENT)[0],
max=int_range(CONF_BATTERY_RECOVERED_PERCENT)[1],
step=1,
mode=selector.NumberSelectorMode.BOX,
)
),
vol.Optional( vol.Optional(
CONF_NOTIFICATIONS_ENABLED, CONF_NOTIFICATIONS_ENABLED,
default=self._opt(CONF_NOTIFICATIONS_ENABLED), default=self._opt(CONF_NOTIFICATIONS_ENABLED),
@@ -698,6 +734,12 @@ class GlobalOptionsFlow(OptionsFlow):
CONF_PANEL_TITLE, CONF_PANEL_TITLE,
description={"suggested_value": current.get(CONF_PANEL_TITLE, "")}, description={"suggested_value": current.get(CONF_PANEL_TITLE, "")},
): selector.TextSelector(selector.TextSelectorConfig(type=selector.TextSelectorType.TEXT)), ): selector.TextSelector(selector.TextSelectorConfig(type=selector.TextSelectorType.TEXT)),
# D#182: shopping-search template with {q}; blank = automatic
# (Amazon store of the HA country, then of the UI language).
vol.Optional(
CONF_PART_SEARCH_URL_TEMPLATE,
description={"suggested_value": current.get(CONF_PART_SEARCH_URL_TEMPLATE, "")},
): selector.TextSelector(selector.TextSelectorConfig(type=selector.TextSelectorType.URL)),
} }
), ),
errors=errors, errors=errors,
@@ -307,6 +307,9 @@ COMPLETION_SOURCES = (
"voice", "voice",
"notification_action", "notification_action",
"shopping_list", "shopping_list",
# D#183: checked off in a mirrored external to-do list — a person did
# it, so it is NOT automatic (same class as "todo").
"todo_mirror",
"service", "service",
"auto_recovery", "auto_recovery",
) )
@@ -321,8 +324,15 @@ COMPLETION_PROVENANCE_NOTES: dict[str, str] = {
"notification_action": "Completed from the notification", "notification_action": "Completed from the notification",
"nfc": "Completed via NFC tag", "nfc": "Completed via NFC tag",
"shopping_list": "Completed from the shopping list", "shopping_list": "Completed from the shopping list",
"todo_mirror": "Completed from a mirrored to-do list",
} }
# D#183: per-task mirror into external ``todo.*`` lists (family members work
# from their to-do app; checking the row off completes the task here). The
# list of entity ids is capped and shape-validated at every write path.
MAX_MIRROR_TODO_LISTS = 5
MIRROR_TODO_ENTITY_PATTERN = r"^todo\.[a-z0-9_]+$"
# --- Config Keys: Notification Actions --- # --- Config Keys: Notification Actions ---
CONF_ACTION_COMPLETE_ENABLED = "action_complete_enabled" CONF_ACTION_COMPLETE_ENABLED = "action_complete_enabled"
CONF_ACTION_SKIP_ENABLED = "action_skip_enabled" CONF_ACTION_SKIP_ENABLED = "action_skip_enabled"
@@ -855,3 +865,13 @@ MAX_VACATION_EXEMPT_TASKS = 2000
# --- Trigger Entity Availability --- # --- Trigger Entity Availability ---
STARTUP_GRACE_PERIOD_SECONDS = 300 # 5 minutes STARTUP_GRACE_PERIOD_SECONDS = 300 # 5 minutes
MISSING_ENTITY_THRESHOLD_REFRESHES = 6 # ~30 min at 5-min intervals MISSING_ENTITY_THRESHOLD_REFRESHES = 6 # ~30 min at 5-min intervals
# --- Battery fleet hysteresis (#180) ---
# A battery that went low stays counted low until its level rises ABOVE this
# percent (or a replacement is recorded) — a level oscillating around the low
# floor must not flip the fleet task's auto-complete on every dip.
CONF_BATTERY_RECOVERED_PERCENT = "battery_recovered_percent"
DEFAULT_BATTERY_RECOVERED_PERCENT = 50
BATTERY_RECOVERED_PERCENT_RANGE: tuple[int, int] = (20, 100)
# D#182: the shopping-search template is user-settable (max URL length).
MAX_PART_SEARCH_URL_TEMPLATE_LENGTH = 500
@@ -481,8 +481,23 @@ class MaintenanceCoordinator(DataUpdateCoordinator[dict[str, Any]]):
if self._todo_entity is not None and self._todo_entity.hass is not None: if self._todo_entity is not None and self._todo_entity.hass is not None:
self._todo_entity.refresh() self._todo_entity.refresh()
# D#183: mirror the due tasks into their external to-do lists (a
# no-op unless a task names one).
await self._async_sync_todo_mirror(result[CONF_TASKS])
return result return result
async def _async_sync_todo_mirror(self, task_results: dict[str, Any]) -> None:
"""Hand this refresh's results to the to-do mirror (helpers/todo_mirror)."""
from .helpers.todo_mirror import TODO_MIRROR_KEY
mirror = self.hass.data.get(DOMAIN, {}).get(TODO_MIRROR_KEY)
if mirror is None:
return
await mirror.async_sync_entry(
self.entry.entry_id, task_results, store=self._store, object_name=self.maintenance_object.name
)
async def _evaluate_trigger_fallback(self, task: MaintenanceTask, task_id: str) -> None: async def _evaluate_trigger_fallback(self, task: MaintenanceTask, task_id: str) -> None:
"""Evaluate trigger state as fallback (main evaluation is event-driven). """Evaluate trigger state as fallback (main evaluation is event-driven).
@@ -115,6 +115,8 @@ def _build_export_object(
# for documentation_url/notes; import mirrors these keys). # for documentation_url/notes; import mirrors these keys).
"priority": tdata.get("priority", "normal"), "priority": tdata.get("priority", "normal"),
"labels": tdata.get("labels") or [], "labels": tdata.get("labels") or [],
# D#183: mirror targets (todo.* ids) — config, so a backup keeps them.
"mirror_todo_entities": tdata.get("mirror_todo_entities") or [],
"earliest_completion_days": tdata.get("earliest_completion_days"), "earliest_completion_days": tdata.get("earliest_completion_days"),
# #170: reference number — a restore keeps "8.3" on the booklets # #170: reference number — a restore keeps "8.3" on the booklets
# already printed; a colliding import is renumbered on setup. # already printed; a colliding import is renumbered on setup.
@@ -410,15 +410,18 @@ export class MaintenanceBatteryFleetSection extends LitElement {
/** One-click fix for a detected-but-unrecorded swap: record the DETECTED /** One-click fix for a detected-but-unrecorded swap: record the DETECTED
* jump time in Battery Notes, so the forecast re-anchors on the real * jump time in Battery Notes, so the forecast re-anchors on the real
* replacement instead of the dead battery's date. */ * replacement instead of the dead battery's date. Goes through the
* backend (#181) so the swap also consumes the type-part cells from
* stock, exactly like the Replaced action. */
private async _recordJump(entityId: string, jump: { at: number; device_id: string }): Promise<void> { private async _recordJump(entityId: string, jump: { at: number; device_id: string }): Promise<void> {
if (this._marking) return; if (this._marking) return;
this._marking = true; this._marking = true;
this._error = ""; this._error = "";
try { try {
await this.hass.callService("battery_notes", "set_battery_replaced", { await this.hass.connection.sendMessagePromise({
device_id: jump.device_id, type: "maintenance_supporter/battery_fleet/record_replacement",
datetime_replaced: new Date(jump.at * 1000).toISOString(), entity_id: entityId,
replaced_at: new Date(jump.at * 1000).toISOString(),
}); });
this._recorded = [...this._recorded, entityId]; this._recorded = [...this._recorded, entityId];
await this._load(); await this._load();
@@ -54,6 +54,11 @@ interface SettingsResponse {
/** #146: household "low" floors (percent) for discovery + battery fleet. */ /** #146: household "low" floors (percent) for discovery + battery fleet. */
default_consumable_threshold?: number; default_consumable_threshold?: number;
battery_low_percent?: number; battery_low_percent?: number;
/** #180: a low battery counts as replaced only once its level is above this. */
battery_recovered_percent?: number;
/** D#182: shopping-search URL with {q} ("" = automatic) + the automatic value in effect. */
part_search_url_template?: string;
part_search_url_default?: string;
/** D#162 follow-up: per-type lifetime overrides + the computed catalog. */ /** D#162 follow-up: per-type lifetime overrides + the computed catalog. */
battery_lifetime_months?: Record<string, number>; battery_lifetime_months?: Record<string, number>;
battery_lifetimes?: { battery_lifetimes?: {
@@ -860,9 +865,23 @@ export class MaintenanceSettingsView extends LitElement {
<span class="setting-label">${t("settings_battery_low_percent", L)}</span> <span class="setting-label">${t("settings_battery_low_percent", L)}</span>
${this._intSetting("battery_low_percent", g.battery_low_percent ?? 20)} ${this._intSetting("battery_low_percent", g.battery_low_percent ?? 20)}
</label> </label>
<label class="setting-row">
<span class="setting-label">${t("settings_battery_recovered_percent", L)}</span>
${this._intSetting("battery_recovered_percent", g.battery_recovered_percent ?? 50)}
</label>
<div class="setting-hint">${t("settings_battery_recovered_percent_hint", L)}</div>
${this._renderBatteryNotesHint(L)} ${this._renderBatteryNotesHint(L)}
${this._renderBatteryLifetimes(L)} ${this._renderBatteryLifetimes(L)}
<div class="setting-hint">${t("settings_thresholds_hint", L)}</div> <div class="setting-hint">${t("settings_thresholds_hint", L)}</div>
<label class="setting-row">
<span class="setting-label">${t("settings_part_search_url", L)}</span>
<!-- D#182: no live() — same typed-input rule as the numbers above; the
placeholder shows the automatic template (country, then language). -->
<input type="url" class="part-search-url" .value=${g.part_search_url_template ?? ""}
placeholder=${g.part_search_url_default ?? ""}
@change=${(e: Event) => this._updateSetting("part_search_url_template", (e.target as HTMLInputElement).value.trim())} />
</label>
<div class="setting-hint">${t("settings_part_search_url_hint", L)}</div>
<label class="setting-row"> <label class="setting-row">
<span class="setting-label">${t("settings_row_actions", L)}</span> <span class="setting-label">${t("settings_row_actions", L)}</span>
<select .value=${live(g.row_action_style || "buttons_compact")} <select .value=${live(g.row_action_style || "buttons_compact")}
@@ -208,6 +208,8 @@ export class MaintenanceTaskDialog extends LitElement {
@state() private _customIcon = ""; @state() private _customIcon = "";
@state() private _priority = "normal"; @state() private _priority = "normal";
@state() private _labels = ""; @state() private _labels = "";
/** D#183: external todo.* lists the task is mirrored into while due. */
@state() private _mirrorTodoEntities: string[] = [];
@state() private _enabled = true; @state() private _enabled = true;
// Trigger fields // Trigger fields
@@ -415,6 +417,7 @@ export class MaintenanceTaskDialog extends LitElement {
this._customIcon = task.custom_icon || ""; this._customIcon = task.custom_icon || "";
this._priority = task.priority || "normal"; this._priority = task.priority || "normal";
this._labels = (task.labels || []).join(", "); this._labels = (task.labels || []).join(", ");
this._mirrorTodoEntities = [...(task.mirror_todo_entities || [])];
this._enabled = task.enabled !== false; this._enabled = task.enabled !== false;
this._lastPerformed = task.last_performed || ""; this._lastPerformed = task.last_performed || "";
this._nfcTagId = task.nfc_tag_id || ""; this._nfcTagId = task.nfc_tag_id || "";
@@ -571,6 +574,7 @@ export class MaintenanceTaskDialog extends LitElement {
this._customIcon = ""; this._customIcon = "";
this._priority = "normal"; this._priority = "normal";
this._labels = ""; this._labels = "";
this._mirrorTodoEntities = [];
this._enabled = true; this._enabled = true;
this._lastPerformed = ""; this._lastPerformed = "";
this._nfcTagId = ""; this._nfcTagId = "";
@@ -1322,6 +1326,8 @@ export class MaintenanceTaskDialog extends LitElement {
.split(",") .split(",")
.map((s) => s.trim()) .map((s) => s.trim())
.filter(Boolean); .filter(Boolean);
// D#183: always sent — [] clears the mirror targets.
data.mirror_todo_entities = this._mirrorTodoEntities.filter(Boolean);
data.enabled = this._enabled; data.enabled = this._enabled;
data.last_performed = this._lastPerformed || null; data.last_performed = this._lastPerformed || null;
data.nfc_tag_id = this._nfcTagId || null; data.nfc_tag_id = this._nfcTagId || null;
@@ -2714,6 +2720,34 @@ export class MaintenanceTaskDialog extends LitElement {
/> />
<div class="field-help">${t("labels_help", L)}</div> <div class="field-help">${t("labels_help", L)}</div>
</div> </div>
<div class="field mirror-todo-field">
${this._entityPickerFallback ? html`
<ms-textfield
label="${t("task_mirror_todo", L)}"
placeholder="todo.family, todo.kids"
.value=${this._mirrorTodoEntities.join(", ")}
@input=${(e: Event) => {
this._mirrorTodoEntities = (e.target as HTMLInputElement).value
.split(",").map((s: string) => s.trim()).filter(Boolean);
}}
></ms-textfield>
` : html`
<ha-form
class="entity-picker-form"
.hass=${this.hass}
.schema=${[{
name: "mirror_todo_entities",
selector: { entity: { multiple: true, domain: ["todo"] } },
}]}
.data=${{ mirror_todo_entities: this._mirrorTodoEntities }}
.computeLabel=${() => t("task_mirror_todo", L)}
@value-changed=${(e: CustomEvent) => {
const ids = ((e.detail.value as { mirror_todo_entities?: string[] }).mirror_todo_entities || []).filter(Boolean);
this._mirrorTodoEntities = ids;
}}
></ha-form>`}
<div class="field-help">${t("task_mirror_todo_hint", L)}</div>
</div>
<div class="select-row"> <div class="select-row">
<label>${t("schedule_type", L)}</label> <label>${t("schedule_type", L)}</label>
<select <select
@@ -8,6 +8,9 @@
*/ */
export const LS_KEYS = { export const LS_KEYS = {
/** #179: object-page sections the user folded away (JSON list of section
* ids: tasks | documents | parts | history) — one setting for every object. */
objectSections: "msp-object-sections",
/** #170: service-booklet print options (layout + include switches). */ /** #170: service-booklet print options (layout + include switches). */
printOptions: "msp-print-options", printOptions: "msp-print-options",
/** D#162: the battery roster starts open; a deliberate collapse is remembered. */ /** D#162: the battery roster starts open; a deliberate collapse is remembered. */
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Neplatné datum", "ws_err_invalid_date": "Neplatné datum",
"ws_err_invalid_format": "Neplatný formát", "ws_err_invalid_format": "Neplatný formát",
"ws_err_invalid_url": "Neplatný odkaz", "ws_err_invalid_url": "Neplatný odkaz",
"ws_err_invalid_mirror_todo": "Neplatný seznam úkolů",
"ws_err_not_configured": "Zatím nenastaveno", "ws_err_not_configured": "Zatím nenastaveno",
"ws_err_not_loaded": "Zatím nenačteno — zkuste to za chvíli znovu", "ws_err_not_loaded": "Zatím nenačteno — zkuste to za chvíli znovu",
"ws_err_limit_reached": "Dosažen limit", "ws_err_limit_reached": "Dosažen limit",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "Nejsou nastaveny výchozí hodnoty pro rychlé dokončení", "ws_err_no_defaults": "Nejsou nastaveny výchozí hodnoty pro rychlé dokončení",
"ws_err_self_link_device": "Objekt nelze propojit sám se sebou", "ws_err_self_link_device": "Objekt nelze propojit sám se sebou",
"ws_err_too_early": "Příliš brzy — tento úkol lze dokončit až blíže k termínu", "ws_err_too_early": "Příliš brzy — tento úkol lze dokončit až blíže k termínu",
"ws_err_invalid_search_template": "Odkaz pro vyhledávání musí být URL http(s) obsahující {q}",
"feat_schedule_time": "Plánování podle denní doby", "feat_schedule_time": "Plánování podle denní doby",
"feat_schedule_time_desc": "Úkoly se stanou po termínu v určenou denní dobu místo o půlnoci.", "feat_schedule_time_desc": "Úkoly se stanou po termínu v určenou denní dobu místo o půlnoci.",
"schedule_time_toggle": "Termín v určitou hodinu", "schedule_time_toggle": "Termín v určitou hodinu",
@@ -199,6 +201,8 @@
"labels": "Štítky", "labels": "Štítky",
"labels_placeholder": "např. bezpečnost, sezónní, viditelné-nájemci", "labels_placeholder": "např. bezpečnost, sezónní, viditelné-nájemci",
"labels_help": "Štítky oddělené čárkami pro filtrování a přehledy.", "labels_help": "Štítky oddělené čárkami pro filtrování a přehledy.",
"task_mirror_todo": "Zrcadlit do seznamů úkolů",
"task_mirror_todo_hint": "Úkol se objeví v těchto seznamech, dokud je aktuální; odškrtnutí tam ho dokončí zde.",
"priority_low": "Nízká", "priority_low": "Nízká",
"priority_normal": "Normální", "priority_normal": "Normální",
"priority_high": "Vysoká", "priority_high": "Vysoká",
@@ -496,6 +500,8 @@
"settings_default_warning": "Výchozí dny upozornění", "settings_default_warning": "Výchozí dny upozornění",
"settings_consumable_threshold": "Práh „spotřební materiál nízký“ (%)", "settings_consumable_threshold": "Práh „spotřební materiál nízký“ (%)",
"settings_battery_low_percent": "Práh „baterie slabá“ (%)", "settings_battery_low_percent": "Práh „baterie slabá“ (%)",
"settings_battery_recovered_percent": "Baterie se považuje za vyměněnou nad (%)",
"settings_battery_recovered_percent_hint": "Slabá baterie se počítá jako slabá, dokud její stav nevystoupí nad tuto hodnotu nebo není zaznamenána výměna — stav kolísající kolem prahu tak nedokončuje úlohu flotily stále dokola.",
"settings_battery_lifetimes": "Typická životnost baterií", "settings_battery_lifetimes": "Typická životnost baterií",
"settings_battery_lifetimes_hint": "Použije se jen u baterií bez procent: poznámka Battery Notes jen s typem a datem výměny nebo senzor hlásící pouze „slabá“. Splatnost = poslední výměna + tato životnost. Baterie hlásící úroveň mají prognózu z naměřeného vybíjení. Po třech výměnách daného typu nahradí medián intervalů vestavěnou hodnotu — vaše hodnota má vždy přednost.", "settings_battery_lifetimes_hint": "Použije se jen u baterií bez procent: poznámka Battery Notes jen s typem a datem výměny nebo senzor hlásící pouze „slabá“. Splatnost = poslední výměna + tato životnost. Baterie hlásící úroveň mají prognózu z naměřeného vybíjení. Po třech výměnách daného typu nahradí medián intervalů vestavěnou hodnotu — vaše hodnota má vždy přednost.",
"settings_battery_lifetime_months": "měsíců", "settings_battery_lifetime_months": "měsíců",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "ve vaší flotile", "settings_battery_lifetime_in_fleet": "ve vaší flotile",
"settings_battery_lifetime_learned_models": "Naučeno podle modelu: {list}", "settings_battery_lifetime_learned_models": "Naučeno podle modelu: {list}",
"settings_thresholds_hint": "Výchozí hodnoty pro nová Navrhovaná nastavení (zbývající procenta) a pro baterie flotily bez vlastního prahu Battery Notes. Stávající úkoly si ponechají svou hodnotu.", "settings_thresholds_hint": "Výchozí hodnoty pro nová Navrhovaná nastavení (zbývající procenta) a pro baterie flotily bez vlastního prahu Battery Notes. Stávající úkoly si ponechají svou hodnotu.",
"settings_part_search_url": "Odkaz pro vyhledávání nákupu",
"settings_part_search_url_hint": "URL s {q} místo hledaných výrazů, pro díly bez odkazu na produkt. Ponechte prázdné pro automatický obchod (podle země, jinak podle jazyka).",
"settings_value_out_of_range": "Hodnota musí být mezi {min} a {max}", "settings_value_out_of_range": "Hodnota musí být mezi {min} a {max}",
"bn_summary": "{name}: {pct} % pro {n} baterií", "bn_summary": "{name}: {pct} % pro {n} baterií",
"bn_floor_decides": "Tvůj práh {floor} % rozhoduje pro všechny; u každé baterie platí vyšší z obou prahů.", "bn_floor_decides": "Tvůj práh {floor} % rozhoduje pro všechny; u každé baterie platí vyšší z obou prahů.",
@@ -717,6 +725,8 @@
"archived": "Archivováno", "archived": "Archivováno",
"show_archived": "Zobrazit archivované", "show_archived": "Zobrazit archivované",
"hide_archived": "Skrýt archivované", "hide_archived": "Skrýt archivované",
"section_collapse": "Sbalit sekci",
"section_expand": "Rozbalit sekci",
"confirm_archive_object": "Archivovat tento objekt a jeho úkoly? Historie zůstane zachována a lze ji později obnovit.", "confirm_archive_object": "Archivovat tento objekt a jeho úkoly? Historie zůstane zachována a lze ji později obnovit.",
"settings_archive": "Archiv a uchovávání", "settings_archive": "Archiv a uchovávání",
"settings_archive_desc": "Odkládejte dokončené jednorázové úkoly bez mazání. Archivované položky jsou skryté a neaktivní, ale zachovávají historii a náklady.", "settings_archive_desc": "Odkládejte dokončené jednorázové úkoly bez mazání. Archivované položky jsou skryté a neaktivní, ale zachovávají historii a náklady.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "Ugyldig dato", "ws_err_invalid_date": "Ugyldig dato",
"ws_err_invalid_format": "Ugyldigt format", "ws_err_invalid_format": "Ugyldigt format",
"ws_err_invalid_url": "Ugyldigt link", "ws_err_invalid_url": "Ugyldigt link",
"ws_err_invalid_mirror_todo": "Ugyldig to-do-liste",
"ws_err_not_configured": "Ikke sat op endnu", "ws_err_not_configured": "Ikke sat op endnu",
"ws_err_not_loaded": "Ikke indlæst endnu — prøv igen om lidt", "ws_err_not_loaded": "Ikke indlæst endnu — prøv igen om lidt",
"ws_err_limit_reached": "Grænsen er nået", "ws_err_limit_reached": "Grænsen er nået",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "Ingen standardværdier for hurtig fuldførelse", "ws_err_no_defaults": "Ingen standardværdier for hurtig fuldførelse",
"ws_err_self_link_device": "Et objekt kan ikke knyttes til sig selv", "ws_err_self_link_device": "Et objekt kan ikke knyttes til sig selv",
"ws_err_too_early": "For tidligt — opgaven kan først fuldføres tættere på forfaldsdatoen", "ws_err_too_early": "For tidligt — opgaven kan først fuldføres tættere på forfaldsdatoen",
"ws_err_invalid_search_template": "Søgelinket skal være en http(s)-URL, der indeholder {q}",
"feat_schedule_time": "Planlægning efter tidspunkt på dagen", "feat_schedule_time": "Planlægning efter tidspunkt på dagen",
"feat_schedule_time_desc": "Opgaver bliver forfaldne på et bestemt tidspunkt på dagen i stedet for midnat.", "feat_schedule_time_desc": "Opgaver bliver forfaldne på et bestemt tidspunkt på dagen i stedet for midnat.",
"schedule_time_toggle": "Forfalder på et bestemt tidspunkt", "schedule_time_toggle": "Forfalder på et bestemt tidspunkt",
@@ -201,6 +203,8 @@
"labels": "Etiketter", "labels": "Etiketter",
"labels_placeholder": "f.eks. sikkerhed, sæson, synlig-for-lejer", "labels_placeholder": "f.eks. sikkerhed, sæson, synlig-for-lejer",
"labels_help": "Kommaseparerede tags til filtrering og rapporter.", "labels_help": "Kommaseparerede tags til filtrering og rapporter.",
"task_mirror_todo": "Spejl til to-do-lister",
"task_mirror_todo_hint": "Opgaven vises på disse lister, mens den er aktuel; afkrydses den der, fuldføres den her.",
"priority_low": "Lav", "priority_low": "Lav",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Høj", "priority_high": "Høj",
@@ -498,6 +502,8 @@
"settings_default_warning": "Standard advarselsdage", "settings_default_warning": "Standard advarselsdage",
"settings_consumable_threshold": "Tærskel „forbrugsvare lav“ (%)", "settings_consumable_threshold": "Tærskel „forbrugsvare lav“ (%)",
"settings_battery_low_percent": "Tærskel „batteri lavt“ (%)", "settings_battery_low_percent": "Tærskel „batteri lavt“ (%)",
"settings_battery_recovered_percent": "Batteri regnes som udskiftet over (%)",
"settings_battery_recovered_percent_hint": "Et lavt batteri tælles som lavt, indtil niveauet stiger over denne værdi, eller et skift registreres — så kan et niveau, der svinger omkring tærsklen, ikke fuldføre flådeopgaven igen og igen.",
"settings_battery_lifetimes": "Typiske batterilevetider", "settings_battery_lifetimes": "Typiske batterilevetider",
"settings_battery_lifetimes_hint": "Bruges kun til batterier uden procent: en Battery Notes-note med kun type og udskiftningsdato, eller en sensor der kun melder \"lavt\". Forfaldsdato = seneste udskiftning + denne levetid. Batterier der melder niveau får prognosen fra den målte afladning. Når flåden har set tre udskiftninger af en type, overtager medianintervallet fra den indbyggede værdi — din egen værdi vinder altid.", "settings_battery_lifetimes_hint": "Bruges kun til batterier uden procent: en Battery Notes-note med kun type og udskiftningsdato, eller en sensor der kun melder \"lavt\". Forfaldsdato = seneste udskiftning + denne levetid. Batterier der melder niveau får prognosen fra den målte afladning. Når flåden har set tre udskiftninger af en type, overtager medianintervallet fra den indbyggede værdi — din egen værdi vinder altid.",
"settings_battery_lifetime_months": "måneder", "settings_battery_lifetime_months": "måneder",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "i din flåde", "settings_battery_lifetime_in_fleet": "i din flåde",
"settings_battery_lifetime_learned_models": "Lært pr. model: {list}", "settings_battery_lifetime_learned_models": "Lært pr. model: {list}",
"settings_thresholds_hint": "Standardværdier for nye Foreslåede opsætninger (resterende procent) og for flådebatterier uden egen Battery Notes-tærskel. Eksisterende opgaver beholder deres værdi.", "settings_thresholds_hint": "Standardværdier for nye Foreslåede opsætninger (resterende procent) og for flådebatterier uden egen Battery Notes-tærskel. Eksisterende opgaver beholder deres værdi.",
"settings_part_search_url": "Søgelink til indkøb",
"settings_part_search_url_hint": "URL med {q} i stedet for søgeordene, til dele uden produktlink. Lad stå tomt for den automatiske butik (efter land, ellers sprog).",
"settings_value_out_of_range": "Værdien skal være mellem {min} og {max}", "settings_value_out_of_range": "Værdien skal være mellem {min} og {max}",
"bn_summary": "{name}: {pct} % for {n} batterier", "bn_summary": "{name}: {pct} % for {n} batterier",
"bn_floor_decides": "Din tærskel på {floor} % afgør for alle; pr. batteri gælder den højeste af de to tærskler.", "bn_floor_decides": "Din tærskel på {floor} % afgør for alle; pr. batteri gælder den højeste af de to tærskler.",
@@ -717,6 +725,8 @@
"archived": "Arkiveret", "archived": "Arkiveret",
"show_archived": "Vis arkiverede", "show_archived": "Vis arkiverede",
"hide_archived": "Skjul arkiverede", "hide_archived": "Skjul arkiverede",
"section_collapse": "Fold sektionen sammen",
"section_expand": "Fold sektionen ud",
"confirm_archive_object": "Arkivér dette objekt og dets opgaver? Historikken bevares og kan gendannes senere.", "confirm_archive_object": "Arkivér dette objekt og dets opgaver? Historikken bevares og kan gendannes senere.",
"settings_archive": "Arkiv og opbevaring", "settings_archive": "Arkiv og opbevaring",
"settings_archive_desc": "Læg færdige engangsopgaver væk uden at slette dem. Arkiverede elementer er skjult og inaktive, men bevarer historik og omkostninger.", "settings_archive_desc": "Læg færdige engangsopgaver væk uden at slette dem. Arkiverede elementer er skjult og inaktive, men bevarer historik og omkostninger.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "Ungültiges Datum", "ws_err_invalid_date": "Ungültiges Datum",
"ws_err_invalid_format": "Ungültiges Format", "ws_err_invalid_format": "Ungültiges Format",
"ws_err_invalid_url": "Ungültiger Link", "ws_err_invalid_url": "Ungültiger Link",
"ws_err_invalid_mirror_todo": "Ungültige To-do-Liste",
"ws_err_not_configured": "Noch nicht eingerichtet", "ws_err_not_configured": "Noch nicht eingerichtet",
"ws_err_not_loaded": "Noch nicht geladen — gleich noch einmal versuchen", "ws_err_not_loaded": "Noch nicht geladen — gleich noch einmal versuchen",
"ws_err_limit_reached": "Limit erreicht", "ws_err_limit_reached": "Limit erreicht",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "Keine Vorgaben für das Schnell-Erledigen hinterlegt", "ws_err_no_defaults": "Keine Vorgaben für das Schnell-Erledigen hinterlegt",
"ws_err_self_link_device": "Ein Objekt kann nicht mit sich selbst verknüpft werden", "ws_err_self_link_device": "Ein Objekt kann nicht mit sich selbst verknüpft werden",
"ws_err_too_early": "Zu früh — diese Aufgabe kann erst näher am Fälligkeitsdatum erledigt werden", "ws_err_too_early": "Zu früh — diese Aufgabe kann erst näher am Fälligkeitsdatum erledigt werden",
"ws_err_invalid_search_template": "Der Suchlink muss eine http(s)-URL mit {q} sein",
"feat_schedule_time": "Uhrzeit-Scheduling", "feat_schedule_time": "Uhrzeit-Scheduling",
"feat_schedule_time_desc": "Tasks werden zu einer festen Uhrzeit fällig statt um Mitternacht.", "feat_schedule_time_desc": "Tasks werden zu einer festen Uhrzeit fällig statt um Mitternacht.",
"schedule_time_toggle": "Zu einer bestimmten Uhrzeit fällig", "schedule_time_toggle": "Zu einer bestimmten Uhrzeit fällig",
@@ -201,6 +203,8 @@
"labels": "Labels", "labels": "Labels",
"labels_placeholder": "z. B. Sicherheit, Saison, Mieter-sichtbar", "labels_placeholder": "z. B. Sicherheit, Saison, Mieter-sichtbar",
"labels_help": "Kommagetrennte Tags zum Filtern und für Berichte.", "labels_help": "Kommagetrennte Tags zum Filtern und für Berichte.",
"task_mirror_todo": "In To-do-Listen spiegeln",
"task_mirror_todo_hint": "Die Aufgabe erscheint in diesen Listen, solange sie fällig ist; wird sie dort abgehakt, gilt sie hier als erledigt.",
"priority_low": "Niedrig", "priority_low": "Niedrig",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Hoch", "priority_high": "Hoch",
@@ -498,6 +502,8 @@
"settings_default_warning": "Standard-Warntage", "settings_default_warning": "Standard-Warntage",
"settings_consumable_threshold": "Schwelle „Verbrauchsmaterial niedrig“ (%)", "settings_consumable_threshold": "Schwelle „Verbrauchsmaterial niedrig“ (%)",
"settings_battery_low_percent": "Schwelle „Batterie niedrig“ (%)", "settings_battery_low_percent": "Schwelle „Batterie niedrig“ (%)",
"settings_battery_recovered_percent": "Batterie gilt als ersetzt ab (%)",
"settings_battery_recovered_percent_hint": "Eine niedrige Batterie bleibt so lange als niedrig gezählt, bis ihr Stand über diesen Wert steigt oder ein Wechsel erfasst wird — ein Stand, der um die Schwelle pendelt, schließt die Flottenaufgabe so nicht immer wieder ab.",
"settings_battery_lifetimes": "Typische Batterie-Lebensdauern", "settings_battery_lifetimes": "Typische Batterie-Lebensdauern",
"settings_battery_lifetimes_hint": "Wird nur für Batterien ohne Prozentanzeige verwendet: eine Battery-Notes-Notiz, die nur Typ und Austauschdatum kennt, oder ein Sensor, der nur „schwach“ meldet. Deren Fälligkeit ist letzter Wechsel + diese Lebensdauer. Batterien mit Füllstand bekommen ihre Prognose aus der gemessenen Entladung. Sobald die Flotte drei Wechsel eines Typs gesehen hat, ersetzt das mittlere Intervall den eingebauten Wert — dein eigener Wert gewinnt immer.", "settings_battery_lifetimes_hint": "Wird nur für Batterien ohne Prozentanzeige verwendet: eine Battery-Notes-Notiz, die nur Typ und Austauschdatum kennt, oder ein Sensor, der nur „schwach“ meldet. Deren Fälligkeit ist letzter Wechsel + diese Lebensdauer. Batterien mit Füllstand bekommen ihre Prognose aus der gemessenen Entladung. Sobald die Flotte drei Wechsel eines Typs gesehen hat, ersetzt das mittlere Intervall den eingebauten Wert — dein eigener Wert gewinnt immer.",
"settings_battery_lifetime_months": "Monate", "settings_battery_lifetime_months": "Monate",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "in deiner Flotte", "settings_battery_lifetime_in_fleet": "in deiner Flotte",
"settings_battery_lifetime_learned_models": "Gelernt je Modell: {list}", "settings_battery_lifetime_learned_models": "Gelernt je Modell: {list}",
"settings_thresholds_hint": "Vorgaben für neue Vorgeschlagene Einrichtungen (Prozent-Restwert) und für Flotten-Batterien ohne eigene Battery-Notes-Schwelle. Bestehende Aufgaben behalten ihren Wert.", "settings_thresholds_hint": "Vorgaben für neue Vorgeschlagene Einrichtungen (Prozent-Restwert) und für Flotten-Batterien ohne eigene Battery-Notes-Schwelle. Bestehende Aufgaben behalten ihren Wert.",
"settings_part_search_url": "Link für die Einkaufssuche",
"settings_part_search_url_hint": "URL mit {q} anstelle der Suchbegriffe, für Teile ohne Produktlink. Leer lassen für den automatischen Shop (nach Land, sonst nach Sprache).",
"settings_value_out_of_range": "Der Wert muss zwischen {min} und {max} liegen", "settings_value_out_of_range": "Der Wert muss zwischen {min} und {max} liegen",
"bn_summary": "{name}: {pct} % für {n} Batterien", "bn_summary": "{name}: {pct} % für {n} Batterien",
"bn_floor_decides": "Deine {floor}-%-Schwelle entscheidet für alle; pro Batterie zählt die höhere der beiden Schwellen.", "bn_floor_decides": "Deine {floor}-%-Schwelle entscheidet für alle; pro Batterie zählt die höhere der beiden Schwellen.",
@@ -717,6 +725,8 @@
"archived": "Archiviert", "archived": "Archiviert",
"show_archived": "Archivierte anzeigen", "show_archived": "Archivierte anzeigen",
"hide_archived": "Archivierte ausblenden", "hide_archived": "Archivierte ausblenden",
"section_collapse": "Bereich einklappen",
"section_expand": "Bereich ausklappen",
"confirm_archive_object": "Dieses Objekt und seine Aufgaben archivieren? Verlauf bleibt erhalten, kann später wiederhergestellt werden.", "confirm_archive_object": "Dieses Objekt und seine Aufgaben archivieren? Verlauf bleibt erhalten, kann später wiederhergestellt werden.",
"settings_archive": "Archiv & Aufbewahrung", "settings_archive": "Archiv & Aufbewahrung",
"settings_archive_desc": "Erledigte einmalige Aufgaben archivieren statt löschen. Archivierte Einträge sind ausgeblendet und inaktiv, behalten aber Verlauf und Kosten.", "settings_archive_desc": "Erledigte einmalige Aufgaben archivieren statt löschen. Archivierte Einträge sind ausgeblendet und inaktiv, behalten aber Verlauf und Kosten.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "Invalid date", "ws_err_invalid_date": "Invalid date",
"ws_err_invalid_format": "Invalid format", "ws_err_invalid_format": "Invalid format",
"ws_err_invalid_url": "Invalid link", "ws_err_invalid_url": "Invalid link",
"ws_err_invalid_mirror_todo": "Invalid to-do list",
"ws_err_not_configured": "Not set up yet", "ws_err_not_configured": "Not set up yet",
"ws_err_not_loaded": "Not loaded yet — try again in a moment", "ws_err_not_loaded": "Not loaded yet — try again in a moment",
"ws_err_limit_reached": "Limit reached", "ws_err_limit_reached": "Limit reached",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "No quick-complete defaults set", "ws_err_no_defaults": "No quick-complete defaults set",
"ws_err_self_link_device": "An object cannot be linked to itself", "ws_err_self_link_device": "An object cannot be linked to itself",
"ws_err_too_early": "Too early — this task can only be completed closer to its due date", "ws_err_too_early": "Too early — this task can only be completed closer to its due date",
"ws_err_invalid_search_template": "The search link must be an http(s) URL containing {q}",
"feat_schedule_time": "Time-of-day scheduling", "feat_schedule_time": "Time-of-day scheduling",
"feat_schedule_time_desc": "Tasks become overdue at a specific time of day instead of midnight.", "feat_schedule_time_desc": "Tasks become overdue at a specific time of day instead of midnight.",
"schedule_time_toggle": "Due at a specific time", "schedule_time_toggle": "Due at a specific time",
@@ -201,6 +203,8 @@
"labels": "Labels", "labels": "Labels",
"labels_placeholder": "e.g. safety, seasonal, tenant-visible", "labels_placeholder": "e.g. safety, seasonal, tenant-visible",
"labels_help": "Comma-separated tags for filtering and reporting.", "labels_help": "Comma-separated tags for filtering and reporting.",
"task_mirror_todo": "Mirror into to-do lists",
"task_mirror_todo_hint": "The task appears in these lists while it is due; checking it off there completes it here.",
"priority_low": "Low", "priority_low": "Low",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "High", "priority_high": "High",
@@ -498,6 +502,8 @@
"settings_default_warning": "Default warning days", "settings_default_warning": "Default warning days",
"settings_consumable_threshold": "Consumable low threshold (%)", "settings_consumable_threshold": "Consumable low threshold (%)",
"settings_battery_low_percent": "Battery low threshold (%)", "settings_battery_low_percent": "Battery low threshold (%)",
"settings_battery_recovered_percent": "Battery counts as replaced above (%)",
"settings_battery_recovered_percent_hint": "A low battery stays counted as low until its level rises above this value or a replacement is recorded — so a level hovering around the low threshold cannot complete the fleet task again and again.",
"settings_battery_lifetimes": "Typical battery lifetimes", "settings_battery_lifetimes": "Typical battery lifetimes",
"settings_battery_lifetimes_hint": "Only used for batteries without a percentage: a Battery Notes note that has just a type and a last-replaced date, or a sensor that only reports \"low\". Their due date is last replaced + this lifetime. Batteries that report a level get their forecast from the measured discharge instead. Once the fleet has seen three replacements of a type, the median interval takes over from the built-in value — your own value always wins.", "settings_battery_lifetimes_hint": "Only used for batteries without a percentage: a Battery Notes note that has just a type and a last-replaced date, or a sensor that only reports \"low\". Their due date is last replaced + this lifetime. Batteries that report a level get their forecast from the measured discharge instead. Once the fleet has seen three replacements of a type, the median interval takes over from the built-in value — your own value always wins.",
"settings_battery_lifetime_months": "months", "settings_battery_lifetime_months": "months",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "in your fleet", "settings_battery_lifetime_in_fleet": "in your fleet",
"settings_battery_lifetime_learned_models": "Learned per model: {list}", "settings_battery_lifetime_learned_models": "Learned per model: {list}",
"settings_thresholds_hint": "Defaults for new Suggested setups (percent-remaining consumables) and for fleet batteries without their own Battery Notes threshold. Existing tasks keep their value.", "settings_thresholds_hint": "Defaults for new Suggested setups (percent-remaining consumables) and for fleet batteries without their own Battery Notes threshold. Existing tasks keep their value.",
"settings_part_search_url": "Shopping search link",
"settings_part_search_url_hint": "URL with {q} in place of the search terms, used for parts without a product link. Leave empty for the automatic store (by country, then by language).",
"settings_value_out_of_range": "Value must be between {min} and {max}", "settings_value_out_of_range": "Value must be between {min} and {max}",
"bn_summary": "{name}: {pct} % for {n} batteries", "bn_summary": "{name}: {pct} % for {n} batteries",
"bn_floor_decides": "Your {floor} % floor decides for all of them; the higher of the two thresholds counts per battery.", "bn_floor_decides": "Your {floor} % floor decides for all of them; the higher of the two thresholds counts per battery.",
@@ -723,6 +731,8 @@
"archived": "Archived", "archived": "Archived",
"show_archived": "Show archived", "show_archived": "Show archived",
"hide_archived": "Hide archived", "hide_archived": "Hide archived",
"section_collapse": "Collapse section",
"section_expand": "Expand section",
"confirm_archive_object": "Archive this object and its tasks? They keep their history and can be unarchived later.", "confirm_archive_object": "Archive this object and its tasks? They keep their history and can be unarchived later.",
"settings_archive": "Archive & Retention", "settings_archive": "Archive & Retention",
"settings_archive_desc": "Retire completed one-off tasks without deleting them. Archived items are hidden and inert but keep their history and cost.", "settings_archive_desc": "Retire completed one-off tasks without deleting them. Archived items are hidden and inert but keep their history and cost.",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Fecha no válida", "ws_err_invalid_date": "Fecha no válida",
"ws_err_invalid_format": "Formato no válido", "ws_err_invalid_format": "Formato no válido",
"ws_err_invalid_url": "Enlace no válido", "ws_err_invalid_url": "Enlace no válido",
"ws_err_invalid_mirror_todo": "Lista de tareas no válida",
"ws_err_not_configured": "Aún no configurado", "ws_err_not_configured": "Aún no configurado",
"ws_err_not_loaded": "Aún no cargado — inténtalo de nuevo en un momento", "ws_err_not_loaded": "Aún no cargado — inténtalo de nuevo en un momento",
"ws_err_limit_reached": "Límite alcanzado", "ws_err_limit_reached": "Límite alcanzado",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "No hay valores predeterminados para completar rápido", "ws_err_no_defaults": "No hay valores predeterminados para completar rápido",
"ws_err_self_link_device": "Un objeto no puede vincularse a sí mismo", "ws_err_self_link_device": "Un objeto no puede vincularse a sí mismo",
"ws_err_too_early": "Demasiado pronto — esta tarea solo puede completarse más cerca de su vencimiento", "ws_err_too_early": "Demasiado pronto — esta tarea solo puede completarse más cerca de su vencimiento",
"ws_err_invalid_search_template": "El enlace de búsqueda debe ser una URL http(s) que contenga {q}",
"feat_schedule_time": "Programación por hora", "feat_schedule_time": "Programación por hora",
"feat_schedule_time_desc": "Las tareas vencen a una hora específica en lugar de medianoche.", "feat_schedule_time_desc": "Las tareas vencen a una hora específica en lugar de medianoche.",
"schedule_time_toggle": "Vence a una hora concreta", "schedule_time_toggle": "Vence a una hora concreta",
@@ -199,6 +201,8 @@
"labels": "Etiquetas", "labels": "Etiquetas",
"labels_placeholder": "p. ej. seguridad, estacional, visible-inquilino", "labels_placeholder": "p. ej. seguridad, estacional, visible-inquilino",
"labels_help": "Etiquetas separadas por comas para filtrar e informes.", "labels_help": "Etiquetas separadas por comas para filtrar e informes.",
"task_mirror_todo": "Reflejar en listas de tareas",
"task_mirror_todo_hint": "La tarea aparece en estas listas mientras esté pendiente; marcarla allí la completa aquí.",
"priority_low": "Baja", "priority_low": "Baja",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Alta", "priority_high": "Alta",
@@ -496,6 +500,8 @@
"settings_default_warning": "Días de aviso predeterminados", "settings_default_warning": "Días de aviso predeterminados",
"settings_consumable_threshold": "Umbral „consumible bajo“ (%)", "settings_consumable_threshold": "Umbral „consumible bajo“ (%)",
"settings_battery_low_percent": "Umbral „pila baja“ (%)", "settings_battery_low_percent": "Umbral „pila baja“ (%)",
"settings_battery_recovered_percent": "Pila considerada sustituida por encima de (%)",
"settings_battery_recovered_percent_hint": "Una pila baja sigue contando como baja hasta que su nivel supere este valor o se registre una sustitución — así un nivel que oscila alrededor del umbral no completa la tarea de la flota una y otra vez.",
"settings_battery_lifetimes": "Duraciones típicas de las pilas", "settings_battery_lifetimes": "Duraciones típicas de las pilas",
"settings_battery_lifetimes_hint": "Solo se usa para pilas sin porcentaje: una nota de Battery Notes que solo tiene tipo y fecha de sustitución, o un sensor que solo avisa de « baja ». Su vencimiento es última sustitución + esta duración. Las pilas que informan de un nivel obtienen su previsión de la descarga medida. Cuando la flota ha visto tres sustituciones de un tipo, el intervalo mediano sustituye al valor integrado — tu valor siempre gana.", "settings_battery_lifetimes_hint": "Solo se usa para pilas sin porcentaje: una nota de Battery Notes que solo tiene tipo y fecha de sustitución, o un sensor que solo avisa de « baja ». Su vencimiento es última sustitución + esta duración. Las pilas que informan de un nivel obtienen su previsión de la descarga medida. Cuando la flota ha visto tres sustituciones de un tipo, el intervalo mediano sustituye al valor integrado — tu valor siempre gana.",
"settings_battery_lifetime_months": "meses", "settings_battery_lifetime_months": "meses",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "en tu flota", "settings_battery_lifetime_in_fleet": "en tu flota",
"settings_battery_lifetime_learned_models": "Aprendido por modelo: {list}", "settings_battery_lifetime_learned_models": "Aprendido por modelo: {list}",
"settings_thresholds_hint": "Valores predeterminados para nuevas Configuraciones sugeridas (porcentaje restante) y para pilas de la flota sin umbral propio de Battery Notes. Las tareas existentes conservan su valor.", "settings_thresholds_hint": "Valores predeterminados para nuevas Configuraciones sugeridas (porcentaje restante) y para pilas de la flota sin umbral propio de Battery Notes. Las tareas existentes conservan su valor.",
"settings_part_search_url": "Enlace de búsqueda de compra",
"settings_part_search_url_hint": "URL con {q} en lugar de los términos de búsqueda, para piezas sin enlace de producto. Dejar vacío para la tienda automática (por país, si no por idioma).",
"settings_value_out_of_range": "El valor debe estar entre {min} y {max}", "settings_value_out_of_range": "El valor debe estar entre {min} y {max}",
"bn_summary": "{name}: {pct} % para {n} pilas", "bn_summary": "{name}: {pct} % para {n} pilas",
"bn_floor_decides": "Tu umbral del {floor} % decide para todas; por pila cuenta el mayor de los dos umbrales.", "bn_floor_decides": "Tu umbral del {floor} % decide para todas; por pila cuenta el mayor de los dos umbrales.",
@@ -717,6 +725,8 @@
"archived": "Archivado", "archived": "Archivado",
"show_archived": "Mostrar archivados", "show_archived": "Mostrar archivados",
"hide_archived": "Ocultar archivados", "hide_archived": "Ocultar archivados",
"section_collapse": "Contraer sección",
"section_expand": "Expandir sección",
"confirm_archive_object": "¿Archivar este objeto y sus tareas? Se conserva el historial y se puede restaurar más tarde.", "confirm_archive_object": "¿Archivar este objeto y sus tareas? Se conserva el historial y se puede restaurar más tarde.",
"settings_archive": "Archivado y retención", "settings_archive": "Archivado y retención",
"settings_archive_desc": "Retira las tareas únicas completadas sin eliminarlas. Los elementos archivados se ocultan y quedan inactivos, pero conservan su historial y coste.", "settings_archive_desc": "Retira las tareas únicas completadas sin eliminarlas. Los elementos archivados se ocultan y quedan inactivos, pero conservan su historial y coste.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "Virheellinen päivämäärä", "ws_err_invalid_date": "Virheellinen päivämäärä",
"ws_err_invalid_format": "Virheellinen muoto", "ws_err_invalid_format": "Virheellinen muoto",
"ws_err_invalid_url": "Virheellinen linkki", "ws_err_invalid_url": "Virheellinen linkki",
"ws_err_invalid_mirror_todo": "Virheellinen tehtävälista",
"ws_err_not_configured": "Ei vielä määritetty", "ws_err_not_configured": "Ei vielä määritetty",
"ws_err_not_loaded": "Ei vielä ladattu — yritä hetken kuluttua uudelleen", "ws_err_not_loaded": "Ei vielä ladattu — yritä hetken kuluttua uudelleen",
"ws_err_limit_reached": "Raja saavutettu", "ws_err_limit_reached": "Raja saavutettu",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "Pikavalmistumisen oletuksia ei ole asetettu", "ws_err_no_defaults": "Pikavalmistumisen oletuksia ei ole asetettu",
"ws_err_self_link_device": "Objektia ei voi linkittää itseensä", "ws_err_self_link_device": "Objektia ei voi linkittää itseensä",
"ws_err_too_early": "Liian aikaista — tehtävän voi merkitä tehdyksi vasta lähempänä eräpäivää", "ws_err_too_early": "Liian aikaista — tehtävän voi merkitä tehdyksi vasta lähempänä eräpäivää",
"ws_err_invalid_search_template": "Hakulinkin on oltava http(s)-URL, joka sisältää {q}",
"feat_schedule_time": "Kellonajan ajoitus", "feat_schedule_time": "Kellonajan ajoitus",
"feat_schedule_time_desc": "Tehtävät erääntyvät tiettyyn kellonaikaan keskiyön sijaan.", "feat_schedule_time_desc": "Tehtävät erääntyvät tiettyyn kellonaikaan keskiyön sijaan.",
"schedule_time_toggle": "Erääntyy tiettyyn kellonaikaan", "schedule_time_toggle": "Erääntyy tiettyyn kellonaikaan",
@@ -201,6 +203,8 @@
"labels": "Tunnisteet", "labels": "Tunnisteet",
"labels_placeholder": "esim. turvallisuus, kausittainen, vuokralaiselle-näkyvä", "labels_placeholder": "esim. turvallisuus, kausittainen, vuokralaiselle-näkyvä",
"labels_help": "Pilkuin erotellut tunnisteet suodatusta ja raportointia varten.", "labels_help": "Pilkuin erotellut tunnisteet suodatusta ja raportointia varten.",
"task_mirror_todo": "Peilaa tehtävälistoihin",
"task_mirror_todo_hint": "Tehtävä näkyy näissä listoissa, kun se on ajankohtainen; sen kuittaaminen siellä suorittaa sen täällä.",
"priority_low": "Matala", "priority_low": "Matala",
"priority_normal": "Normaali", "priority_normal": "Normaali",
"priority_high": "Korkea", "priority_high": "Korkea",
@@ -498,6 +502,8 @@
"settings_default_warning": "Oletusvaroituspäivät", "settings_default_warning": "Oletusvaroituspäivät",
"settings_consumable_threshold": "Kynnys „kulutustarvike vähissä“ (%)", "settings_consumable_threshold": "Kynnys „kulutustarvike vähissä“ (%)",
"settings_battery_low_percent": "Kynnys „paristo vähissä“ (%)", "settings_battery_low_percent": "Kynnys „paristo vähissä“ (%)",
"settings_battery_recovered_percent": "Paristo lasketaan vaihdetuksi yli (%)",
"settings_battery_recovered_percent_hint": "Vähissä oleva paristo lasketaan vähissä olevaksi, kunnes sen taso nousee tämän arvon yli tai vaihto kirjataan — näin kynnyksen ympärillä heilahteleva taso ei suorita laivastotehtävää yhä uudelleen.",
"settings_battery_lifetimes": "Paristojen tyypilliset käyttöiät", "settings_battery_lifetimes": "Paristojen tyypilliset käyttöiät",
"settings_battery_lifetimes_hint": "Käytetään vain paristoille ilman prosenttilukua: Battery Notes -merkintä, jolla on vain tyyppi ja vaihtopäivä, tai anturi, joka ilmoittaa vain ”vähissä”. Erääntyminen = viimeisin vaihto + tämä käyttöikä. Tasoa raportoivien paristojen ennuste tulee mitatusta purkautumisesta. Kun laivasto on nähnyt kolme saman tyypin vaihtoa, mediaaniväli korvaa sisäänrakennetun arvon — oma arvosi voittaa aina.", "settings_battery_lifetimes_hint": "Käytetään vain paristoille ilman prosenttilukua: Battery Notes -merkintä, jolla on vain tyyppi ja vaihtopäivä, tai anturi, joka ilmoittaa vain ”vähissä”. Erääntyminen = viimeisin vaihto + tämä käyttöikä. Tasoa raportoivien paristojen ennuste tulee mitatusta purkautumisesta. Kun laivasto on nähnyt kolme saman tyypin vaihtoa, mediaaniväli korvaa sisäänrakennetun arvon — oma arvosi voittaa aina.",
"settings_battery_lifetime_months": "kuukautta", "settings_battery_lifetime_months": "kuukautta",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "laivastossasi", "settings_battery_lifetime_in_fleet": "laivastossasi",
"settings_battery_lifetime_learned_models": "Opittu mallikohtaisesti: {list}", "settings_battery_lifetime_learned_models": "Opittu mallikohtaisesti: {list}",
"settings_thresholds_hint": "Oletukset uusille Ehdotetuille asetuksille (jäljellä oleva prosentti) ja paristokannan paristoille ilman omaa Battery Notes -kynnystä. Olemassa olevat tehtävät säilyttävät arvonsa.", "settings_thresholds_hint": "Oletukset uusille Ehdotetuille asetuksille (jäljellä oleva prosentti) ja paristokannan paristoille ilman omaa Battery Notes -kynnystä. Olemassa olevat tehtävät säilyttävät arvonsa.",
"settings_part_search_url": "Ostohaun linkki",
"settings_part_search_url_hint": "URL, jossa {q} korvaa hakusanat, osille ilman tuotelinkkiä. Jätä tyhjäksi, niin kauppa valitaan automaattisesti (maan, muuten kielen mukaan).",
"settings_value_out_of_range": "Arvon on oltava välillä {min}–{max}", "settings_value_out_of_range": "Arvon on oltava välillä {min}–{max}",
"bn_summary": "{name}: {pct} % {n} paristolle", "bn_summary": "{name}: {pct} % {n} paristolle",
"bn_floor_decides": "Sinun {floor} %:n kynnyksesi ratkaisee kaikille; paristoa kohden pätee korkeampi kahdesta kynnyksestä.", "bn_floor_decides": "Sinun {floor} %:n kynnyksesi ratkaisee kaikille; paristoa kohden pätee korkeampi kahdesta kynnyksestä.",
@@ -717,6 +725,8 @@
"archived": "Arkistoitu", "archived": "Arkistoitu",
"show_archived": "Näytä arkistoidut", "show_archived": "Näytä arkistoidut",
"hide_archived": "Piilota arkistoidut", "hide_archived": "Piilota arkistoidut",
"section_collapse": "Pienennä osio",
"section_expand": "Laajenna osio",
"confirm_archive_object": "Arkistoidaanko tämä kohde ja sen tehtävät? Historia säilyy ja sen voi palauttaa myöhemmin.", "confirm_archive_object": "Arkistoidaanko tämä kohde ja sen tehtävät? Historia säilyy ja sen voi palauttaa myöhemmin.",
"settings_archive": "Arkistointi ja säilytys", "settings_archive": "Arkistointi ja säilytys",
"settings_archive_desc": "Siirrä valmiit kertatehtävät arkistoon poistamatta niitä. Arkistoidut kohteet ovat piilossa ja passiivisia, mutta säilyttävät historian ja kustannukset.", "settings_archive_desc": "Siirrä valmiit kertatehtävät arkistoon poistamatta niitä. Arkistoidut kohteet ovat piilossa ja passiivisia, mutta säilyttävät historian ja kustannukset.",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Date non valide", "ws_err_invalid_date": "Date non valide",
"ws_err_invalid_format": "Format non valide", "ws_err_invalid_format": "Format non valide",
"ws_err_invalid_url": "Lien non valide", "ws_err_invalid_url": "Lien non valide",
"ws_err_invalid_mirror_todo": "Liste de tâches non valide",
"ws_err_not_configured": "Pas encore configuré", "ws_err_not_configured": "Pas encore configuré",
"ws_err_not_loaded": "Pas encore chargé — réessayez dans un instant", "ws_err_not_loaded": "Pas encore chargé — réessayez dans un instant",
"ws_err_limit_reached": "Limite atteinte", "ws_err_limit_reached": "Limite atteinte",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "Aucune valeur par défaut pour la validation rapide", "ws_err_no_defaults": "Aucune valeur par défaut pour la validation rapide",
"ws_err_self_link_device": "Un objet ne peut pas être lié à lui-même", "ws_err_self_link_device": "Un objet ne peut pas être lié à lui-même",
"ws_err_too_early": "Trop tôt — cette tâche ne peut être terminée que plus près de son échéance", "ws_err_too_early": "Trop tôt — cette tâche ne peut être terminée que plus près de son échéance",
"ws_err_invalid_search_template": "Le lien de recherche doit être une URL http(s) contenant {q}",
"feat_schedule_time": "Planification à l'heure", "feat_schedule_time": "Planification à l'heure",
"feat_schedule_time_desc": "Les tâches arrivent à échéance à une heure précise plutôt qu'à minuit.", "feat_schedule_time_desc": "Les tâches arrivent à échéance à une heure précise plutôt qu'à minuit.",
"schedule_time_toggle": "Échéance à une heure précise", "schedule_time_toggle": "Échéance à une heure précise",
@@ -199,6 +201,8 @@
"labels": "Étiquettes", "labels": "Étiquettes",
"labels_placeholder": "p. ex. sécurité, saisonnier, visible-locataire", "labels_placeholder": "p. ex. sécurité, saisonnier, visible-locataire",
"labels_help": "Étiquettes séparées par des virgules pour le filtrage et les rapports.", "labels_help": "Étiquettes séparées par des virgules pour le filtrage et les rapports.",
"task_mirror_todo": "Refléter dans des listes de tâches",
"task_mirror_todo_hint": "La tâche apparaît dans ces listes tant qu'elle est à faire ; la cocher là-bas la termine ici.",
"priority_low": "Basse", "priority_low": "Basse",
"priority_normal": "Normale", "priority_normal": "Normale",
"priority_high": "Haute", "priority_high": "Haute",
@@ -496,6 +500,8 @@
"settings_default_warning": "Jours d'avertissement par défaut", "settings_default_warning": "Jours d'avertissement par défaut",
"settings_consumable_threshold": "Seuil « consommable bas » (%)", "settings_consumable_threshold": "Seuil « consommable bas » (%)",
"settings_battery_low_percent": "Seuil « pile faible » (%)", "settings_battery_low_percent": "Seuil « pile faible » (%)",
"settings_battery_recovered_percent": "Pile considérée remplacée au-dessus de (%)",
"settings_battery_recovered_percent_hint": "Une pile faible reste comptée comme faible tant que son niveau ne dépasse pas cette valeur ou qu'un remplacement n'est pas enregistré — un niveau qui oscille autour du seuil ne peut ainsi plus terminer la tâche du parc encore et encore.",
"settings_battery_lifetimes": "Durées de vie typiques des piles", "settings_battery_lifetimes": "Durées de vie typiques des piles",
"settings_battery_lifetimes_hint": "Utilisé uniquement pour les piles sans pourcentage : une note Battery Notes qui ne connaît qu'un type et une date de remplacement, ou un capteur qui ne signale que « faible ». Leur échéance est dernier remplacement + cette durée. Les piles qui remontent un niveau sont prévues d'après la décharge mesurée. Dès que le parc a vu trois remplacements d'un type, l'intervalle médian remplace la valeur intégrée — votre valeur l'emporte toujours.", "settings_battery_lifetimes_hint": "Utilisé uniquement pour les piles sans pourcentage : une note Battery Notes qui ne connaît qu'un type et une date de remplacement, ou un capteur qui ne signale que « faible ». Leur échéance est dernier remplacement + cette durée. Les piles qui remontent un niveau sont prévues d'après la décharge mesurée. Dès que le parc a vu trois remplacements d'un type, l'intervalle médian remplace la valeur intégrée — votre valeur l'emporte toujours.",
"settings_battery_lifetime_months": "mois", "settings_battery_lifetime_months": "mois",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "dans votre parc", "settings_battery_lifetime_in_fleet": "dans votre parc",
"settings_battery_lifetime_learned_models": "Appris par modèle : {list}", "settings_battery_lifetime_learned_models": "Appris par modèle : {list}",
"settings_thresholds_hint": "Valeurs par défaut pour les nouvelles Configurations suggérées (pourcentage restant) et pour les piles de la flotte sans seuil Battery Notes propre. Les tâches existantes gardent leur valeur.", "settings_thresholds_hint": "Valeurs par défaut pour les nouvelles Configurations suggérées (pourcentage restant) et pour les piles de la flotte sans seuil Battery Notes propre. Les tâches existantes gardent leur valeur.",
"settings_part_search_url": "Lien de recherche d'achat",
"settings_part_search_url_hint": "URL avec {q} à la place des termes de recherche, utilisée pour les pièces sans lien produit. Laisser vide pour la boutique automatique (selon le pays, sinon la langue).",
"settings_value_out_of_range": "La valeur doit être comprise entre {min} et {max}", "settings_value_out_of_range": "La valeur doit être comprise entre {min} et {max}",
"bn_summary": "{name} : {pct} % pour {n} piles", "bn_summary": "{name} : {pct} % pour {n} piles",
"bn_floor_decides": "Votre seuil de {floor} % décide pour toutes ; par pile, c'est le plus élevé des deux seuils qui compte.", "bn_floor_decides": "Votre seuil de {floor} % décide pour toutes ; par pile, c'est le plus élevé des deux seuils qui compte.",
@@ -717,6 +725,8 @@
"archived": "Archivé", "archived": "Archivé",
"show_archived": "Afficher les archivés", "show_archived": "Afficher les archivés",
"hide_archived": "Masquer les archivés", "hide_archived": "Masquer les archivés",
"section_collapse": "Réduire la section",
"section_expand": "Développer la section",
"confirm_archive_object": "Archiver cet objet et ses tâches ? L'historique est conservé et peut être restauré plus tard.", "confirm_archive_object": "Archiver cet objet et ses tâches ? L'historique est conservé et peut être restauré plus tard.",
"settings_archive": "Archivage et conservation", "settings_archive": "Archivage et conservation",
"settings_archive_desc": "Mettez de côté les tâches ponctuelles terminées sans les supprimer. Les éléments archivés sont masqués et inactifs, mais conservent leur historique et leurs coûts.", "settings_archive_desc": "Mettez de côté les tâches ponctuelles terminées sans les supprimer. Les éléments archivés sont masqués et inactifs, mais conservent leur historique et leurs coûts.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "अमान्य तारीख", "ws_err_invalid_date": "अमान्य तारीख",
"ws_err_invalid_format": "अमान्य प्रारूप", "ws_err_invalid_format": "अमान्य प्रारूप",
"ws_err_invalid_url": "अमान्य लिंक", "ws_err_invalid_url": "अमान्य लिंक",
"ws_err_invalid_mirror_todo": "अमान्य टू-डू सूची",
"ws_err_not_configured": "अभी सेट नहीं किया गया", "ws_err_not_configured": "अभी सेट नहीं किया गया",
"ws_err_not_loaded": "अभी लोड नहीं हुआ — कुछ देर बाद फिर से कोशिश करें", "ws_err_not_loaded": "अभी लोड नहीं हुआ — कुछ देर बाद फिर से कोशिश करें",
"ws_err_limit_reached": "सीमा पूरी हो गई", "ws_err_limit_reached": "सीमा पूरी हो गई",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "त्वरित पूर्णता के लिए डिफ़ॉल्ट सेट नहीं", "ws_err_no_defaults": "त्वरित पूर्णता के लिए डिफ़ॉल्ट सेट नहीं",
"ws_err_self_link_device": "कोई ऑब्जेक्ट स्वयं से लिंक नहीं हो सकता", "ws_err_self_link_device": "कोई ऑब्जेक्ट स्वयं से लिंक नहीं हो सकता",
"ws_err_too_early": "बहुत जल्दी — यह कार्य केवल नियत तारीख के करीब ही पूरा किया जा सकता है", "ws_err_too_early": "बहुत जल्दी — यह कार्य केवल नियत तारीख के करीब ही पूरा किया जा सकता है",
"ws_err_invalid_search_template": "खोज लिंक {q} वाला http(s) URL होना चाहिए",
"feat_schedule_time": "दिन का समय निर्धारण", "feat_schedule_time": "दिन का समय निर्धारण",
"feat_schedule_time_desc": "कार्य मध्यरात्रि के बजाय दिन के एक विशिष्ट समय पर अतिदेय हो जाते हैं।", "feat_schedule_time_desc": "कार्य मध्यरात्रि के बजाय दिन के एक विशिष्ट समय पर अतिदेय हो जाते हैं।",
"schedule_time_toggle": "किसी निश्चित समय पर देय", "schedule_time_toggle": "किसी निश्चित समय पर देय",
@@ -201,6 +203,8 @@
"labels": "लेबल", "labels": "लेबल",
"labels_placeholder": "जैसे सुरक्षा, मौसमी, किरायेदार-दृश्य", "labels_placeholder": "जैसे सुरक्षा, मौसमी, किरायेदार-दृश्य",
"labels_help": "फ़िल्टरिंग और रिपोर्टिंग के लिए अल्पविराम से अलग किए गए टैग।", "labels_help": "फ़िल्टरिंग और रिपोर्टिंग के लिए अल्पविराम से अलग किए गए टैग।",
"task_mirror_todo": "टू-डू सूचियों में मिरर करें",
"task_mirror_todo_hint": "जब तक कार्य देय है, यह इन सूचियों में दिखता है; वहाँ पूरा करने पर यह यहाँ भी पूरा हो जाता है।",
"priority_low": "कम", "priority_low": "कम",
"priority_normal": "सामान्य", "priority_normal": "सामान्य",
"priority_high": "उच्च", "priority_high": "उच्च",
@@ -498,6 +502,8 @@
"settings_default_warning": "डिफ़ॉल्ट चेतावनी दिन", "settings_default_warning": "डिफ़ॉल्ट चेतावनी दिन",
"settings_consumable_threshold": "उपभोग्य „कम“ सीमा (%)", "settings_consumable_threshold": "उपभोग्य „कम“ सीमा (%)",
"settings_battery_low_percent": "बैटरी „कम“ सीमा (%)", "settings_battery_low_percent": "बैटरी „कम“ सीमा (%)",
"settings_battery_recovered_percent": "इससे ऊपर बैटरी बदली हुई मानी जाएगी (%)",
"settings_battery_recovered_percent_hint": "कम बैटरी तब तक कम गिनी जाती है जब तक उसका स्तर इस मान से ऊपर न हो जाए या बदलाव दर्ज न हो — ताकि सीमा के आसपास झूलता स्तर बेड़े के कार्य को बार-बार पूरा न कर दे।",
"settings_battery_lifetimes": "बैटरी की सामान्य आयु", "settings_battery_lifetimes": "बैटरी की सामान्य आयु",
"settings_battery_lifetimes_hint": "केवल बिना प्रतिशत वाली बैटरियों के लिए: सिर्फ़ प्रकार और बदलने की तारीख वाला Battery Notes नोट, या केवल \"कम\" बताने वाला सेंसर। नियत तिथि = अंतिम बदलाव + यह आयु। स्तर बताने वाली बैटरियों का पूर्वानुमान मापे गए डिस्चार्ज से बनता है। एक प्रकार के तीन बदलाव देखने के बाद माध्यिका अंतराल अंतर्निहित मान की जगह लेता है — आपका अपना मान हमेशा प्राथमिकता पाता है।", "settings_battery_lifetimes_hint": "केवल बिना प्रतिशत वाली बैटरियों के लिए: सिर्फ़ प्रकार और बदलने की तारीख वाला Battery Notes नोट, या केवल \"कम\" बताने वाला सेंसर। नियत तिथि = अंतिम बदलाव + यह आयु। स्तर बताने वाली बैटरियों का पूर्वानुमान मापे गए डिस्चार्ज से बनता है। एक प्रकार के तीन बदलाव देखने के बाद माध्यिका अंतराल अंतर्निहित मान की जगह लेता है — आपका अपना मान हमेशा प्राथमिकता पाता है।",
"settings_battery_lifetime_months": "महीने", "settings_battery_lifetime_months": "महीने",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "आपके बेड़े में", "settings_battery_lifetime_in_fleet": "आपके बेड़े में",
"settings_battery_lifetime_learned_models": "मॉडल अनुसार सीखा: {list}", "settings_battery_lifetime_learned_models": "मॉडल अनुसार सीखा: {list}",
"settings_thresholds_hint": "नए सुझाए गए सेटअप (शेष प्रतिशत) और अपनी Battery Notes सीमा न रखने वाली बेड़े की बैटरियों के लिए डिफ़ॉल्ट। मौजूदा कार्य अपना मान रखते हैं।", "settings_thresholds_hint": "नए सुझाए गए सेटअप (शेष प्रतिशत) और अपनी Battery Notes सीमा न रखने वाली बेड़े की बैटरियों के लिए डिफ़ॉल्ट। मौजूदा कार्य अपना मान रखते हैं।",
"settings_part_search_url": "खरीदारी खोज लिंक",
"settings_part_search_url_hint": "खोज शब्दों की जगह {q} वाला URL, बिना उत्पाद लिंक वाले पुर्जों के लिए। स्वचालित स्टोर (देश, फिर भाषा के अनुसार) के लिए खाली छोड़ें।",
"settings_value_out_of_range": "मान {min} और {max} के बीच होना चाहिए", "settings_value_out_of_range": "मान {min} और {max} के बीच होना चाहिए",
"bn_summary": "{name}: {n} बैटरियों के लिए {pct} %", "bn_summary": "{name}: {n} बैटरियों के लिए {pct} %",
"bn_floor_decides": "आपकी {floor} % सीमा सभी के लिए निर्णायक है; प्रत्येक बैटरी के लिए दोनों में से ऊँची सीमा मान्य है।", "bn_floor_decides": "आपकी {floor} % सीमा सभी के लिए निर्णायक है; प्रत्येक बैटरी के लिए दोनों में से ऊँची सीमा मान्य है।",
@@ -717,6 +725,8 @@
"archived": "संग्रहीत", "archived": "संग्रहीत",
"show_archived": "संग्रहीत दिखाएँ", "show_archived": "संग्रहीत दिखाएँ",
"hide_archived": "संग्रहीत छिपाएँ", "hide_archived": "संग्रहीत छिपाएँ",
"section_collapse": "अनुभाग संक्षिप्त करें",
"section_expand": "अनुभाग विस्तृत करें",
"confirm_archive_object": "इस ऑब्जेक्ट और इसके कार्यों को संग्रहित करें? इतिहास सुरक्षित रहता है और बाद में पुनर्स्थापित किया जा सकता है।", "confirm_archive_object": "इस ऑब्जेक्ट और इसके कार्यों को संग्रहित करें? इतिहास सुरक्षित रहता है और बाद में पुनर्स्थापित किया जा सकता है।",
"settings_archive": "संग्रह और प्रतिधारण", "settings_archive": "संग्रह और प्रतिधारण",
"settings_archive_desc": "पूर्ण एक-बार के कार्यों को हटाए बिना अलग रखें। संग्रहीत आइटम छिपे और निष्क्रिय रहते हैं, पर इतिहास और लागत बनाए रखते हैं।", "settings_archive_desc": "पूर्ण एक-बार के कार्यों को हटाए बिना अलग रखें। संग्रहीत आइटम छिपे और निष्क्रिय रहते हैं, पर इतिहास और लागत बनाए रखते हैं।",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "Érvénytelen dátum", "ws_err_invalid_date": "Érvénytelen dátum",
"ws_err_invalid_format": "Érvénytelen formátum", "ws_err_invalid_format": "Érvénytelen formátum",
"ws_err_invalid_url": "Érvénytelen hivatkozás", "ws_err_invalid_url": "Érvénytelen hivatkozás",
"ws_err_invalid_mirror_todo": "Érvénytelen teendőlista",
"ws_err_not_configured": "Még nincs beállítva", "ws_err_not_configured": "Még nincs beállítva",
"ws_err_not_loaded": "Még nincs betöltve — próbálja újra egy pillanat múlva", "ws_err_not_loaded": "Még nincs betöltve — próbálja újra egy pillanat múlva",
"ws_err_limit_reached": "Elérte a korlátot", "ws_err_limit_reached": "Elérte a korlátot",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "Nincs beállítva gyors befejezési alapérték", "ws_err_no_defaults": "Nincs beállítva gyors befejezési alapérték",
"ws_err_self_link_device": "Egy objektum nem kapcsolható önmagához", "ws_err_self_link_device": "Egy objektum nem kapcsolható önmagához",
"ws_err_too_early": "Túl korai — ez a feladat csak a határidőhöz közelebb fejezhető be", "ws_err_too_early": "Túl korai — ez a feladat csak a határidőhöz közelebb fejezhető be",
"ws_err_invalid_search_template": "A keresőhivatkozásnak {q}-t tartalmazó http(s) URL-nek kell lennie",
"feat_schedule_time": "Napszakhoz kötött ütemezés", "feat_schedule_time": "Napszakhoz kötött ütemezés",
"feat_schedule_time_desc": "A feladatok nem éjfélkor, hanem egy megadott napszakban válnak lejárttá.", "feat_schedule_time_desc": "A feladatok nem éjfélkor, hanem egy megadott napszakban válnak lejárttá.",
"schedule_time_toggle": "Adott időpontban esedékes", "schedule_time_toggle": "Adott időpontban esedékes",
@@ -201,6 +203,8 @@
"labels": "Címkék", "labels": "Címkék",
"labels_placeholder": "pl. biztonság, szezonális, bérlőnek látható", "labels_placeholder": "pl. biztonság, szezonális, bérlőnek látható",
"labels_help": "Vesszővel elválasztott címkék szűréshez és jelentésekhez.", "labels_help": "Vesszővel elválasztott címkék szűréshez és jelentésekhez.",
"task_mirror_todo": "Tükrözés teendőlistákba",
"task_mirror_todo_hint": "A feladat addig jelenik meg ezekben a listákban, amíg esedékes; ha ott kipipálod, itt is elkészül.",
"priority_low": "Alacsony", "priority_low": "Alacsony",
"priority_normal": "Normál", "priority_normal": "Normál",
"priority_high": "Magas", "priority_high": "Magas",
@@ -498,6 +502,8 @@
"settings_default_warning": "Alapértelmezett figyelmeztetési napok", "settings_default_warning": "Alapértelmezett figyelmeztetési napok",
"settings_consumable_threshold": "„Fogyóeszköz alacsony” küszöb (%)", "settings_consumable_threshold": "„Fogyóeszköz alacsony” küszöb (%)",
"settings_battery_low_percent": "„Alacsony akkumulátor” küszöb (%)", "settings_battery_low_percent": "„Alacsony akkumulátor” küszöb (%)",
"settings_battery_recovered_percent": "Az elem cseréltnek számít e fölött (%)",
"settings_battery_recovered_percent_hint": "A lemerült elem addig számít lemerültnek, amíg a töltöttsége e fölé az érték fölé nem emelkedik, vagy egy cserét nem rögzítenek — így a küszöb körül ingadozó töltöttség nem zárja le újra és újra a flottafeladatot.",
"settings_battery_lifetimes": "Jellemző elem-élettartamok", "settings_battery_lifetimes": "Jellemző elem-élettartamok",
"settings_battery_lifetimes_hint": "Csak százalék nélküli elemeknél használjuk: olyan Battery Notes-bejegyzésnél, amelynek csak típusa és cseredátuma van, vagy csak „alacsony”-t jelentő érzékelőnél. Esedékesség = utolsó csere + ez az élettartam. A szintet jelentő elemek előrejelzése a mért kisülésből jön. Ha a flotta már három cserét látott egy típusból, a medián időköz veszi át a beépített értéket — a saját értéked mindig nyer.", "settings_battery_lifetimes_hint": "Csak százalék nélküli elemeknél használjuk: olyan Battery Notes-bejegyzésnél, amelynek csak típusa és cseredátuma van, vagy csak „alacsony”-t jelentő érzékelőnél. Esedékesség = utolsó csere + ez az élettartam. A szintet jelentő elemek előrejelzése a mért kisülésből jön. Ha a flotta már három cserét látott egy típusból, a medián időköz veszi át a beépített értéket — a saját értéked mindig nyer.",
"settings_battery_lifetime_months": "hónap", "settings_battery_lifetime_months": "hónap",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "a flottádban", "settings_battery_lifetime_in_fleet": "a flottádban",
"settings_battery_lifetime_learned_models": "Modellenként tanulva: {list}", "settings_battery_lifetime_learned_models": "Modellenként tanulva: {list}",
"settings_thresholds_hint": "Alapértékek az új Javasolt beállításokhoz (százalékos maradék) és a saját Battery Notes-küszöb nélküli flottaelemekhez. A meglévő feladatok megtartják az értéküket.", "settings_thresholds_hint": "Alapértékek az új Javasolt beállításokhoz (százalékos maradék) és a saját Battery Notes-küszöb nélküli flottaelemekhez. A meglévő feladatok megtartják az értéküket.",
"settings_part_search_url": "Vásárlási keresőhivatkozás",
"settings_part_search_url_hint": "URL {q}-val a keresőkifejezések helyén, a terméklink nélküli alkatrészekhez. Hagyja üresen az automatikus bolthoz (ország, különben nyelv szerint).",
"settings_value_out_of_range": "Az értéknek {min} és {max} között kell lennie", "settings_value_out_of_range": "Az értéknek {min} és {max} között kell lennie",
"bn_summary": "{name}: {pct} % {n} elemhez", "bn_summary": "{name}: {pct} % {n} elemhez",
"bn_floor_decides": "A te {floor} %-os küszöböd dönt mindegyiknél; elemenként a két küszöb közül a magasabb számít.", "bn_floor_decides": "A te {floor} %-os küszöböd dönt mindegyiknél; elemenként a két küszöb közül a magasabb számít.",
@@ -723,6 +731,8 @@
"archived": "Archiválva", "archived": "Archiválva",
"show_archived": "Archiváltak megjelenítése", "show_archived": "Archiváltak megjelenítése",
"hide_archived": "Archiváltak elrejtése", "hide_archived": "Archiváltak elrejtése",
"section_collapse": "Szakasz összecsukása",
"section_expand": "Szakasz kibontása",
"confirm_archive_object": "Archiválja az objektumot és a feladatait? Megtartják előzményeiket, és később visszaállíthatók.", "confirm_archive_object": "Archiválja az objektumot és a feladatait? Megtartják előzményeiket, és később visszaállíthatók.",
"settings_archive": "Archiválás és megőrzés", "settings_archive": "Archiválás és megőrzés",
"settings_archive_desc": "Elvégzett egyszeri feladatok kivezetése törlés nélkül. Az archivált elemek rejtettek és inaktívak, de megtartják előzményeiket és költségeiket.", "settings_archive_desc": "Elvégzett egyszeri feladatok kivezetése törlés nélkül. Az archivált elemek rejtettek és inaktívak, de megtartják előzményeiket és költségeiket.",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Data non valida", "ws_err_invalid_date": "Data non valida",
"ws_err_invalid_format": "Formato non valido", "ws_err_invalid_format": "Formato non valido",
"ws_err_invalid_url": "Link non valido", "ws_err_invalid_url": "Link non valido",
"ws_err_invalid_mirror_todo": "Lista di cose da fare non valida",
"ws_err_not_configured": "Non ancora configurato", "ws_err_not_configured": "Non ancora configurato",
"ws_err_not_loaded": "Non ancora caricato — riprova tra un istante", "ws_err_not_loaded": "Non ancora caricato — riprova tra un istante",
"ws_err_limit_reached": "Limite raggiunto", "ws_err_limit_reached": "Limite raggiunto",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "Nessun valore predefinito per il completamento rapido", "ws_err_no_defaults": "Nessun valore predefinito per il completamento rapido",
"ws_err_self_link_device": "Un oggetto non può essere collegato a sé stesso", "ws_err_self_link_device": "Un oggetto non può essere collegato a sé stesso",
"ws_err_too_early": "Troppo presto — questa attività può essere completata solo più vicino alla scadenza", "ws_err_too_early": "Troppo presto — questa attività può essere completata solo più vicino alla scadenza",
"ws_err_invalid_search_template": "Il link di ricerca deve essere un URL http(s) contenente {q}",
"feat_schedule_time": "Pianificazione oraria", "feat_schedule_time": "Pianificazione oraria",
"feat_schedule_time_desc": "Le attività scadono a un'ora specifica anziché a mezzanotte.", "feat_schedule_time_desc": "Le attività scadono a un'ora specifica anziché a mezzanotte.",
"schedule_time_toggle": "Scadenza a un orario preciso", "schedule_time_toggle": "Scadenza a un orario preciso",
@@ -199,6 +201,8 @@
"labels": "Etichette", "labels": "Etichette",
"labels_placeholder": "es. sicurezza, stagionale, visibile-inquilino", "labels_placeholder": "es. sicurezza, stagionale, visibile-inquilino",
"labels_help": "Tag separati da virgole per filtri e report.", "labels_help": "Tag separati da virgole per filtri e report.",
"task_mirror_todo": "Rispecchia nelle liste di cose da fare",
"task_mirror_todo_hint": "L'attività compare in queste liste finché è in scadenza; spuntarla lì la completa qui.",
"priority_low": "Bassa", "priority_low": "Bassa",
"priority_normal": "Normale", "priority_normal": "Normale",
"priority_high": "Alta", "priority_high": "Alta",
@@ -496,6 +500,8 @@
"settings_default_warning": "Giorni di avviso predefiniti", "settings_default_warning": "Giorni di avviso predefiniti",
"settings_consumable_threshold": "Soglia „consumabile basso“ (%)", "settings_consumable_threshold": "Soglia „consumabile basso“ (%)",
"settings_battery_low_percent": "Soglia „batteria scarica“ (%)", "settings_battery_low_percent": "Soglia „batteria scarica“ (%)",
"settings_battery_recovered_percent": "Batteria considerata sostituita sopra (%)",
"settings_battery_recovered_percent_hint": "Una batteria scarica resta conteggiata come scarica finché il livello non supera questo valore o non viene registrata una sostituzione — così un livello che oscilla attorno alla soglia non completa di continuo l'attività della flotta.",
"settings_battery_lifetimes": "Durate tipiche delle batterie", "settings_battery_lifetimes": "Durate tipiche delle batterie",
"settings_battery_lifetimes_hint": "Usato solo per batterie senza percentuale: una nota Battery Notes con solo tipo e data di sostituzione, o un sensore che segnala solo « scarica ». La scadenza è ultima sostituzione + questa durata. Le batterie che riportano un livello ricavano la previsione dalla scarica misurata. Dopo tre sostituzioni dello stesso tipo, l'intervallo mediano sostituisce il valore integrato — il tuo valore vince sempre.", "settings_battery_lifetimes_hint": "Usato solo per batterie senza percentuale: una nota Battery Notes con solo tipo e data di sostituzione, o un sensore che segnala solo « scarica ». La scadenza è ultima sostituzione + questa durata. Le batterie che riportano un livello ricavano la previsione dalla scarica misurata. Dopo tre sostituzioni dello stesso tipo, l'intervallo mediano sostituisce il valore integrato — il tuo valore vince sempre.",
"settings_battery_lifetime_months": "mesi", "settings_battery_lifetime_months": "mesi",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "nel tuo parco", "settings_battery_lifetime_in_fleet": "nel tuo parco",
"settings_battery_lifetime_learned_models": "Appreso per modello: {list}", "settings_battery_lifetime_learned_models": "Appreso per modello: {list}",
"settings_thresholds_hint": "Valori predefiniti per le nuove Configurazioni suggerite (percentuale residua) e per le batterie della flotta senza soglia Battery Notes propria. Le attività esistenti mantengono il loro valore.", "settings_thresholds_hint": "Valori predefiniti per le nuove Configurazioni suggerite (percentuale residua) e per le batterie della flotta senza soglia Battery Notes propria. Le attività esistenti mantengono il loro valore.",
"settings_part_search_url": "Link di ricerca per l'acquisto",
"settings_part_search_url_hint": "URL con {q} al posto dei termini di ricerca, usato per i ricambi senza link al prodotto. Lasciare vuoto per il negozio automatico (per paese, altrimenti per lingua).",
"settings_value_out_of_range": "Il valore deve essere compreso tra {min} e {max}", "settings_value_out_of_range": "Il valore deve essere compreso tra {min} e {max}",
"bn_summary": "{name}: {pct} % per {n} batterie", "bn_summary": "{name}: {pct} % per {n} batterie",
"bn_floor_decides": "La tua soglia del {floor} % decide per tutte; per ogni batteria conta la più alta delle due soglie.", "bn_floor_decides": "La tua soglia del {floor} % decide per tutte; per ogni batteria conta la più alta delle due soglie.",
@@ -717,6 +725,8 @@
"archived": "Archiviato", "archived": "Archiviato",
"show_archived": "Mostra archiviati", "show_archived": "Mostra archiviati",
"hide_archived": "Nascondi archiviati", "hide_archived": "Nascondi archiviati",
"section_collapse": "Comprimi sezione",
"section_expand": "Espandi sezione",
"confirm_archive_object": "Archiviare questo oggetto e le sue attività? La cronologia viene conservata e può essere ripristinata in seguito.", "confirm_archive_object": "Archiviare questo oggetto e le sue attività? La cronologia viene conservata e può essere ripristinata in seguito.",
"settings_archive": "Archiviazione e conservazione", "settings_archive": "Archiviazione e conservazione",
"settings_archive_desc": "Metti da parte le attività una tantum completate senza eliminarle. Gli elementi archiviati sono nascosti e inattivi, ma conservano cronologia e costi.", "settings_archive_desc": "Metti da parte le attività una tantum completate senza eliminarle. Gli elementi archiviati sono nascosti e inattivi, ma conservano cronologia e costi.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "日付が無効です", "ws_err_invalid_date": "日付が無効です",
"ws_err_invalid_format": "形式が無効です", "ws_err_invalid_format": "形式が無効です",
"ws_err_invalid_url": "リンクが無効です", "ws_err_invalid_url": "リンクが無効です",
"ws_err_invalid_mirror_todo": "無効なToDoリスト",
"ws_err_not_configured": "まだ設定されていません", "ws_err_not_configured": "まだ設定されていません",
"ws_err_not_loaded": "まだ読み込まれていません — しばらくしてからもう一度お試しください", "ws_err_not_loaded": "まだ読み込まれていません — しばらくしてからもう一度お試しください",
"ws_err_limit_reached": "上限に達しました", "ws_err_limit_reached": "上限に達しました",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "クイック完了の既定値が設定されていません", "ws_err_no_defaults": "クイック完了の既定値が設定されていません",
"ws_err_self_link_device": "オブジェクトを自分自身にリンクすることはできません", "ws_err_self_link_device": "オブジェクトを自分自身にリンクすることはできません",
"ws_err_too_early": "早すぎます — このタスクは期日が近づいてからのみ完了できます", "ws_err_too_early": "早すぎます — このタスクは期日が近づいてからのみ完了できます",
"ws_err_invalid_search_template": "検索リンクは {q} を含む http(s) URL である必要があります",
"feat_schedule_time": "時刻指定スケジュール", "feat_schedule_time": "時刻指定スケジュール",
"feat_schedule_time_desc": "タスクが深夜0時ではなく指定した時刻に期限超過となります。", "feat_schedule_time_desc": "タスクが深夜0時ではなく指定した時刻に期限超過となります。",
"schedule_time_toggle": "特定の時刻に期限", "schedule_time_toggle": "特定の時刻に期限",
@@ -201,6 +203,8 @@
"labels": "ラベル", "labels": "ラベル",
"labels_placeholder": "例:安全、季節、入居者に表示", "labels_placeholder": "例:安全、季節、入居者に表示",
"labels_help": "フィルタリングとレポート用のカンマ区切りタグ。", "labels_help": "フィルタリングとレポート用のカンマ区切りタグ。",
"task_mirror_todo": "ToDoリストにミラーする",
"task_mirror_todo_hint": "期限中はこれらのリストにタスクが表示され、そこで完了にするとここでも完了になります。",
"priority_low": "低", "priority_low": "低",
"priority_normal": "標準", "priority_normal": "標準",
"priority_high": "高", "priority_high": "高",
@@ -498,6 +502,8 @@
"settings_default_warning": "既定の警告日数", "settings_default_warning": "既定の警告日数",
"settings_consumable_threshold": "消耗品「残量少」しきい値(%)", "settings_consumable_threshold": "消耗品「残量少」しきい値(%)",
"settings_battery_low_percent": "電池「残量少」しきい値(%)", "settings_battery_low_percent": "電池「残量少」しきい値(%)",
"settings_battery_recovered_percent": "この値を超えたら交換済みとみなす(%)",
"settings_battery_recovered_percent_hint": "残量が少ない電池は、残量がこの値を超えるか交換が記録されるまで「残量少」として数えられます。しきい値付近で変動する残量が一括タスクを何度も完了させることを防ぎます。",
"settings_battery_lifetimes": "電池の標準寿命", "settings_battery_lifetimes": "電池の標準寿命",
"settings_battery_lifetimes_hint": "パーセント表示のない電池にのみ使います:種類と交換日だけの Battery Notes メモや「残量低下」しか報告しないセンサーです。期日は最終交換日+この寿命。残量を報告する電池は実測の放電から予測します。同じ種類の交換を3回記録すると、中央値の間隔が内蔵値に代わります。自分で設定した値が常に優先されます。", "settings_battery_lifetimes_hint": "パーセント表示のない電池にのみ使います:種類と交換日だけの Battery Notes メモや「残量低下」しか報告しないセンサーです。期日は最終交換日+この寿命。残量を報告する電池は実測の放電から予測します。同じ種類の交換を3回記録すると、中央値の間隔が内蔵値に代わります。自分で設定した値が常に優先されます。",
"settings_battery_lifetime_months": "か月", "settings_battery_lifetime_months": "か月",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "使用中", "settings_battery_lifetime_in_fleet": "使用中",
"settings_battery_lifetime_learned_models": "型番ごとの学習値:{list}", "settings_battery_lifetime_learned_models": "型番ごとの学習値:{list}",
"settings_thresholds_hint": "新しい「推奨セットアップ」(残量パーセント)と、独自の Battery Notes しきい値を持たないバッテリー一覧の電池に適用される既定値です。既存のタスクは値を保持します。", "settings_thresholds_hint": "新しい「推奨セットアップ」(残量パーセント)と、独自の Battery Notes しきい値を持たないバッテリー一覧の電池に適用される既定値です。既存のタスクは値を保持します。",
"settings_part_search_url": "購入検索リンク",
"settings_part_search_url_hint": "検索語の代わりに {q} を含む URL。製品リンクのない部品に使われます。空欄なら自動選択(国、次に言語で判定)。",
"settings_value_out_of_range": "値は {min} から {max} の間で指定してください", "settings_value_out_of_range": "値は {min} から {max} の間で指定してください",
"bn_summary": "{name}:{n} 個の電池に {pct} %", "bn_summary": "{name}:{n} 個の電池に {pct} %",
"bn_floor_decides": "あなたの {floor} % のしきい値がすべてに適用されます。電池ごとに高い方のしきい値が有効です。", "bn_floor_decides": "あなたの {floor} % のしきい値がすべてに適用されます。電池ごとに高い方のしきい値が有効です。",
@@ -717,6 +725,8 @@
"archived": "アーカイブ済み", "archived": "アーカイブ済み",
"show_archived": "アーカイブを表示", "show_archived": "アーカイブを表示",
"hide_archived": "アーカイブを非表示", "hide_archived": "アーカイブを非表示",
"section_collapse": "セクションを折りたたむ",
"section_expand": "セクションを展開する",
"confirm_archive_object": "このオブジェクトとそのタスクをアーカイブしますか?履歴は保持され、後で元に戻せます。", "confirm_archive_object": "このオブジェクトとそのタスクをアーカイブしますか?履歴は保持され、後で元に戻せます。",
"settings_archive": "アーカイブと保持", "settings_archive": "アーカイブと保持",
"settings_archive_desc": "完了した単発タスクを削除せずに片付けます。アーカイブされた項目は非表示で動作しませんが、履歴とコストは保持されます。", "settings_archive_desc": "完了した単発タスクを削除せずに片付けます。アーカイブされた項目は非表示で動作しませんが、履歴とコストは保持されます。",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "잘못된 날짜", "ws_err_invalid_date": "잘못된 날짜",
"ws_err_invalid_format": "잘못된 형식", "ws_err_invalid_format": "잘못된 형식",
"ws_err_invalid_url": "잘못된 링크", "ws_err_invalid_url": "잘못된 링크",
"ws_err_invalid_mirror_todo": "잘못된 할 일 목록",
"ws_err_not_configured": "아직 설정되지 않음", "ws_err_not_configured": "아직 설정되지 않음",
"ws_err_not_loaded": "아직 로드되지 않음 — 잠시 후 다시 시도하세요", "ws_err_not_loaded": "아직 로드되지 않음 — 잠시 후 다시 시도하세요",
"ws_err_limit_reached": "한도에 도달함", "ws_err_limit_reached": "한도에 도달함",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "빠른 완료 기본값이 설정되지 않음", "ws_err_no_defaults": "빠른 완료 기본값이 설정되지 않음",
"ws_err_self_link_device": "객체는 자기 자신에게 연결할 수 없음", "ws_err_self_link_device": "객체는 자기 자신에게 연결할 수 없음",
"ws_err_too_early": "너무 이름 — 이 작업은 기한에 가까워져야 완료할 수 있습니다", "ws_err_too_early": "너무 이름 — 이 작업은 기한에 가까워져야 완료할 수 있습니다",
"ws_err_invalid_search_template": "검색 링크는 {q}를 포함한 http(s) URL이어야 합니다",
"feat_schedule_time": "시각 지정 일정", "feat_schedule_time": "시각 지정 일정",
"feat_schedule_time_desc": "작업이 자정이 아닌 지정한 시각에 기한 초과로 전환됩니다.", "feat_schedule_time_desc": "작업이 자정이 아닌 지정한 시각에 기한 초과로 전환됩니다.",
"schedule_time_toggle": "특정 시각에 기한", "schedule_time_toggle": "특정 시각에 기한",
@@ -201,6 +203,8 @@
"labels": "라벨", "labels": "라벨",
"labels_placeholder": "예: 안전, 계절, 세입자용", "labels_placeholder": "예: 안전, 계절, 세입자용",
"labels_help": "필터링과 보고서에 쓰이는 쉼표로 구분된 태그입니다.", "labels_help": "필터링과 보고서에 쓰이는 쉼표로 구분된 태그입니다.",
"task_mirror_todo": "할 일 목록에 미러링",
"task_mirror_todo_hint": "작업이 예정된 동안 이 목록에 표시되며, 거기서 완료하면 여기서도 완료됩니다.",
"priority_low": "낮음", "priority_low": "낮음",
"priority_normal": "보통", "priority_normal": "보통",
"priority_high": "높음", "priority_high": "높음",
@@ -498,6 +502,8 @@
"settings_default_warning": "기본 경고 일수", "settings_default_warning": "기본 경고 일수",
"settings_consumable_threshold": "소모품 „부족“ 임계값 (%)", "settings_consumable_threshold": "소모품 „부족“ 임계값 (%)",
"settings_battery_low_percent": "배터리 „부족“ 임계값 (%)", "settings_battery_low_percent": "배터리 „부족“ 임계값 (%)",
"settings_battery_recovered_percent": "이 값 초과 시 배터리 교체됨으로 간주 (%)",
"settings_battery_recovered_percent_hint": "부족한 배터리는 잔량이 이 값을 초과하거나 교체가 기록될 때까지 부족으로 계속 집계됩니다. 임계값 근처에서 오르내리는 잔량이 배터리 일괄 작업을 반복 완료하지 못하게 합니다.",
"settings_battery_lifetimes": "배터리 일반 수명", "settings_battery_lifetimes": "배터리 일반 수명",
"settings_battery_lifetimes_hint": "백분율이 없는 배터리에만 사용됩니다: 종류와 교체일만 있는 Battery Notes 메모나 \"낮음\"만 알리는 센서입니다. 만기 = 마지막 교체 + 이 수명. 잔량을 보고하는 배터리는 실측 방전으로 예측합니다. 같은 종류의 교체를 3회 기록하면 중앙값 간격이 내장값을 대체합니다. 직접 설정한 값이 항상 우선합니다.", "settings_battery_lifetimes_hint": "백분율이 없는 배터리에만 사용됩니다: 종류와 교체일만 있는 Battery Notes 메모나 \"낮음\"만 알리는 센서입니다. 만기 = 마지막 교체 + 이 수명. 잔량을 보고하는 배터리는 실측 방전으로 예측합니다. 같은 종류의 교체를 3회 기록하면 중앙값 간격이 내장값을 대체합니다. 직접 설정한 값이 항상 우선합니다.",
"settings_battery_lifetime_months": "개월", "settings_battery_lifetime_months": "개월",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "내 장치에 사용 중", "settings_battery_lifetime_in_fleet": "내 장치에 사용 중",
"settings_battery_lifetime_learned_models": "모델별 학습값: {list}", "settings_battery_lifetime_learned_models": "모델별 학습값: {list}",
"settings_thresholds_hint": "새 추천 설정(남은 비율)과 자체 Battery Notes 임계값이 없는 배터리 목록 배터리의 기본값입니다. 기존 작업은 값을 유지합니다.", "settings_thresholds_hint": "새 추천 설정(남은 비율)과 자체 Battery Notes 임계값이 없는 배터리 목록 배터리의 기본값입니다. 기존 작업은 값을 유지합니다.",
"settings_part_search_url": "구매 검색 링크",
"settings_part_search_url_hint": "검색어 자리에 {q}가 들어가는 URL로, 제품 링크가 없는 부품에 사용됩니다. 비워 두면 자동 선택(국가, 그다음 언어 기준)됩니다.",
"settings_value_out_of_range": "값은 {min}에서 {max} 사이여야 합니다", "settings_value_out_of_range": "값은 {min}에서 {max} 사이여야 합니다",
"bn_summary": "{name}: 배터리 {n}개에 {pct} %", "bn_summary": "{name}: 배터리 {n}개에 {pct} %",
"bn_floor_decides": "당신의 {floor} % 임계값이 모두에 적용됩니다. 배터리마다 두 임계값 중 높은 쪽이 적용됩니다.", "bn_floor_decides": "당신의 {floor} % 임계값이 모두에 적용됩니다. 배터리마다 두 임계값 중 높은 쪽이 적용됩니다.",
@@ -723,6 +731,8 @@
"archived": "보관됨", "archived": "보관됨",
"show_archived": "보관된 항목 보기", "show_archived": "보관된 항목 보기",
"hide_archived": "보관된 항목 숨기기", "hide_archived": "보관된 항목 숨기기",
"section_collapse": "섹션 접기",
"section_expand": "섹션 펼치기",
"confirm_archive_object": "이 객체와 작업을 보관할까요? 기록은 유지되며 나중에 보관 해제할 수 있습니다.", "confirm_archive_object": "이 객체와 작업을 보관할까요? 기록은 유지되며 나중에 보관 해제할 수 있습니다.",
"settings_archive": "보관 및 보존", "settings_archive": "보관 및 보존",
"settings_archive_desc": "완료된 일회성 작업을 삭제하지 않고 정리합니다. 보관된 항목은 숨겨지고 동작하지 않지만 기록과 비용은 유지됩니다.", "settings_archive_desc": "완료된 일회성 작업을 삭제하지 않고 정리합니다. 보관된 항목은 숨겨지고 동작하지 않지만 기록과 비용은 유지됩니다.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "Ugyldig dato", "ws_err_invalid_date": "Ugyldig dato",
"ws_err_invalid_format": "Ugyldig format", "ws_err_invalid_format": "Ugyldig format",
"ws_err_invalid_url": "Ugyldig lenke", "ws_err_invalid_url": "Ugyldig lenke",
"ws_err_invalid_mirror_todo": "Ugyldig gjøremålsliste",
"ws_err_not_configured": "Ikke satt opp ennå", "ws_err_not_configured": "Ikke satt opp ennå",
"ws_err_not_loaded": "Ikke lastet ennå — prøv igjen om et øyeblikk", "ws_err_not_loaded": "Ikke lastet ennå — prøv igjen om et øyeblikk",
"ws_err_limit_reached": "Grensen er nådd", "ws_err_limit_reached": "Grensen er nådd",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "Ingen standardverdier for hurtigfullføring", "ws_err_no_defaults": "Ingen standardverdier for hurtigfullføring",
"ws_err_self_link_device": "Et objekt kan ikke kobles til seg selv", "ws_err_self_link_device": "Et objekt kan ikke kobles til seg selv",
"ws_err_too_early": "For tidlig — oppgaven kan først fullføres nærmere forfallsdatoen", "ws_err_too_early": "For tidlig — oppgaven kan først fullføres nærmere forfallsdatoen",
"ws_err_invalid_search_template": "Søkelenken må være en http(s)-URL som inneholder {q}",
"feat_schedule_time": "Planlegging med klokkeslett", "feat_schedule_time": "Planlegging med klokkeslett",
"feat_schedule_time_desc": "Oppgaver forfaller på et bestemt klokkeslett i stedet for ved midnatt.", "feat_schedule_time_desc": "Oppgaver forfaller på et bestemt klokkeslett i stedet for ved midnatt.",
"schedule_time_toggle": "Forfaller på et bestemt klokkeslett", "schedule_time_toggle": "Forfaller på et bestemt klokkeslett",
@@ -201,6 +203,8 @@
"labels": "Etiketter", "labels": "Etiketter",
"labels_placeholder": "f.eks. sikkerhet, sesong, synlig-for-leietaker", "labels_placeholder": "f.eks. sikkerhet, sesong, synlig-for-leietaker",
"labels_help": "Kommaseparerte etiketter for filtrering og rapporter.", "labels_help": "Kommaseparerte etiketter for filtrering og rapporter.",
"task_mirror_todo": "Speil til gjøremålslister",
"task_mirror_todo_hint": "Oppgaven vises i disse listene mens den er aktuell; krysses den av der, fullføres den her.",
"priority_low": "Lav", "priority_low": "Lav",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Høy", "priority_high": "Høy",
@@ -498,6 +502,8 @@
"settings_default_warning": "Standard varslingsdager", "settings_default_warning": "Standard varslingsdager",
"settings_consumable_threshold": "Terskel „forbruksvare lav“ (%)", "settings_consumable_threshold": "Terskel „forbruksvare lav“ (%)",
"settings_battery_low_percent": "Terskel „batteri lavt“ (%)", "settings_battery_low_percent": "Terskel „batteri lavt“ (%)",
"settings_battery_recovered_percent": "Batteri regnes som byttet over (%)",
"settings_battery_recovered_percent_hint": "Et lavt batteri telles som lavt til nivået stiger over denne verdien eller et bytte registreres — slik kan et nivå som svinger rundt terskelen ikke fullføre flåteoppgaven igjen og igjen.",
"settings_battery_lifetimes": "Typiske batterilevetider", "settings_battery_lifetimes": "Typiske batterilevetider",
"settings_battery_lifetimes_hint": "Brukes bare for batterier uten prosent: et Battery Notes-notat med bare type og byttedato, eller en sensor som bare melder «lavt». Forfall = siste bytte + denne levetiden. Batterier som melder nivå får prognosen fra målt utlading. Når flåten har sett tre bytter av en type, overtar medianintervallet fra den innebygde verdien — din egen verdi vinner alltid.", "settings_battery_lifetimes_hint": "Brukes bare for batterier uten prosent: et Battery Notes-notat med bare type og byttedato, eller en sensor som bare melder «lavt». Forfall = siste bytte + denne levetiden. Batterier som melder nivå får prognosen fra målt utlading. Når flåten har sett tre bytter av en type, overtar medianintervallet fra den innebygde verdien — din egen verdi vinner alltid.",
"settings_battery_lifetime_months": "måneder", "settings_battery_lifetime_months": "måneder",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "i flåten din", "settings_battery_lifetime_in_fleet": "i flåten din",
"settings_battery_lifetime_learned_models": "Lært per modell: {list}", "settings_battery_lifetime_learned_models": "Lært per modell: {list}",
"settings_thresholds_hint": "Standardverdier for nye Foreslåtte oppsett (gjenværende prosent) og for flåtebatterier uten egen Battery Notes-terskel. Eksisterende oppgaver beholder verdien sin.", "settings_thresholds_hint": "Standardverdier for nye Foreslåtte oppsett (gjenværende prosent) og for flåtebatterier uten egen Battery Notes-terskel. Eksisterende oppgaver beholder verdien sin.",
"settings_part_search_url": "Søkelenke for innkjøp",
"settings_part_search_url_hint": "URL med {q} i stedet for søkeordene, for deler uten produktlenke. La stå tomt for den automatiske butikken (etter land, ellers språk).",
"settings_value_out_of_range": "Verdien må være mellom {min} og {max}", "settings_value_out_of_range": "Verdien må være mellom {min} og {max}",
"bn_summary": "{name}: {pct} % for {n} batterier", "bn_summary": "{name}: {pct} % for {n} batterier",
"bn_floor_decides": "Din terskel på {floor} % avgjør for alle; per batteri gjelder den høyeste av de to tersklene.", "bn_floor_decides": "Din terskel på {floor} % avgjør for alle; per batteri gjelder den høyeste av de to tersklene.",
@@ -717,6 +725,8 @@
"archived": "Arkivert", "archived": "Arkivert",
"show_archived": "Vis arkiverte", "show_archived": "Vis arkiverte",
"hide_archived": "Skjul arkiverte", "hide_archived": "Skjul arkiverte",
"section_collapse": "Fold sammen seksjonen",
"section_expand": "Fold ut seksjonen",
"confirm_archive_object": "Arkivere dette objektet og oppgavene? Historikken beholdes og kan gjenopprettes senere.", "confirm_archive_object": "Arkivere dette objektet og oppgavene? Historikken beholdes og kan gjenopprettes senere.",
"settings_archive": "Arkiv og oppbevaring", "settings_archive": "Arkiv og oppbevaring",
"settings_archive_desc": "Legg bort fullførte engangsoppgaver uten å slette dem. Arkiverte elementer er skjult og inaktive, men beholder historikk og kostnad.", "settings_archive_desc": "Legg bort fullførte engangsoppgaver uten å slette dem. Arkiverte elementer er skjult og inaktive, men beholder historikk og kostnad.",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Ongeldige datum", "ws_err_invalid_date": "Ongeldige datum",
"ws_err_invalid_format": "Ongeldig formaat", "ws_err_invalid_format": "Ongeldig formaat",
"ws_err_invalid_url": "Ongeldige link", "ws_err_invalid_url": "Ongeldige link",
"ws_err_invalid_mirror_todo": "Ongeldige takenlijst",
"ws_err_not_configured": "Nog niet ingesteld", "ws_err_not_configured": "Nog niet ingesteld",
"ws_err_not_loaded": "Nog niet geladen — probeer het zo opnieuw", "ws_err_not_loaded": "Nog niet geladen — probeer het zo opnieuw",
"ws_err_limit_reached": "Limiet bereikt", "ws_err_limit_reached": "Limiet bereikt",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "Geen standaardwaarden voor snel afronden ingesteld", "ws_err_no_defaults": "Geen standaardwaarden voor snel afronden ingesteld",
"ws_err_self_link_device": "Een object kan niet aan zichzelf worden gekoppeld", "ws_err_self_link_device": "Een object kan niet aan zichzelf worden gekoppeld",
"ws_err_too_early": "Te vroeg — deze taak kan pas dichter bij de vervaldatum worden afgerond", "ws_err_too_early": "Te vroeg — deze taak kan pas dichter bij de vervaldatum worden afgerond",
"ws_err_invalid_search_template": "De zoeklink moet een http(s)-URL met {q} zijn",
"feat_schedule_time": "Tijd-van-dag-planning", "feat_schedule_time": "Tijd-van-dag-planning",
"feat_schedule_time_desc": "Taken vervallen op een specifieke tijd in plaats van middernacht.", "feat_schedule_time_desc": "Taken vervallen op een specifieke tijd in plaats van middernacht.",
"schedule_time_toggle": "Vervalt op een vast tijdstip", "schedule_time_toggle": "Vervalt op een vast tijdstip",
@@ -199,6 +201,8 @@
"labels": "Labels", "labels": "Labels",
"labels_placeholder": "bijv. veiligheid, seizoensgebonden, zichtbaar-voor-huurder", "labels_placeholder": "bijv. veiligheid, seizoensgebonden, zichtbaar-voor-huurder",
"labels_help": "Kommagescheiden tags voor filteren en rapportages.", "labels_help": "Kommagescheiden tags voor filteren en rapportages.",
"task_mirror_todo": "Spiegelen naar takenlijsten",
"task_mirror_todo_hint": "De taak verschijnt in deze lijsten zolang ze te doen is; afvinken daar voltooit ze hier.",
"priority_low": "Laag", "priority_low": "Laag",
"priority_normal": "Normaal", "priority_normal": "Normaal",
"priority_high": "Hoog", "priority_high": "Hoog",
@@ -496,6 +500,8 @@
"settings_default_warning": "Standaard waarschuwingsdagen", "settings_default_warning": "Standaard waarschuwingsdagen",
"settings_consumable_threshold": "Drempel „verbruiksartikel laag“ (%)", "settings_consumable_threshold": "Drempel „verbruiksartikel laag“ (%)",
"settings_battery_low_percent": "Drempel „batterij laag“ (%)", "settings_battery_low_percent": "Drempel „batterij laag“ (%)",
"settings_battery_recovered_percent": "Batterij geldt als vervangen boven (%)",
"settings_battery_recovered_percent_hint": "Een lege batterij blijft als laag geteld tot het niveau boven deze waarde stijgt of een vervanging wordt vastgelegd — zo kan een niveau dat rond de drempel schommelt de vloottaak niet steeds opnieuw afronden.",
"settings_battery_lifetimes": "Gebruikelijke batterijlevensduur", "settings_battery_lifetimes": "Gebruikelijke batterijlevensduur",
"settings_battery_lifetimes_hint": "Alleen gebruikt voor batterijen zonder percentage: een Battery Notes-notitie met enkel een type en een vervangdatum, of een sensor die alleen „bijna leeg“ meldt. Hun vervaldatum is laatste vervanging + deze levensduur. Batterijen die een niveau melden krijgen hun voorspelling uit de gemeten ontlading. Zodra de vloot drie vervangingen van een type heeft gezien, vervangt het mediane interval de ingebouwde waarde — je eigen waarde wint altijd.", "settings_battery_lifetimes_hint": "Alleen gebruikt voor batterijen zonder percentage: een Battery Notes-notitie met enkel een type en een vervangdatum, of een sensor die alleen „bijna leeg“ meldt. Hun vervaldatum is laatste vervanging + deze levensduur. Batterijen die een niveau melden krijgen hun voorspelling uit de gemeten ontlading. Zodra de vloot drie vervangingen van een type heeft gezien, vervangt het mediane interval de ingebouwde waarde — je eigen waarde wint altijd.",
"settings_battery_lifetime_months": "maanden", "settings_battery_lifetime_months": "maanden",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "in je vloot", "settings_battery_lifetime_in_fleet": "in je vloot",
"settings_battery_lifetime_learned_models": "Geleerd per model: {list}", "settings_battery_lifetime_learned_models": "Geleerd per model: {list}",
"settings_thresholds_hint": "Standaardwaarden voor nieuwe Voorgestelde installaties (resterend percentage) en voor vlootbatterijen zonder eigen Battery Notes-drempel. Bestaande taken behouden hun waarde.", "settings_thresholds_hint": "Standaardwaarden voor nieuwe Voorgestelde installaties (resterend percentage) en voor vlootbatterijen zonder eigen Battery Notes-drempel. Bestaande taken behouden hun waarde.",
"settings_part_search_url": "Zoeklink voor aankopen",
"settings_part_search_url_hint": "URL met {q} op de plaats van de zoektermen, voor onderdelen zonder productlink. Leeg laten voor de automatische winkel (per land, anders per taal).",
"settings_value_out_of_range": "De waarde moet tussen {min} en {max} liggen", "settings_value_out_of_range": "De waarde moet tussen {min} en {max} liggen",
"bn_summary": "{name}: {pct} % voor {n} batterijen", "bn_summary": "{name}: {pct} % voor {n} batterijen",
"bn_floor_decides": "Jouw drempel van {floor} % beslist voor allemaal; per batterij telt de hoogste van de twee drempels.", "bn_floor_decides": "Jouw drempel van {floor} % beslist voor allemaal; per batterij telt de hoogste van de twee drempels.",
@@ -717,6 +725,8 @@
"archived": "Gearchiveerd", "archived": "Gearchiveerd",
"show_archived": "Gearchiveerde tonen", "show_archived": "Gearchiveerde tonen",
"hide_archived": "Gearchiveerde verbergen", "hide_archived": "Gearchiveerde verbergen",
"section_collapse": "Sectie inklappen",
"section_expand": "Sectie uitklappen",
"confirm_archive_object": "Dit object en zijn taken archiveren? De geschiedenis blijft behouden en kan later worden hersteld.", "confirm_archive_object": "Dit object en zijn taken archiveren? De geschiedenis blijft behouden en kan later worden hersteld.",
"settings_archive": "Archief & bewaring", "settings_archive": "Archief & bewaring",
"settings_archive_desc": "Voltooide eenmalige taken archiveren in plaats van verwijderen. Gearchiveerde items zijn verborgen en inactief, maar behouden geschiedenis en kosten.", "settings_archive_desc": "Voltooide eenmalige taken archiveren in plaats van verwijderen. Gearchiveerde items zijn verborgen en inactief, maar behouden geschiedenis en kosten.",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Nieprawidłowa data", "ws_err_invalid_date": "Nieprawidłowa data",
"ws_err_invalid_format": "Nieprawidłowy format", "ws_err_invalid_format": "Nieprawidłowy format",
"ws_err_invalid_url": "Nieprawidłowy link", "ws_err_invalid_url": "Nieprawidłowy link",
"ws_err_invalid_mirror_todo": "Nieprawidłowa lista zadań",
"ws_err_not_configured": "Jeszcze nie skonfigurowano", "ws_err_not_configured": "Jeszcze nie skonfigurowano",
"ws_err_not_loaded": "Jeszcze nie załadowano — spróbuj ponownie za chwilę", "ws_err_not_loaded": "Jeszcze nie załadowano — spróbuj ponownie za chwilę",
"ws_err_limit_reached": "Osiągnięto limit", "ws_err_limit_reached": "Osiągnięto limit",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "Brak domyślnych wartości szybkiego ukończenia", "ws_err_no_defaults": "Brak domyślnych wartości szybkiego ukończenia",
"ws_err_self_link_device": "Obiekt nie może być powiązany sam ze sobą", "ws_err_self_link_device": "Obiekt nie może być powiązany sam ze sobą",
"ws_err_too_early": "Za wcześnie — to zadanie można ukończyć dopiero bliżej terminu", "ws_err_too_early": "Za wcześnie — to zadanie można ukończyć dopiero bliżej terminu",
"ws_err_invalid_search_template": "Link wyszukiwania musi być adresem URL http(s) zawierającym {q}",
"feat_schedule_time": "Harmonogram według pory dnia", "feat_schedule_time": "Harmonogram według pory dnia",
"feat_schedule_time_desc": "Zadania stają się zaległe o określonej porze dnia zamiast o północy.", "feat_schedule_time_desc": "Zadania stają się zaległe o określonej porze dnia zamiast o północy.",
"schedule_time_toggle": "Termin o określonej godzinie", "schedule_time_toggle": "Termin o określonej godzinie",
@@ -199,6 +201,8 @@
"labels": "Etykiety", "labels": "Etykiety",
"labels_placeholder": "np. bezpieczeństwo, sezonowe, widoczne-dla-najemcy", "labels_placeholder": "np. bezpieczeństwo, sezonowe, widoczne-dla-najemcy",
"labels_help": "Tagi rozdzielone przecinkami do filtrowania i raportów.", "labels_help": "Tagi rozdzielone przecinkami do filtrowania i raportów.",
"task_mirror_todo": "Odzwierciedlaj na listach zadań",
"task_mirror_todo_hint": "Zadanie pojawia się na tych listach, dopóki jest do zrobienia; odhaczenie go tam kończy je tutaj.",
"priority_low": "Niski", "priority_low": "Niski",
"priority_normal": "Normalny", "priority_normal": "Normalny",
"priority_high": "Wysoki", "priority_high": "Wysoki",
@@ -496,6 +500,8 @@
"settings_default_warning": "Domyślne dni ostrzeżenia", "settings_default_warning": "Domyślne dni ostrzeżenia",
"settings_consumable_threshold": "Próg „materiał eksploatacyjny niski” (%)", "settings_consumable_threshold": "Próg „materiał eksploatacyjny niski” (%)",
"settings_battery_low_percent": "Próg „bateria słaba” (%)", "settings_battery_low_percent": "Próg „bateria słaba” (%)",
"settings_battery_recovered_percent": "Bateria uznana za wymienioną powyżej (%)",
"settings_battery_recovered_percent_hint": "Słaba bateria pozostaje liczona jako słaba, dopóki jej poziom nie wzrośnie powyżej tej wartości lub nie zostanie zapisana wymiana — poziom oscylujący wokół progu nie kończy więc zadania floty raz za razem.",
"settings_battery_lifetimes": "Typowa żywotność baterii", "settings_battery_lifetimes": "Typowa żywotność baterii",
"settings_battery_lifetimes_hint": "Używane tylko dla baterii bez procentu: notatka Battery Notes z samym typem i datą wymiany albo czujnik zgłaszający tylko „niski”. Termin = ostatnia wymiana + ta żywotność. Baterie raportujące poziom dostają prognozę z mierzonego rozładowania. Po trzech wymianach danego typu mediana odstępów zastępuje wbudowaną wartość — Twoja wartość zawsze wygrywa.", "settings_battery_lifetimes_hint": "Używane tylko dla baterii bez procentu: notatka Battery Notes z samym typem i datą wymiany albo czujnik zgłaszający tylko „niski”. Termin = ostatnia wymiana + ta żywotność. Baterie raportujące poziom dostają prognozę z mierzonego rozładowania. Po trzech wymianach danego typu mediana odstępów zastępuje wbudowaną wartość — Twoja wartość zawsze wygrywa.",
"settings_battery_lifetime_months": "mies.", "settings_battery_lifetime_months": "mies.",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "w Twojej flocie", "settings_battery_lifetime_in_fleet": "w Twojej flocie",
"settings_battery_lifetime_learned_models": "Nauczone według modelu: {list}", "settings_battery_lifetime_learned_models": "Nauczone według modelu: {list}",
"settings_thresholds_hint": "Wartości domyślne dla nowych Sugerowanych konfiguracji (procent pozostały) i dla baterii floty bez własnego progu Battery Notes. Istniejące zadania zachowują swoją wartość.", "settings_thresholds_hint": "Wartości domyślne dla nowych Sugerowanych konfiguracji (procent pozostały) i dla baterii floty bez własnego progu Battery Notes. Istniejące zadania zachowują swoją wartość.",
"settings_part_search_url": "Link wyszukiwania zakupów",
"settings_part_search_url_hint": "Adres URL z {q} w miejscu wyszukiwanych słów, dla części bez linku do produktu. Pozostaw puste dla automatycznego sklepu (według kraju, w przeciwnym razie języka).",
"settings_value_out_of_range": "Wartość musi mieścić się w zakresie od {min} do {max}", "settings_value_out_of_range": "Wartość musi mieścić się w zakresie od {min} do {max}",
"bn_summary": "{name}: {pct} % dla {n} baterii", "bn_summary": "{name}: {pct} % dla {n} baterii",
"bn_floor_decides": "Twój próg {floor} % decyduje dla wszystkich; dla każdej baterii liczy się wyższy z dwóch progów.", "bn_floor_decides": "Twój próg {floor} % decyduje dla wszystkich; dla każdej baterii liczy się wyższy z dwóch progów.",
@@ -717,6 +725,8 @@
"archived": "Zarchiwizowane", "archived": "Zarchiwizowane",
"show_archived": "Pokaż zarchiwizowane", "show_archived": "Pokaż zarchiwizowane",
"hide_archived": "Ukryj zarchiwizowane", "hide_archived": "Ukryj zarchiwizowane",
"section_collapse": "Zwiń sekcję",
"section_expand": "Rozwiń sekcję",
"confirm_archive_object": "Zarchiwizować ten obiekt i jego zadania? Historia zostanie zachowana i można ją później przywrócić.", "confirm_archive_object": "Zarchiwizować ten obiekt i jego zadania? Historia zostanie zachowana i można ją później przywrócić.",
"settings_archive": "Archiwum i przechowywanie", "settings_archive": "Archiwum i przechowywanie",
"settings_archive_desc": "Odkładaj ukończone zadania jednorazowe bez usuwania. Zarchiwizowane elementy są ukryte i nieaktywne, ale zachowują historię i koszty.", "settings_archive_desc": "Odkładaj ukończone zadania jednorazowe bez usuwania. Zarchiwizowane elementy są ukryte i nieaktywne, ale zachowują historię i koszty.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "Data inválida", "ws_err_invalid_date": "Data inválida",
"ws_err_invalid_format": "Formato inválido", "ws_err_invalid_format": "Formato inválido",
"ws_err_invalid_url": "Link inválido", "ws_err_invalid_url": "Link inválido",
"ws_err_invalid_mirror_todo": "Lista de tarefas inválida",
"ws_err_not_configured": "Ainda não configurado", "ws_err_not_configured": "Ainda não configurado",
"ws_err_not_loaded": "Ainda não carregado — tente novamente em instantes", "ws_err_not_loaded": "Ainda não carregado — tente novamente em instantes",
"ws_err_limit_reached": "Limite atingido", "ws_err_limit_reached": "Limite atingido",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "Sem padrões para conclusão rápida", "ws_err_no_defaults": "Sem padrões para conclusão rápida",
"ws_err_self_link_device": "Um objeto não pode ser vinculado a si mesmo", "ws_err_self_link_device": "Um objeto não pode ser vinculado a si mesmo",
"ws_err_too_early": "Cedo demais — esta tarefa só pode ser concluída mais perto do vencimento", "ws_err_too_early": "Cedo demais — esta tarefa só pode ser concluída mais perto do vencimento",
"ws_err_invalid_search_template": "O link de busca deve ser uma URL http(s) contendo {q}",
"feat_schedule_time": "Agendamento por horário", "feat_schedule_time": "Agendamento por horário",
"feat_schedule_time_desc": "As tarefas ficam atrasadas em um horário específico do dia, em vez de à meia-noite.", "feat_schedule_time_desc": "As tarefas ficam atrasadas em um horário específico do dia, em vez de à meia-noite.",
"schedule_time_toggle": "Vence em um horário específico", "schedule_time_toggle": "Vence em um horário específico",
@@ -201,6 +203,8 @@
"labels": "Etiquetas", "labels": "Etiquetas",
"labels_placeholder": "ex.: segurança, sazonal, visível ao inquilino", "labels_placeholder": "ex.: segurança, sazonal, visível ao inquilino",
"labels_help": "Tags separadas por vírgula para filtragem e relatórios.", "labels_help": "Tags separadas por vírgula para filtragem e relatórios.",
"task_mirror_todo": "Espelhar nas listas de tarefas",
"task_mirror_todo_hint": "A tarefa aparece nessas listas enquanto estiver pendente; marcá-la lá a conclui aqui.",
"priority_low": "Baixa", "priority_low": "Baixa",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Alta", "priority_high": "Alta",
@@ -498,6 +502,8 @@
"settings_default_warning": "Dias de aviso padrão", "settings_default_warning": "Dias de aviso padrão",
"settings_consumable_threshold": "Limite „consumível baixo“ (%)", "settings_consumable_threshold": "Limite „consumível baixo“ (%)",
"settings_battery_low_percent": "Limite „pilha fraca“ (%)", "settings_battery_low_percent": "Limite „pilha fraca“ (%)",
"settings_battery_recovered_percent": "Pilha considerada trocada acima de (%)",
"settings_battery_recovered_percent_hint": "Uma pilha fraca continua contando como fraca até o nível subir acima deste valor ou uma troca ser registrada — assim um nível oscilando em torno do limite não conclui a tarefa da frota repetidamente.",
"settings_battery_lifetimes": "Vida útil típica das pilhas", "settings_battery_lifetimes": "Vida útil típica das pilhas",
"settings_battery_lifetimes_hint": "Usado apenas para pilhas sem porcentagem: uma nota do Battery Notes só com tipo e data de troca, ou um sensor que apenas informa « fraca ». O vencimento é última troca + esta vida útil. Pilhas que informam nível têm a previsão pela descarga medida. Após três trocas de um tipo, o intervalo mediano substitui o valor integrado — seu valor sempre vence.", "settings_battery_lifetimes_hint": "Usado apenas para pilhas sem porcentagem: uma nota do Battery Notes só com tipo e data de troca, ou um sensor que apenas informa « fraca ». O vencimento é última troca + esta vida útil. Pilhas que informam nível têm a previsão pela descarga medida. Após três trocas de um tipo, o intervalo mediano substitui o valor integrado — seu valor sempre vence.",
"settings_battery_lifetime_months": "meses", "settings_battery_lifetime_months": "meses",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "na sua frota", "settings_battery_lifetime_in_fleet": "na sua frota",
"settings_battery_lifetime_learned_models": "Aprendido por modelo: {list}", "settings_battery_lifetime_learned_models": "Aprendido por modelo: {list}",
"settings_thresholds_hint": "Padrões para novas Configurações sugeridas (porcentagem restante) e para pilhas da frota sem limite próprio do Battery Notes. As tarefas existentes mantêm seu valor.", "settings_thresholds_hint": "Padrões para novas Configurações sugeridas (porcentagem restante) e para pilhas da frota sem limite próprio do Battery Notes. As tarefas existentes mantêm seu valor.",
"settings_part_search_url": "Link de busca para compra",
"settings_part_search_url_hint": "URL com {q} no lugar dos termos de busca, usada para peças sem link de produto. Deixe vazio para a loja automática (por país, senão por idioma).",
"settings_value_out_of_range": "O valor deve estar entre {min} e {max}", "settings_value_out_of_range": "O valor deve estar entre {min} e {max}",
"bn_summary": "{name}: {pct} % para {n} pilhas", "bn_summary": "{name}: {pct} % para {n} pilhas",
"bn_floor_decides": "Seu limite de {floor} % decide para todas; por pilha vale o maior dos dois limites.", "bn_floor_decides": "Seu limite de {floor} % decide para todas; por pilha vale o maior dos dois limites.",
@@ -723,6 +731,8 @@
"archived": "Arquivada", "archived": "Arquivada",
"show_archived": "Mostrar arquivados", "show_archived": "Mostrar arquivados",
"hide_archived": "Ocultar arquivados", "hide_archived": "Ocultar arquivados",
"section_collapse": "Recolher seção",
"section_expand": "Expandir seção",
"confirm_archive_object": "Arquivar este objeto e suas tarefas? Eles mantêm o histórico e podem ser desarquivados depois.", "confirm_archive_object": "Arquivar este objeto e suas tarefas? Eles mantêm o histórico e podem ser desarquivados depois.",
"settings_archive": "Arquivamento e retenção", "settings_archive": "Arquivamento e retenção",
"settings_archive_desc": "Aposente tarefas únicas concluídas sem excluí-las. Itens arquivados ficam ocultos e inativos, mas mantêm o histórico e o custo.", "settings_archive_desc": "Aposente tarefas únicas concluídas sem excluí-las. Itens arquivados ficam ocultos e inativos, mas mantêm o histórico e o custo.",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Data inválida", "ws_err_invalid_date": "Data inválida",
"ws_err_invalid_format": "Formato inválido", "ws_err_invalid_format": "Formato inválido",
"ws_err_invalid_url": "Ligação inválida", "ws_err_invalid_url": "Ligação inválida",
"ws_err_invalid_mirror_todo": "Lista de tarefas inválida",
"ws_err_not_configured": "Ainda não configurado", "ws_err_not_configured": "Ainda não configurado",
"ws_err_not_loaded": "Ainda não carregado — tente novamente daqui a pouco", "ws_err_not_loaded": "Ainda não carregado — tente novamente daqui a pouco",
"ws_err_limit_reached": "Limite atingido", "ws_err_limit_reached": "Limite atingido",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "Sem predefinições para conclusão rápida", "ws_err_no_defaults": "Sem predefinições para conclusão rápida",
"ws_err_self_link_device": "Um objeto não pode ser ligado a si próprio", "ws_err_self_link_device": "Um objeto não pode ser ligado a si próprio",
"ws_err_too_early": "Demasiado cedo — esta tarefa só pode ser concluída mais perto do prazo", "ws_err_too_early": "Demasiado cedo — esta tarefa só pode ser concluída mais perto do prazo",
"ws_err_invalid_search_template": "A ligação de pesquisa tem de ser um URL http(s) com {q}",
"feat_schedule_time": "Agendamento por hora", "feat_schedule_time": "Agendamento por hora",
"feat_schedule_time_desc": "Tarefas vencem em um horário específico em vez de meia-noite.", "feat_schedule_time_desc": "Tarefas vencem em um horário específico em vez de meia-noite.",
"schedule_time_toggle": "Vence a uma hora específica", "schedule_time_toggle": "Vence a uma hora específica",
@@ -199,6 +201,8 @@
"labels": "Etiquetas", "labels": "Etiquetas",
"labels_placeholder": "p. ex. segurança, sazonal, visível-inquilino", "labels_placeholder": "p. ex. segurança, sazonal, visível-inquilino",
"labels_help": "Etiquetas separadas por vírgulas para filtragem e relatórios.", "labels_help": "Etiquetas separadas por vírgulas para filtragem e relatórios.",
"task_mirror_todo": "Espelhar em listas de tarefas",
"task_mirror_todo_hint": "A tarefa aparece nestas listas enquanto estiver pendente; marcá-la lá conclui-a aqui.",
"priority_low": "Baixa", "priority_low": "Baixa",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Alta", "priority_high": "Alta",
@@ -496,6 +500,8 @@
"settings_default_warning": "Dias de aviso predefinidos", "settings_default_warning": "Dias de aviso predefinidos",
"settings_consumable_threshold": "Limiar „consumível baixo“ (%)", "settings_consumable_threshold": "Limiar „consumível baixo“ (%)",
"settings_battery_low_percent": "Limiar „pilha fraca“ (%)", "settings_battery_low_percent": "Limiar „pilha fraca“ (%)",
"settings_battery_recovered_percent": "Pilha considerada substituída acima de (%)",
"settings_battery_recovered_percent_hint": "Uma pilha fraca continua a contar como fraca até o nível subir acima deste valor ou ser registada uma substituição — assim, um nível que oscila em torno do limiar não conclui a tarefa da frota vezes sem conta.",
"settings_battery_lifetimes": "Durações típicas das pilhas", "settings_battery_lifetimes": "Durações típicas das pilhas",
"settings_battery_lifetimes_hint": "Usado apenas para pilhas sem percentagem: uma nota do Battery Notes só com tipo e data de substituição, ou um sensor que apenas reporta « fraca ». O vencimento é última substituição + esta duração. Pilhas que reportam nível obtêm a previsão da descarga medida. Após três substituições de um tipo, o intervalo mediano substitui o valor integrado — o seu valor ganha sempre.", "settings_battery_lifetimes_hint": "Usado apenas para pilhas sem percentagem: uma nota do Battery Notes só com tipo e data de substituição, ou um sensor que apenas reporta « fraca ». O vencimento é última substituição + esta duração. Pilhas que reportam nível obtêm a previsão da descarga medida. Após três substituições de um tipo, o intervalo mediano substitui o valor integrado — o seu valor ganha sempre.",
"settings_battery_lifetime_months": "meses", "settings_battery_lifetime_months": "meses",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "na sua frota", "settings_battery_lifetime_in_fleet": "na sua frota",
"settings_battery_lifetime_learned_models": "Aprendido por modelo: {list}", "settings_battery_lifetime_learned_models": "Aprendido por modelo: {list}",
"settings_thresholds_hint": "Predefinições para novas Configurações sugeridas (percentagem restante) e para pilhas da frota sem limiar Battery Notes próprio. As tarefas existentes mantêm o seu valor.", "settings_thresholds_hint": "Predefinições para novas Configurações sugeridas (percentagem restante) e para pilhas da frota sem limiar Battery Notes próprio. As tarefas existentes mantêm o seu valor.",
"settings_part_search_url": "Ligação de pesquisa de compra",
"settings_part_search_url_hint": "URL com {q} no lugar dos termos de pesquisa, usada para peças sem ligação de produto. Deixar vazio para a loja automática (por país, senão por idioma).",
"settings_value_out_of_range": "O valor tem de estar entre {min} e {max}", "settings_value_out_of_range": "O valor tem de estar entre {min} e {max}",
"bn_summary": "{name}: {pct} % para {n} pilhas", "bn_summary": "{name}: {pct} % para {n} pilhas",
"bn_floor_decides": "O teu limiar de {floor} % decide para todas; por pilha conta o mais alto dos dois limiares.", "bn_floor_decides": "O teu limiar de {floor} % decide para todas; por pilha conta o mais alto dos dois limiares.",
@@ -717,6 +725,8 @@
"archived": "Arquivado", "archived": "Arquivado",
"show_archived": "Mostrar arquivados", "show_archived": "Mostrar arquivados",
"hide_archived": "Ocultar arquivados", "hide_archived": "Ocultar arquivados",
"section_collapse": "Recolher secção",
"section_expand": "Expandir secção",
"confirm_archive_object": "Arquivar este objeto e as suas tarefas? O histórico é mantido e pode ser restaurado mais tarde.", "confirm_archive_object": "Arquivar este objeto e as suas tarefas? O histórico é mantido e pode ser restaurado mais tarde.",
"settings_archive": "Arquivo e retenção", "settings_archive": "Arquivo e retenção",
"settings_archive_desc": "Retire tarefas únicas concluídas sem as eliminar. Os itens arquivados ficam ocultos e inativos, mas mantêm histórico e custos.", "settings_archive_desc": "Retire tarefas únicas concluídas sem as eliminar. Os itens arquivados ficam ocultos e inativos, mas mantêm histórico e custos.",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Недопустимая дата", "ws_err_invalid_date": "Недопустимая дата",
"ws_err_invalid_format": "Недопустимый формат", "ws_err_invalid_format": "Недопустимый формат",
"ws_err_invalid_url": "Недопустимая ссылка", "ws_err_invalid_url": "Недопустимая ссылка",
"ws_err_invalid_mirror_todo": "Недопустимый список дел",
"ws_err_not_configured": "Ещё не настроено", "ws_err_not_configured": "Ещё не настроено",
"ws_err_not_loaded": "Ещё не загружено — попробуйте чуть позже", "ws_err_not_loaded": "Ещё не загружено — попробуйте чуть позже",
"ws_err_limit_reached": "Достигнут предел", "ws_err_limit_reached": "Достигнут предел",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "Не заданы значения по умолчанию для быстрого завершения", "ws_err_no_defaults": "Не заданы значения по умолчанию для быстрого завершения",
"ws_err_self_link_device": "Объект нельзя связать с самим собой", "ws_err_self_link_device": "Объект нельзя связать с самим собой",
"ws_err_too_early": "Слишком рано — эту задачу можно завершить только ближе к сроку", "ws_err_too_early": "Слишком рано — эту задачу можно завершить только ближе к сроку",
"ws_err_invalid_search_template": "Ссылка для поиска должна быть URL http(s) с {q}",
"feat_schedule_time": "Планирование по времени дня", "feat_schedule_time": "Планирование по времени дня",
"feat_schedule_time_desc": "Задачи становятся просроченными в определённое время дня, а не в полночь.", "feat_schedule_time_desc": "Задачи становятся просроченными в определённое время дня, а не в полночь.",
"schedule_time_toggle": "Срок в определённое время", "schedule_time_toggle": "Срок в определённое время",
@@ -199,6 +201,8 @@
"labels": "Метки", "labels": "Метки",
"labels_placeholder": "напр. безопасность, сезонное, видно-арендатору", "labels_placeholder": "напр. безопасность, сезонное, видно-арендатору",
"labels_help": "Теги через запятую для фильтрации и отчётов.", "labels_help": "Теги через запятую для фильтрации и отчётов.",
"task_mirror_todo": "Отражать в списках дел",
"task_mirror_todo_hint": "Задача появляется в этих списках, пока она актуальна; отметка там завершает её здесь.",
"priority_low": "Низкий", "priority_low": "Низкий",
"priority_normal": "Обычный", "priority_normal": "Обычный",
"priority_high": "Высокий", "priority_high": "Высокий",
@@ -496,6 +500,8 @@
"settings_default_warning": "Дни предупреждения по умолчанию", "settings_default_warning": "Дни предупреждения по умолчанию",
"settings_consumable_threshold": "Порог «расходник заканчивается» (%)", "settings_consumable_threshold": "Порог «расходник заканчивается» (%)",
"settings_battery_low_percent": "Порог «батарея разряжена» (%)", "settings_battery_low_percent": "Порог «батарея разряжена» (%)",
"settings_battery_recovered_percent": "Батарея считается заменённой выше (%)",
"settings_battery_recovered_percent_hint": "Разряженная батарея считается разряженной, пока её уровень не поднимется выше этого значения или не будет записана замена — уровень, колеблющийся около порога, больше не завершает задачу парка снова и снова.",
"settings_battery_lifetimes": "Типичный срок службы батарей", "settings_battery_lifetimes": "Типичный срок службы батарей",
"settings_battery_lifetimes_hint": "Используется только для батарей без процента: заметка Battery Notes лишь с типом и датой замены или датчик, сообщающий только «низкий». Срок = последняя замена + этот срок службы. Для батарей с уровнем прогноз строится по измеренному разряду. После трёх замен одного типа медианный интервал заменяет встроенное значение — ваше значение всегда главнее.", "settings_battery_lifetimes_hint": "Используется только для батарей без процента: заметка Battery Notes лишь с типом и датой замены или датчик, сообщающий только «низкий». Срок = последняя замена + этот срок службы. Для батарей с уровнем прогноз строится по измеренному разряду. После трёх замен одного типа медианный интервал заменяет встроенное значение — ваше значение всегда главнее.",
"settings_battery_lifetime_months": "мес.", "settings_battery_lifetime_months": "мес.",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "в вашем парке", "settings_battery_lifetime_in_fleet": "в вашем парке",
"settings_battery_lifetime_learned_models": "Изучено по моделям: {list}", "settings_battery_lifetime_learned_models": "Изучено по моделям: {list}",
"settings_thresholds_hint": "Значения по умолчанию для новых «Предлагаемых настроек» (остаток в процентах) и для батарей парка без собственного порога Battery Notes. Существующие задачи сохраняют своё значение.", "settings_thresholds_hint": "Значения по умолчанию для новых «Предлагаемых настроек» (остаток в процентах) и для батарей парка без собственного порога Battery Notes. Существующие задачи сохраняют своё значение.",
"settings_part_search_url": "Ссылка для поиска покупки",
"settings_part_search_url_hint": "URL с {q} вместо поискового запроса, для деталей без ссылки на товар. Оставьте пустым для автоматического магазина (по стране, иначе по языку).",
"settings_value_out_of_range": "Значение должно быть от {min} до {max}", "settings_value_out_of_range": "Значение должно быть от {min} до {max}",
"bn_summary": "{name}: {pct} % для {n} батарей", "bn_summary": "{name}: {pct} % для {n} батарей",
"bn_floor_decides": "Ваш порог {floor} % действует для всех; для каждой батареи учитывается больший из двух порогов.", "bn_floor_decides": "Ваш порог {floor} % действует для всех; для каждой батареи учитывается больший из двух порогов.",
@@ -717,6 +725,8 @@
"archived": "В архиве", "archived": "В архиве",
"show_archived": "Показать архив", "show_archived": "Показать архив",
"hide_archived": "Скрыть архив", "hide_archived": "Скрыть архив",
"section_collapse": "Свернуть раздел",
"section_expand": "Развернуть раздел",
"confirm_archive_object": "Архивировать этот объект и его задачи? История сохранится, позже можно восстановить.", "confirm_archive_object": "Архивировать этот объект и его задачи? История сохранится, позже можно восстановить.",
"settings_archive": "Архив и хранение", "settings_archive": "Архив и хранение",
"settings_archive_desc": "Убирайте выполненные разовые задачи в архив, не удаляя их. Архивные элементы скрыты и неактивны, но сохраняют историю и расходы.", "settings_archive_desc": "Убирайте выполненные разовые задачи в архив, не удаляя их. Архивные элементы скрыты и неактивны, но сохраняют историю и расходы.",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Ogiltigt datum", "ws_err_invalid_date": "Ogiltigt datum",
"ws_err_invalid_format": "Ogiltigt format", "ws_err_invalid_format": "Ogiltigt format",
"ws_err_invalid_url": "Ogiltig länk", "ws_err_invalid_url": "Ogiltig länk",
"ws_err_invalid_mirror_todo": "Ogiltig att-göra-lista",
"ws_err_not_configured": "Inte inställt ännu", "ws_err_not_configured": "Inte inställt ännu",
"ws_err_not_loaded": "Inte inläst ännu — försök igen om en stund", "ws_err_not_loaded": "Inte inläst ännu — försök igen om en stund",
"ws_err_limit_reached": "Gränsen nådd", "ws_err_limit_reached": "Gränsen nådd",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "Inga standardvärden för snabbslutförande", "ws_err_no_defaults": "Inga standardvärden för snabbslutförande",
"ws_err_self_link_device": "Ett objekt kan inte länkas till sig självt", "ws_err_self_link_device": "Ett objekt kan inte länkas till sig självt",
"ws_err_too_early": "För tidigt — uppgiften kan bara slutföras närmare förfallodatumet", "ws_err_too_early": "För tidigt — uppgiften kan bara slutföras närmare förfallodatumet",
"ws_err_invalid_search_template": "Söklänken måste vara en http(s)-URL som innehåller {q}",
"feat_schedule_time": "Schemaläggning per tid på dygnet", "feat_schedule_time": "Schemaläggning per tid på dygnet",
"feat_schedule_time_desc": "Uppgifter blir försenade vid en specifik tid på dygnet istället för midnatt.", "feat_schedule_time_desc": "Uppgifter blir försenade vid en specifik tid på dygnet istället för midnatt.",
"schedule_time_toggle": "Förfaller vid en viss tid", "schedule_time_toggle": "Förfaller vid en viss tid",
@@ -199,6 +201,8 @@
"labels": "Etiketter", "labels": "Etiketter",
"labels_placeholder": "t.ex. säkerhet, säsong, synlig-för-hyresgäst", "labels_placeholder": "t.ex. säkerhet, säsong, synlig-för-hyresgäst",
"labels_help": "Kommaseparerade taggar för filtrering och rapporter.", "labels_help": "Kommaseparerade taggar för filtrering och rapporter.",
"task_mirror_todo": "Spegla till att-göra-listor",
"task_mirror_todo_hint": "Uppgiften visas i dessa listor så länge den är aktuell; bockar du av den där slutförs den här.",
"priority_low": "Låg", "priority_low": "Låg",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Hög", "priority_high": "Hög",
@@ -496,6 +500,8 @@
"settings_default_warning": "Standard varningsdagar", "settings_default_warning": "Standard varningsdagar",
"settings_consumable_threshold": "Tröskel „förbrukningsartikel låg“ (%)", "settings_consumable_threshold": "Tröskel „förbrukningsartikel låg“ (%)",
"settings_battery_low_percent": "Tröskel „batteri lågt“ (%)", "settings_battery_low_percent": "Tröskel „batteri lågt“ (%)",
"settings_battery_recovered_percent": "Batteri räknas som bytt över (%)",
"settings_battery_recovered_percent_hint": "Ett lågt batteri räknas som lågt tills nivån stiger över detta värde eller ett byte registreras — så kan en nivå som pendlar kring tröskeln inte slutföra flottuppgiften om och om igen.",
"settings_battery_lifetimes": "Typiska batterilivslängder", "settings_battery_lifetimes": "Typiska batterilivslängder",
"settings_battery_lifetimes_hint": "Används bara för batterier utan procent: en Battery Notes-anteckning med bara typ och bytesdatum, eller en sensor som bara rapporterar ”lågt”. Deras förfallodatum är senaste byte + denna livslängd. Batterier som rapporterar nivå får sin prognos från den uppmätta urladdningen. När flottan sett tre byten av en typ tar medianintervallet över från det inbyggda värdet — ditt eget värde vinner alltid.", "settings_battery_lifetimes_hint": "Används bara för batterier utan procent: en Battery Notes-anteckning med bara typ och bytesdatum, eller en sensor som bara rapporterar ”lågt”. Deras förfallodatum är senaste byte + denna livslängd. Batterier som rapporterar nivå får sin prognos från den uppmätta urladdningen. När flottan sett tre byten av en typ tar medianintervallet över från det inbyggda värdet — ditt eget värde vinner alltid.",
"settings_battery_lifetime_months": "månader", "settings_battery_lifetime_months": "månader",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "i din flotta", "settings_battery_lifetime_in_fleet": "i din flotta",
"settings_battery_lifetime_learned_models": "Inlärt per modell: {list}", "settings_battery_lifetime_learned_models": "Inlärt per modell: {list}",
"settings_thresholds_hint": "Standardvärden för nya Föreslagna inställningar (återstående procent) och för flottans batterier utan egen Battery Notes-tröskel. Befintliga uppgifter behåller sitt värde.", "settings_thresholds_hint": "Standardvärden för nya Föreslagna inställningar (återstående procent) och för flottans batterier utan egen Battery Notes-tröskel. Befintliga uppgifter behåller sitt värde.",
"settings_part_search_url": "Söklänk för inköp",
"settings_part_search_url_hint": "URL med {q} i stället för söktermerna, för delar utan produktlänk. Lämna tomt för den automatiska butiken (efter land, annars språk).",
"settings_value_out_of_range": "Värdet måste vara mellan {min} och {max}", "settings_value_out_of_range": "Värdet måste vara mellan {min} och {max}",
"bn_summary": "{name}: {pct} % för {n} batterier", "bn_summary": "{name}: {pct} % för {n} batterier",
"bn_floor_decides": "Din tröskel på {floor} % avgör för alla; per batteri gäller den högre av de två trösklarna.", "bn_floor_decides": "Din tröskel på {floor} % avgör för alla; per batteri gäller den högre av de två trösklarna.",
@@ -717,6 +725,8 @@
"archived": "Arkiverad", "archived": "Arkiverad",
"show_archived": "Visa arkiverade", "show_archived": "Visa arkiverade",
"hide_archived": "Dölj arkiverade", "hide_archived": "Dölj arkiverade",
"section_collapse": "Fäll ihop sektionen",
"section_expand": "Fäll ut sektionen",
"confirm_archive_object": "Arkivera detta objekt och dess uppgifter? Historiken behålls och kan återställas senare.", "confirm_archive_object": "Arkivera detta objekt och dess uppgifter? Historiken behålls och kan återställas senare.",
"settings_archive": "Arkiv och lagring", "settings_archive": "Arkiv och lagring",
"settings_archive_desc": "Lägg undan slutförda engångsuppgifter utan att radera dem. Arkiverade objekt döljs och är inaktiva men behåller historik och kostnad.", "settings_archive_desc": "Lägg undan slutförda engångsuppgifter utan att radera dem. Arkiverade objekt döljs och är inaktiva men behåller historik och kostnad.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "Geçersiz tarih", "ws_err_invalid_date": "Geçersiz tarih",
"ws_err_invalid_format": "Geçersiz biçim", "ws_err_invalid_format": "Geçersiz biçim",
"ws_err_invalid_url": "Geçersiz bağlantı", "ws_err_invalid_url": "Geçersiz bağlantı",
"ws_err_invalid_mirror_todo": "Geçersiz yapılacaklar listesi",
"ws_err_not_configured": "Henüz ayarlanmadı", "ws_err_not_configured": "Henüz ayarlanmadı",
"ws_err_not_loaded": "Henüz yüklenmedi — birazdan tekrar deneyin", "ws_err_not_loaded": "Henüz yüklenmedi — birazdan tekrar deneyin",
"ws_err_limit_reached": "Sınıra ulaşıldı", "ws_err_limit_reached": "Sınıra ulaşıldı",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "Hızlı tamamlama varsayılanları ayarlanmamış", "ws_err_no_defaults": "Hızlı tamamlama varsayılanları ayarlanmamış",
"ws_err_self_link_device": "Bir nesne kendisine bağlanamaz", "ws_err_self_link_device": "Bir nesne kendisine bağlanamaz",
"ws_err_too_early": "Çok erken — bu görev ancak son tarihine yaklaşınca tamamlanabilir", "ws_err_too_early": "Çok erken — bu görev ancak son tarihine yaklaşınca tamamlanabilir",
"ws_err_invalid_search_template": "Arama bağlantısı {q} içeren bir http(s) URL olmalıdır",
"feat_schedule_time": "Gün içi saat zamanlaması", "feat_schedule_time": "Gün içi saat zamanlaması",
"feat_schedule_time_desc": "Görevler gece yarısı yerine günün belirli bir saatinde gecikmiş olur.", "feat_schedule_time_desc": "Görevler gece yarısı yerine günün belirli bir saatinde gecikmiş olur.",
"schedule_time_toggle": "Belirli bir saatte vadesi dolar", "schedule_time_toggle": "Belirli bir saatte vadesi dolar",
@@ -201,6 +203,8 @@
"labels": "Etiketler", "labels": "Etiketler",
"labels_placeholder": "örn. güvenlik, mevsimlik, kiracıya görünür", "labels_placeholder": "örn. güvenlik, mevsimlik, kiracıya görünür",
"labels_help": "Filtreleme ve raporlama için virgülle ayrılmış etiketler.", "labels_help": "Filtreleme ve raporlama için virgülle ayrılmış etiketler.",
"task_mirror_todo": "Yapılacaklar listelerine yansıt",
"task_mirror_todo_hint": "Görev, zamanı geldiği sürece bu listelerde görünür; orada tamamlandı olarak işaretlemek burada da tamamlar.",
"priority_low": "Düşük", "priority_low": "Düşük",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Yüksek", "priority_high": "Yüksek",
@@ -498,6 +502,8 @@
"settings_default_warning": "Varsayılan uyarı günleri", "settings_default_warning": "Varsayılan uyarı günleri",
"settings_consumable_threshold": "„Sarf malzemesi düşük“ eşiği (%)", "settings_consumable_threshold": "„Sarf malzemesi düşük“ eşiği (%)",
"settings_battery_low_percent": "„Pil zayıf“ eşiği (%)", "settings_battery_low_percent": "„Pil zayıf“ eşiği (%)",
"settings_battery_recovered_percent": "Pil şu değerin üzerinde değiştirilmiş sayılır (%)",
"settings_battery_recovered_percent_hint": "Zayıf bir pil, seviyesi bu değerin üzerine çıkana veya bir değişim kaydedilene kadar zayıf sayılmaya devam eder — böylece eşik çevresinde salınan bir seviye filo görevini tekrar tekrar tamamlayamaz.",
"settings_battery_lifetimes": "Tipik pil ömürleri", "settings_battery_lifetimes": "Tipik pil ömürleri",
"settings_battery_lifetimes_hint": "Yalnızca yüzdesi olmayan piller için kullanılır: sadece tür ve değişim tarihi olan bir Battery Notes notu ya da yalnızca \"düşük\" bildiren bir sensör. Vade = son değişim + bu ömür. Seviye bildiren pillerin tahmini ölçülen deşarjdan gelir. Filo bir türden üç değişim gördüğünde ortanca aralık yerleşik değerin yerini alır — kendi değerin her zaman kazanır.", "settings_battery_lifetimes_hint": "Yalnızca yüzdesi olmayan piller için kullanılır: sadece tür ve değişim tarihi olan bir Battery Notes notu ya da yalnızca \"düşük\" bildiren bir sensör. Vade = son değişim + bu ömür. Seviye bildiren pillerin tahmini ölçülen deşarjdan gelir. Filo bir türden üç değişim gördüğünde ortanca aralık yerleşik değerin yerini alır — kendi değerin her zaman kazanır.",
"settings_battery_lifetime_months": "ay", "settings_battery_lifetime_months": "ay",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "filonda", "settings_battery_lifetime_in_fleet": "filonda",
"settings_battery_lifetime_learned_models": "Modele göre öğrenilen: {list}", "settings_battery_lifetime_learned_models": "Modele göre öğrenilen: {list}",
"settings_thresholds_hint": "Yeni Önerilen kurulumlar (kalan yüzde) ve kendi Battery Notes eşiği olmayan filo pilleri için varsayılanlar. Mevcut görevler değerlerini korur.", "settings_thresholds_hint": "Yeni Önerilen kurulumlar (kalan yüzde) ve kendi Battery Notes eşiği olmayan filo pilleri için varsayılanlar. Mevcut görevler değerlerini korur.",
"settings_part_search_url": "Alışveriş arama bağlantısı",
"settings_part_search_url_hint": "Arama terimleri yerine {q} içeren URL; ürün bağlantısı olmayan parçalar için kullanılır. Otomatik mağaza için boş bırakın (ülkeye, yoksa dile göre).",
"settings_value_out_of_range": "Değer {min} ile {max} arasında olmalıdır", "settings_value_out_of_range": "Değer {min} ile {max} arasında olmalıdır",
"bn_summary": "{name}: {n} pil için % {pct}", "bn_summary": "{name}: {n} pil için % {pct}",
"bn_floor_decides": "Senin % {floor} eşiğin hepsi için belirleyici; her pil için iki eşikten yüksek olanı geçerli.", "bn_floor_decides": "Senin % {floor} eşiğin hepsi için belirleyici; her pil için iki eşikten yüksek olanı geçerli.",
@@ -723,6 +731,8 @@
"archived": "Arşivlendi", "archived": "Arşivlendi",
"show_archived": "Arşivlenenleri göster", "show_archived": "Arşivlenenleri göster",
"hide_archived": "Arşivlenenleri gizle", "hide_archived": "Arşivlenenleri gizle",
"section_collapse": "Bölümü daralt",
"section_expand": "Bölümü genişlet",
"confirm_archive_object": "Bu nesne ve görevleri arşivlensin mi? Geçmişleri korunur ve daha sonra arşivden çıkarılabilirler.", "confirm_archive_object": "Bu nesne ve görevleri arşivlensin mi? Geçmişleri korunur ve daha sonra arşivden çıkarılabilirler.",
"settings_archive": "Arşiv ve Saklama", "settings_archive": "Arşiv ve Saklama",
"settings_archive_desc": "Tamamlanmış tek seferlik görevleri silmeden emekliye ayırın. Arşivlenen öğeler gizlenir ve pasiftir ancak geçmişlerini ve maliyetlerini korurlar.", "settings_archive_desc": "Tamamlanmış tek seferlik görevleri silmeden emekliye ayırın. Arşivlenen öğeler gizlenir ve pasiftir ancak geçmişlerini ve maliyetlerini korurlar.",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Неприпустима дата", "ws_err_invalid_date": "Неприпустима дата",
"ws_err_invalid_format": "Неприпустимий формат", "ws_err_invalid_format": "Неприпустимий формат",
"ws_err_invalid_url": "Неприпустиме посилання", "ws_err_invalid_url": "Неприпустиме посилання",
"ws_err_invalid_mirror_todo": "Неприпустимий список справ",
"ws_err_not_configured": "Ще не налаштовано", "ws_err_not_configured": "Ще не налаштовано",
"ws_err_not_loaded": "Ще не завантажено — спробуйте трохи пізніше", "ws_err_not_loaded": "Ще не завантажено — спробуйте трохи пізніше",
"ws_err_limit_reached": "Досягнуто межу", "ws_err_limit_reached": "Досягнуто межу",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "Не задано значення за замовчуванням для швидкого завершення", "ws_err_no_defaults": "Не задано значення за замовчуванням для швидкого завершення",
"ws_err_self_link_device": "Об'єкт не можна пов'язати із самим собою", "ws_err_self_link_device": "Об'єкт не можна пов'язати із самим собою",
"ws_err_too_early": "Зарано — це завдання можна завершити лише ближче до терміну", "ws_err_too_early": "Зарано — це завдання можна завершити лише ближче до терміну",
"ws_err_invalid_search_template": "Посилання для пошуку має бути URL http(s) із {q}",
"feat_schedule_time": "Планування за часом доби", "feat_schedule_time": "Планування за часом доби",
"feat_schedule_time_desc": "Задачі стають простроченими у певний час доби, а не опівночі.", "feat_schedule_time_desc": "Задачі стають простроченими у певний час доби, а не опівночі.",
"schedule_time_toggle": "Термін у визначений час", "schedule_time_toggle": "Термін у визначений час",
@@ -199,6 +201,8 @@
"labels": "Мітки", "labels": "Мітки",
"labels_placeholder": "напр. безпека, сезонне, видно-орендарю", "labels_placeholder": "напр. безпека, сезонне, видно-орендарю",
"labels_help": "Теги через кому для фільтрації та звітів.", "labels_help": "Теги через кому для фільтрації та звітів.",
"task_mirror_todo": "Відображати у списках справ",
"task_mirror_todo_hint": "Завдання з'являється в цих списках, поки воно актуальне; відмітка там завершує його тут.",
"priority_low": "Низький", "priority_low": "Низький",
"priority_normal": "Звичайний", "priority_normal": "Звичайний",
"priority_high": "Високий", "priority_high": "Високий",
@@ -496,6 +500,8 @@
"settings_default_warning": "Днів попередження за замовчуванням", "settings_default_warning": "Днів попередження за замовчуванням",
"settings_consumable_threshold": "Поріг «витратний матеріал закінчується» (%)", "settings_consumable_threshold": "Поріг «витратний матеріал закінчується» (%)",
"settings_battery_low_percent": "Поріг «батарея розряджена» (%)", "settings_battery_low_percent": "Поріг «батарея розряджена» (%)",
"settings_battery_recovered_percent": "Батарея вважається заміненою вище (%)",
"settings_battery_recovered_percent_hint": "Розряджена батарея вважається розрядженою, доки її рівень не підніметься вище цього значення або не буде записано заміну — рівень, що коливається біля порога, більше не завершує завдання парку знову й знову.",
"settings_battery_lifetimes": "Типовий строк служби батарей", "settings_battery_lifetimes": "Типовий строк служби батарей",
"settings_battery_lifetimes_hint": "Використовується лише для батарей без відсотка: нотатка Battery Notes лише з типом і датою заміни або датчик, що повідомляє тільки «низький». Термін = остання заміна + цей строк служби. Для батарей з рівнем прогноз будується за виміряним розрядом. Після трьох замін одного типу медіанний інтервал замінює вбудоване значення — ваше значення завжди головніше.", "settings_battery_lifetimes_hint": "Використовується лише для батарей без відсотка: нотатка Battery Notes лише з типом і датою заміни або датчик, що повідомляє тільки «низький». Термін = остання заміна + цей строк служби. Для батарей з рівнем прогноз будується за виміряним розрядом. Після трьох замін одного типу медіанний інтервал замінює вбудоване значення — ваше значення завжди головніше.",
"settings_battery_lifetime_months": "міс.", "settings_battery_lifetime_months": "міс.",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "у вашому парку", "settings_battery_lifetime_in_fleet": "у вашому парку",
"settings_battery_lifetime_learned_models": "Вивчено за моделями: {list}", "settings_battery_lifetime_learned_models": "Вивчено за моделями: {list}",
"settings_thresholds_hint": "Значення за замовчуванням для нових «Запропонованих налаштувань» (залишок у відсотках) і для батарей парку без власного порогу Battery Notes. Наявні завдання зберігають своє значення.", "settings_thresholds_hint": "Значення за замовчуванням для нових «Запропонованих налаштувань» (залишок у відсотках) і для батарей парку без власного порогу Battery Notes. Наявні завдання зберігають своє значення.",
"settings_part_search_url": "Посилання для пошуку покупки",
"settings_part_search_url_hint": "URL із {q} замість пошукового запиту, для деталей без посилання на товар. Залиште порожнім для автоматичного магазину (за країною, інакше за мовою).",
"settings_value_out_of_range": "Значення має бути від {min} до {max}", "settings_value_out_of_range": "Значення має бути від {min} до {max}",
"bn_summary": "{name}: {pct} % для {n} батарей", "bn_summary": "{name}: {pct} % для {n} батарей",
"bn_floor_decides": "Ваш поріг {floor} % діє для всіх; для кожної батареї враховується більший із двох порогів.", "bn_floor_decides": "Ваш поріг {floor} % діє для всіх; для кожної батареї враховується більший із двох порогів.",
@@ -717,6 +725,8 @@
"archived": "В архіві", "archived": "В архіві",
"show_archived": "Показати архів", "show_archived": "Показати архів",
"hide_archived": "Сховати архів", "hide_archived": "Сховати архів",
"section_collapse": "Згорнути розділ",
"section_expand": "Розгорнути розділ",
"confirm_archive_object": "Архівувати цей об'єкт та його завдання? Історія збережеться, згодом можна відновити.", "confirm_archive_object": "Архівувати цей об'єкт та його завдання? Історія збережеться, згодом можна відновити.",
"settings_archive": "Архів і зберігання", "settings_archive": "Архів і зберігання",
"settings_archive_desc": "Відкладайте виконані одноразові завдання в архів, не видаляючи їх. Архівні елементи приховані й неактивні, але зберігають історію та витрати.", "settings_archive_desc": "Відкладайте виконані одноразові завдання в архів, не видаляючи їх. Архівні елементи приховані й неактивні, але зберігають історію та витрати.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "日期无效", "ws_err_invalid_date": "日期无效",
"ws_err_invalid_format": "格式无效", "ws_err_invalid_format": "格式无效",
"ws_err_invalid_url": "链接无效", "ws_err_invalid_url": "链接无效",
"ws_err_invalid_mirror_todo": "无效的待办清单",
"ws_err_not_configured": "尚未设置", "ws_err_not_configured": "尚未设置",
"ws_err_not_loaded": "尚未加载 — 请稍后重试", "ws_err_not_loaded": "尚未加载 — 请稍后重试",
"ws_err_limit_reached": "已达上限", "ws_err_limit_reached": "已达上限",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "未设置快速完成默认值", "ws_err_no_defaults": "未设置快速完成默认值",
"ws_err_self_link_device": "对象不能链接到自身", "ws_err_self_link_device": "对象不能链接到自身",
"ws_err_too_early": "为时过早 — 此任务只能在临近到期日时完成", "ws_err_too_early": "为时过早 — 此任务只能在临近到期日时完成",
"ws_err_invalid_search_template": "搜索链接必须是包含 {q} 的 http(s) 网址",
"feat_schedule_time": "具体时间调度", "feat_schedule_time": "具体时间调度",
"feat_schedule_time_desc": "任务将在特定时间点变为逾期,而非默认的午夜。", "feat_schedule_time_desc": "任务将在特定时间点变为逾期,而非默认的午夜。",
"schedule_time_toggle": "在特定时间到期", "schedule_time_toggle": "在特定时间到期",
@@ -201,6 +203,8 @@
"labels": "标签", "labels": "标签",
"labels_placeholder": "例如:安全、季节性、租户可见", "labels_placeholder": "例如:安全、季节性、租户可见",
"labels_help": "用于筛选和报表的逗号分隔标签。", "labels_help": "用于筛选和报表的逗号分隔标签。",
"task_mirror_todo": "镜像到待办清单",
"task_mirror_todo_hint": "任务到期期间会出现在这些清单中;在那里勾选即在此处完成。",
"priority_low": "低", "priority_low": "低",
"priority_normal": "普通", "priority_normal": "普通",
"priority_high": "高", "priority_high": "高",
@@ -498,6 +502,8 @@
"settings_default_warning": "默认预警天数", "settings_default_warning": "默认预警天数",
"settings_consumable_threshold": "耗材“不足”阈值(%)", "settings_consumable_threshold": "耗材“不足”阈值(%)",
"settings_battery_low_percent": "电池“电量低”阈值(%)", "settings_battery_low_percent": "电池“电量低”阈值(%)",
"settings_battery_recovered_percent": "电量高于此值视为已更换(%)",
"settings_battery_recovered_percent_hint": "电量低的电池会一直计为低电量,直到电量高于此值或记录了更换——这样在阈值附近波动的电量不会反复完成电池组任务。",
"settings_battery_lifetimes": "电池典型寿命", "settings_battery_lifetimes": "电池典型寿命",
"settings_battery_lifetimes_hint": "仅用于没有百分比的电池:只有类型和更换日期的 Battery Notes 记录,或只报告“低电量”的传感器。其到期日 = 上次更换 + 此寿命。报告电量的电池改用实测放电来预测。同一类型出现三次更换后,中位间隔将取代内置值——你自己的值始终优先。", "settings_battery_lifetimes_hint": "仅用于没有百分比的电池:只有类型和更换日期的 Battery Notes 记录,或只报告“低电量”的传感器。其到期日 = 上次更换 + 此寿命。报告电量的电池改用实测放电来预测。同一类型出现三次更换后,中位间隔将取代内置值——你自己的值始终优先。",
"settings_battery_lifetime_months": "个月", "settings_battery_lifetime_months": "个月",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "在你的电池群中", "settings_battery_lifetime_in_fleet": "在你的电池群中",
"settings_battery_lifetime_learned_models": "按型号学习:{list}", "settings_battery_lifetime_learned_models": "按型号学习:{list}",
"settings_thresholds_hint": "用于新的“建议设置”(剩余百分比)以及没有自身 Battery Notes 阈值的电池组电池。现有任务保留其值。", "settings_thresholds_hint": "用于新的“建议设置”(剩余百分比)以及没有自身 Battery Notes 阈值的电池组电池。现有任务保留其值。",
"settings_part_search_url": "购物搜索链接",
"settings_part_search_url_hint": "以 {q} 代替搜索词的网址,用于没有产品链接的配件。留空则自动选择商店(先按国家,再按语言)。",
"settings_value_out_of_range": "数值必须介于 {min} 和 {max} 之间", "settings_value_out_of_range": "数值必须介于 {min} 和 {max} 之间",
"bn_summary": "{name}:{n} 块电池为 {pct}%", "bn_summary": "{name}:{n} 块电池为 {pct}%",
"bn_floor_decides": "你的 {floor}% 阈值对所有电池生效;每块电池取两个阈值中较高者。", "bn_floor_decides": "你的 {floor}% 阈值对所有电池生效;每块电池取两个阈值中较高者。",
@@ -717,6 +725,8 @@
"archived": "已归档", "archived": "已归档",
"show_archived": "显示已归档", "show_archived": "显示已归档",
"hide_archived": "隐藏已归档", "hide_archived": "隐藏已归档",
"section_collapse": "折叠此部分",
"section_expand": "展开此部分",
"confirm_archive_object": "归档此对象及其任务?历史记录将保留,以后可恢复。", "confirm_archive_object": "归档此对象及其任务?历史记录将保留,以后可恢复。",
"settings_archive": "归档与保留", "settings_archive": "归档与保留",
"settings_archive_desc": "将已完成的一次性任务归档而不删除。已归档项目会被隐藏且不再活动,但保留其历史记录和费用。", "settings_archive_desc": "将已完成的一次性任务归档而不删除。已归档项目会被隐藏且不再活动,但保留其历史记录和费用。",
@@ -163,6 +163,10 @@ const GROUP_BY_MODES: readonly GroupByMode[] = ["none", "area", "group", "user",
// (OVERVIEW_TABS: imported from helpers/overview-tabs.ts.) // (OVERVIEW_TABS: imported from helpers/overview-tabs.ts.)
/** The dashboard list's status filter options (the <select> in the toolbar). */ /** The dashboard list's status filter options (the <select> in the toolbar). */
const STATUS_FILTERS: readonly string[] = ["overdue", "due_soon", "triggered", "ok"]; const STATUS_FILTERS: readonly string[] = ["overdue", "due_soon", "triggered", "ok"];
/** #179: the object page's collapsible sections — the ids saved under
* LS_KEYS.objectSections and accepted by the `?section=` deep link. */
type ObjectSection = "tasks" | "documents" | "parts" | "history";
const OBJECT_SECTIONS: readonly ObjectSection[] = ["tasks", "documents", "parts", "history"];
// Chart dimension constants for mini sparklines (overview) // Chart dimension constants for mini sparklines (overview)
@@ -330,6 +334,18 @@ export class MaintenanceSupporterPanel extends LitElement {
try { return new Set(JSON.parse(lsGet(LS_KEYS.collapsedSections) || "[]")); } try { return new Set(JSON.parse(lsGet(LS_KEYS.collapsedSections) || "[]")); }
catch { return new Set(); } catch { return new Set(); }
})(); })();
// #179: object-page sections the user folded away — one setting for every
// object. A collapsed section's component is not rendered at all (no
// thumbnails load, nothing to scroll past). `_objectSectionOverride` opens
// one section for the current visit only (a search hit, a `?section=`
// link) and leaves the saved set alone.
@state() private _objectSectionsCollapsed: Set<ObjectSection> = (() => {
try {
const raw: unknown = JSON.parse(lsGet(LS_KEYS.objectSections) || "[]");
return new Set((Array.isArray(raw) ? raw : []).filter((s): s is ObjectSection => (OBJECT_SECTIONS as readonly unknown[]).includes(s)));
} catch { return new Set<ObjectSection>(); }
})();
@state() private _objectSectionOverride: ObjectSection | null = null;
// v2.15.0: command palette ("/" since 2.18.1 — Ctrl+K clashed with HA's own // v2.15.0: command palette ("/" since 2.18.1 — Ctrl+K clashed with HA's own
// global search); 2.78 (#171): the panel's global search — a magnifier in // global search); 2.78 (#171): the panel's global search — a magnifier in
// the header opens it too, results are grouped (objects / tasks / parts // the header opens it too, results are grouped (objects / tasks / parts
@@ -945,6 +961,12 @@ export class MaintenanceSupporterPanel extends LitElement {
const taskId = params.get("task_id"); const taskId = params.get("task_id");
const action = params.get("action"); const action = params.get("action");
// #179: `?entry_id=…&section=tasks|documents|parts|history` opens the
// object with that section unfolded (this visit only — the saved
// collapsed set is not rewritten) and scrolled into view. Unknown
// values are ignored, like every other param.
const sectionParam = params.get("section");
const section = (OBJECT_SECTIONS as readonly string[]).includes(sectionParam ?? "") ? sectionParam as ObjectSection : null;
// Always clean URL params — they are consumed once // Always clean URL params — they are consumed once
const cleanUrl = window.location.pathname + window.location.hash; const cleanUrl = window.location.pathname + window.location.hash;
@@ -961,7 +983,7 @@ export class MaintenanceSupporterPanel extends LitElement {
if (taskId) { if (taskId) {
const task = obj.tasks.find((t) => t.id === taskId); const task = obj.tasks.find((t) => t.id === taskId);
if (!task) { if (!task) {
this._showObject(entryId); this._showObject(entryId, section);
return; return;
} }
this._showTask(entryId, taskId); this._showTask(entryId, taskId);
@@ -977,7 +999,7 @@ export class MaintenanceSupporterPanel extends LitElement {
}); });
} }
} else { } else {
this._showObject(entryId); this._showObject(entryId, section);
} }
} }
@@ -1263,6 +1285,7 @@ export class MaintenanceSupporterPanel extends LitElement {
this._selectedEntryId = s.msp_entry || null; this._selectedEntryId = s.msp_entry || null;
this._selectedTaskId = s.msp_task || null; this._selectedTaskId = s.msp_task || null;
this._moreMenuOpen = false; this._moreMenuOpen = false;
this._objectSectionOverride = null;
if (s.msp_view === "all_parts") void this._loadAllParts(); if (s.msp_view === "all_parts") void this._loadAllParts();
if (s.msp_view === "task" && s.msp_entry && s.msp_task) { if (s.msp_view === "task" && s.msp_entry && s.msp_task) {
this._historyFilter = null; this._historyFilter = null;
@@ -1414,12 +1437,35 @@ export class MaintenanceSupporterPanel extends LitElement {
}); });
} }
private _showObject(entryId: string): void { /** #179: `section` opens one collapsed section for this visit (a search
* hit, a `?section=` link) and scrolls to it; the saved set is untouched. */
private _showObject(entryId: string, section: ObjectSection | null = null): void {
this._pushPanelState("object", entryId); this._pushPanelState("object", entryId);
this._view = "object"; this._view = "object";
this._selectedEntryId = entryId; this._selectedEntryId = entryId;
this._selectedTaskId = null; this._selectedTaskId = null;
this._scrollContentToTop(); this._objectSectionOverride = section;
if (section) this._scrollToObjectSection(section);
else this._scrollContentToTop();
}
private _scrollToObjectSection(section: ObjectSection): void {
void this.updateComplete.then(() => requestAnimationFrame(() => {
const target = this.shadowRoot?.querySelector(`.obj-section[data-section="${section}"]`);
if (target) target.scrollIntoView({ block: "start", behavior: "smooth" });
else this._scrollContentToTop();
}));
}
/** #179: fold / unfold an object-page section; the choice is saved for
* every object. A manual toggle ends the visit-only override. */
private _toggleObjectSection(section: ObjectSection): void {
const next = new Set(this._objectSectionsCollapsed);
const open = this._objectSectionOverride === section || !next.has(section);
if (open) next.add(section); else next.delete(section);
if (this._objectSectionOverride === section) this._objectSectionOverride = null;
this._objectSectionsCollapsed = next;
lsSet(LS_KEYS.objectSections, JSON.stringify([...next]));
} }
/** Master-detail split is active: wide panel, dashboard tab, no bulk. */ /** Master-detail split is active: wide panel, dashboard tab, no bulk. */
@@ -1733,6 +1779,13 @@ export class MaintenanceSupporterPanel extends LitElement {
// honour #page=N; the Companion app's external viewer may not). // honour #page=N; the Companion app's external viewer may not).
void openSignedDocument(this.hass, r.docId, r.page ? `#page=${r.page}` : "").catch(() => { /* helper closed its tab */ }); void openSignedDocument(this.hass, r.docId, r.page ? `#page=${r.page}` : "").catch(() => { /* helper closed its tab */ });
} }
// #179: the file opens in its own tab; the panel lands on the object's
// documents — unfolded for this visit even when the user keeps that
// section collapsed — so the hit has its context when the tab returns.
this._showObject(r.entryId, "documents");
return;
case "part":
this._showObject(r.entryId, "parts");
return; return;
default: default:
this._showObject(r.entryId); this._showObject(r.entryId);
@@ -4083,6 +4136,7 @@ export class MaintenanceSupporterPanel extends LitElement {
</div>` </div>`
: nothing} : nothing}
${this._renderObjectSection("tasks", t("tasks", L), visibleTasks.length, () => html`
<h3>${t("tasks", L)} (${visibleTasks.length})${archivedInObj > 0 ? html` <h3>${t("tasks", L)} (${visibleTasks.length})${archivedInObj > 0 ? html`
<ha-button <ha-button
class="archived-toggle ${this._showArchived ? "active" : ""}" class="archived-toggle ${this._showArchived ? "active" : ""}"
@@ -4131,13 +4185,17 @@ export class MaintenanceSupporterPanel extends LitElement {
)} )}
</div> </div>
`)}</div>`} `)}</div>`}
`)}
${this._renderObjectSection("documents", t("documents", L), typeof o.document_count === "number" ? o.document_count : null, () => html`
<maintenance-documents-section <maintenance-documents-section
.hass=${this.hass} .hass=${this.hass}
.entryId=${obj.entry_id} .entryId=${obj.entry_id}
.canWrite=${!isOperator} .canWrite=${!isOperator}
></maintenance-documents-section> ></maintenance-documents-section>
`)}
${(obj.parts || []).length || !isOperator ? this._renderObjectSection("parts", t("parts_section", L), (obj.parts || []).length, () => html`
<maintenance-parts-section <maintenance-parts-section
.hass=${this.hass} .hass=${this.hass}
.entryId=${obj.entry_id} .entryId=${obj.entry_id}
@@ -4146,7 +4204,9 @@ export class MaintenanceSupporterPanel extends LitElement {
.currencySymbol=${this._currencySymbol} .currencySymbol=${this._currencySymbol}
@parts-changed=${() => this._loadData()} @parts-changed=${() => this._loadData()}
></maintenance-parts-section> ></maintenance-parts-section>
`) : nothing}
${obj.tasks.some((tk) => (tk.times_performed || 0) > 0 || (tk.history || []).length > 0) ? this._renderObjectSection("history", t("object_history_section", L), null, () => html`
<maintenance-object-history-section <maintenance-object-history-section
.hass=${this.hass} .hass=${this.hass}
.entryId=${obj.entry_id} .entryId=${obj.entry_id}
@@ -4156,6 +4216,37 @@ export class MaintenanceSupporterPanel extends LitElement {
.userName=${(id: string) => this._userService?.getUserName(id) ?? null} .userName=${(id: string) => this._userService?.getUserName(id) ?? null}
@open-task=${(e: CustomEvent<{ taskId: string }>) => this._showTask(obj.entry_id, e.detail.taskId)} @open-task=${(e: CustomEvent<{ taskId: string }>) => this._showTask(obj.entry_id, e.detail.taskId)}
></maintenance-object-history-section> ></maintenance-object-history-section>
`) : nothing}
</div>
`;
}
/** #179: one foldable block of the object page. Open = the section renders
* itself (its own heading, buttons, list) with the chevron in the gutter
* beside its heading; collapsed = only a heading row (title, count,
* chevron) — the section's component is not in the DOM at all, so no
* thumbnails load and there is nothing to scroll past. A visit-only
* override (search hit, `?section=` link) opens a collapsed section
* without rewriting the saved set. Callers skip the block where the
* section itself would render nothing (parts for an operator without
* parts, history without a single entry) — a chevron beside nothing. */
private _renderObjectSection(section: ObjectSection, title: string, count: number | null, body: () => unknown) {
const L = this._lang;
const open = this._objectSectionOverride === section || !this._objectSectionsCollapsed.has(section);
const label = open ? t("section_collapse", L) : t("section_expand", L);
return html`
<div class="obj-section ${section} ${open ? "open" : "collapsed"}" data-section=${section}>
<button class="obj-section-toggle" type="button"
aria-expanded=${open ? "true" : "false"}
aria-label=${label} title=${label}
@click=${() => this._toggleObjectSection(section)}>
<ha-icon icon=${open ? "mdi:chevron-up" : "mdi:chevron-down"}></ha-icon>
</button>
${open
? html`<div class="obj-section-body">${body()}</div>`
: html`<h3 class="obj-section-title" @click=${() => this._toggleObjectSection(section)}>
${title}${count !== null ? html`<span class="obj-section-count">${count}</span>` : nothing}
</h3>`}
</div> </div>
`; `;
} }
@@ -604,6 +604,32 @@ export const panelStyles = css`
} }
.detail-header h2 { margin: 0; font-size: 22px; } .detail-header h2 { margin: 0; font-size: 22px; }
h3 { margin: 16px 0 8px; font-size: 16px; font-weight: 500; } h3 { margin: 16px 0 8px; font-size: 16px; font-weight: 500; }
/* #179: object-page sections fold away. A chevron gutter beside each
section; open sections keep their own heading line (the child
component's h3 — buttons and all), the chevron is aligned to it per
section because their top margins differ. Collapsed = heading row only. */
.obj-section { display: grid; grid-template-columns: 28px minmax(0, 1fr); align-items: start; }
.obj-section-toggle {
grid-column: 1; width: 28px; height: 28px; padding: 0; margin: 12px 0 0;
display: inline-flex; align-items: center; justify-content: center;
border: none; border-radius: 50%; background: none; font: inherit;
color: var(--secondary-text-color); cursor: pointer;
}
.obj-section-toggle:hover { background: var(--secondary-background-color); color: var(--primary-text-color); }
.obj-section-toggle:focus-visible { outline: 2px solid var(--primary-color); outline-offset: 1px; }
.obj-section-toggle ha-icon { --mdc-icon-size: 22px; }
.obj-section-body, .obj-section-title { grid-column: 2; min-width: 0; }
.obj-section-title { display: flex; align-items: center; gap: 8px; cursor: pointer; user-select: none; }
.obj-section-count {
font-size: 12px; font-weight: 400; color: var(--secondary-text-color);
background: var(--secondary-background-color); padding: 2px 8px; border-radius: 999px;
}
.obj-section.parts.open > .obj-section-toggle { margin-top: 17px; }
.obj-section.history.open > .obj-section-toggle { margin-top: 32px; }
@media (max-width: 768px) {
.obj-section { grid-template-columns: 24px minmax(0, 1fr); }
.obj-section-toggle { width: 24px; }
}
.meta { color: var(--secondary-text-color); margin: 4px 0; } .meta { color: var(--secondary-text-color); margin: 4px 0; }
/* v1.4.10 (#46): per-object free-form notes block */ /* v1.4.10 (#46): per-object free-form notes block */
.object-notes { .object-notes {
@@ -138,6 +138,10 @@ function renderTaskHeader(task: MaintenanceTask, ctx: TaskDetailContext) {
${task.notify_enabled === false ${task.notify_enabled === false
? html`<span class="nfc-badge muted-badge" title="${t("no_notifications", L)}"><ha-icon icon="mdi:bell-off-outline"></ha-icon></span>` ? html`<span class="nfc-badge muted-badge" title="${t("no_notifications", L)}"><ha-icon icon="mdi:bell-off-outline"></ha-icon></span>`
: nothing} : nothing}
${task.mirror_todo_entities?.length
? html`<span class="nfc-badge mirror-badge" title="${t("task_mirror_todo", L)}: ${task.mirror_todo_entities
.map((eid) => String(ctx.hass?.states?.[eid]?.attributes?.friendly_name ?? eid)).join(", ")}"><ha-icon icon="mdi:clipboard-list-outline"></ha-icon></span>`
: nothing}
${task.nfc_tag_id ${task.nfc_tag_id
? html`<span class="nfc-badge" title="${t("nfc_tag_id", L)}: ${task.nfc_tag_id}"><ha-icon icon="mdi:nfc-variant"></ha-icon> NFC</span>` ? html`<span class="nfc-badge" title="${t("nfc_tag_id", L)}: ${task.nfc_tag_id}"><ha-icon icon="mdi:nfc-variant"></ha-icon> NFC</span>`
: !isOperator ? html`<span class="nfc-badge unlinked" title="${t("nfc_link_hint", L)}" : !isOperator ? html`<span class="nfc-badge unlinked" title="${t("nfc_link_hint", L)}"
@@ -246,6 +246,8 @@ export interface MaintenanceTask {
* complete/skip. */ * complete/skip. */
checklist_progress?: Record<string, boolean>; checklist_progress?: Record<string, boolean>;
labels?: string[]; labels?: string[];
/** D#183: external todo.* lists the task is mirrored into while it is due. */
mirror_todo_entities?: string[];
assignee_pool?: string[]; assignee_pool?: string[];
rotation_strategy?: string | null; rotation_strategy?: string | null;
/** Details this task demands on completion (v2.44): notes/cost/duration/photo/user. */ /** Details this task demands on completion (v2.44): notes/cost/duration/photo/user. */
@@ -33,8 +33,10 @@ export const WS_ERROR_CODE_KEYS: Record<string, string> = {
invalid_entity_slug: "ws_err_invalid_entity_slug", invalid_entity_slug: "ws_err_invalid_entity_slug",
invalid_format: "ws_err_invalid_format", invalid_format: "ws_err_invalid_format",
invalid_input: "ws_err_invalid_input", invalid_input: "ws_err_invalid_input",
invalid_mirror_todo: "ws_err_invalid_mirror_todo",
invalid_parent: "ws_err_invalid_parent", invalid_parent: "ws_err_invalid_parent",
invalid_range: "ws_err_invalid_range", invalid_range: "ws_err_invalid_range",
invalid_search_template: "ws_err_invalid_search_template",
invalid_target: "ws_err_invalid_target", invalid_target: "ws_err_invalid_target",
invalid_trigger_config: "ws_err_invalid_trigger_config", invalid_trigger_config: "ws_err_invalid_trigger_config",
invalid_url: "ws_err_invalid_url", invalid_url: "ws_err_invalid_url",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Neplatné datum", "ws_err_invalid_date": "Neplatné datum",
"ws_err_invalid_format": "Neplatný formát", "ws_err_invalid_format": "Neplatný formát",
"ws_err_invalid_url": "Neplatný odkaz", "ws_err_invalid_url": "Neplatný odkaz",
"ws_err_invalid_mirror_todo": "Neplatný seznam úkolů",
"ws_err_not_configured": "Zatím nenastaveno", "ws_err_not_configured": "Zatím nenastaveno",
"ws_err_not_loaded": "Zatím nenačteno — zkuste to za chvíli znovu", "ws_err_not_loaded": "Zatím nenačteno — zkuste to za chvíli znovu",
"ws_err_limit_reached": "Dosažen limit", "ws_err_limit_reached": "Dosažen limit",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "Nejsou nastaveny výchozí hodnoty pro rychlé dokončení", "ws_err_no_defaults": "Nejsou nastaveny výchozí hodnoty pro rychlé dokončení",
"ws_err_self_link_device": "Objekt nelze propojit sám se sebou", "ws_err_self_link_device": "Objekt nelze propojit sám se sebou",
"ws_err_too_early": "Příliš brzy — tento úkol lze dokončit až blíže k termínu", "ws_err_too_early": "Příliš brzy — tento úkol lze dokončit až blíže k termínu",
"ws_err_invalid_search_template": "Odkaz pro vyhledávání musí být URL http(s) obsahující {q}",
"feat_schedule_time": "Plánování podle denní doby", "feat_schedule_time": "Plánování podle denní doby",
"feat_schedule_time_desc": "Úkoly se stanou po termínu v určenou denní dobu místo o půlnoci.", "feat_schedule_time_desc": "Úkoly se stanou po termínu v určenou denní dobu místo o půlnoci.",
"schedule_time_toggle": "Termín v určitou hodinu", "schedule_time_toggle": "Termín v určitou hodinu",
@@ -199,6 +201,8 @@
"labels": "Štítky", "labels": "Štítky",
"labels_placeholder": "např. bezpečnost, sezónní, viditelné-nájemci", "labels_placeholder": "např. bezpečnost, sezónní, viditelné-nájemci",
"labels_help": "Štítky oddělené čárkami pro filtrování a přehledy.", "labels_help": "Štítky oddělené čárkami pro filtrování a přehledy.",
"task_mirror_todo": "Zrcadlit do seznamů úkolů",
"task_mirror_todo_hint": "Úkol se objeví v těchto seznamech, dokud je aktuální; odškrtnutí tam ho dokončí zde.",
"priority_low": "Nízká", "priority_low": "Nízká",
"priority_normal": "Normální", "priority_normal": "Normální",
"priority_high": "Vysoká", "priority_high": "Vysoká",
@@ -496,6 +500,8 @@
"settings_default_warning": "Výchozí dny upozornění", "settings_default_warning": "Výchozí dny upozornění",
"settings_consumable_threshold": "Práh „spotřební materiál nízký“ (%)", "settings_consumable_threshold": "Práh „spotřební materiál nízký“ (%)",
"settings_battery_low_percent": "Práh „baterie slabá“ (%)", "settings_battery_low_percent": "Práh „baterie slabá“ (%)",
"settings_battery_recovered_percent": "Baterie se považuje za vyměněnou nad (%)",
"settings_battery_recovered_percent_hint": "Slabá baterie se počítá jako slabá, dokud její stav nevystoupí nad tuto hodnotu nebo není zaznamenána výměna — stav kolísající kolem prahu tak nedokončuje úlohu flotily stále dokola.",
"settings_battery_lifetimes": "Typická životnost baterií", "settings_battery_lifetimes": "Typická životnost baterií",
"settings_battery_lifetimes_hint": "Použije se jen u baterií bez procent: poznámka Battery Notes jen s typem a datem výměny nebo senzor hlásící pouze „slabá“. Splatnost = poslední výměna + tato životnost. Baterie hlásící úroveň mají prognózu z naměřeného vybíjení. Po třech výměnách daného typu nahradí medián intervalů vestavěnou hodnotu — vaše hodnota má vždy přednost.", "settings_battery_lifetimes_hint": "Použije se jen u baterií bez procent: poznámka Battery Notes jen s typem a datem výměny nebo senzor hlásící pouze „slabá“. Splatnost = poslední výměna + tato životnost. Baterie hlásící úroveň mají prognózu z naměřeného vybíjení. Po třech výměnách daného typu nahradí medián intervalů vestavěnou hodnotu — vaše hodnota má vždy přednost.",
"settings_battery_lifetime_months": "měsíců", "settings_battery_lifetime_months": "měsíců",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "ve vaší flotile", "settings_battery_lifetime_in_fleet": "ve vaší flotile",
"settings_battery_lifetime_learned_models": "Naučeno podle modelu: {list}", "settings_battery_lifetime_learned_models": "Naučeno podle modelu: {list}",
"settings_thresholds_hint": "Výchozí hodnoty pro nová Navrhovaná nastavení (zbývající procenta) a pro baterie flotily bez vlastního prahu Battery Notes. Stávající úkoly si ponechají svou hodnotu.", "settings_thresholds_hint": "Výchozí hodnoty pro nová Navrhovaná nastavení (zbývající procenta) a pro baterie flotily bez vlastního prahu Battery Notes. Stávající úkoly si ponechají svou hodnotu.",
"settings_part_search_url": "Odkaz pro vyhledávání nákupu",
"settings_part_search_url_hint": "URL s {q} místo hledaných výrazů, pro díly bez odkazu na produkt. Ponechte prázdné pro automatický obchod (podle země, jinak podle jazyka).",
"settings_value_out_of_range": "Hodnota musí být mezi {min} a {max}", "settings_value_out_of_range": "Hodnota musí být mezi {min} a {max}",
"bn_summary": "{name}: {pct} % pro {n} baterií", "bn_summary": "{name}: {pct} % pro {n} baterií",
"bn_floor_decides": "Tvůj práh {floor} % rozhoduje pro všechny; u každé baterie platí vyšší z obou prahů.", "bn_floor_decides": "Tvůj práh {floor} % rozhoduje pro všechny; u každé baterie platí vyšší z obou prahů.",
@@ -717,6 +725,8 @@
"archived": "Archivováno", "archived": "Archivováno",
"show_archived": "Zobrazit archivované", "show_archived": "Zobrazit archivované",
"hide_archived": "Skrýt archivované", "hide_archived": "Skrýt archivované",
"section_collapse": "Sbalit sekci",
"section_expand": "Rozbalit sekci",
"confirm_archive_object": "Archivovat tento objekt a jeho úkoly? Historie zůstane zachována a lze ji později obnovit.", "confirm_archive_object": "Archivovat tento objekt a jeho úkoly? Historie zůstane zachována a lze ji později obnovit.",
"settings_archive": "Archiv a uchovávání", "settings_archive": "Archiv a uchovávání",
"settings_archive_desc": "Odkládejte dokončené jednorázové úkoly bez mazání. Archivované položky jsou skryté a neaktivní, ale zachovávají historii a náklady.", "settings_archive_desc": "Odkládejte dokončené jednorázové úkoly bez mazání. Archivované položky jsou skryté a neaktivní, ale zachovávají historii a náklady.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "Ugyldig dato", "ws_err_invalid_date": "Ugyldig dato",
"ws_err_invalid_format": "Ugyldigt format", "ws_err_invalid_format": "Ugyldigt format",
"ws_err_invalid_url": "Ugyldigt link", "ws_err_invalid_url": "Ugyldigt link",
"ws_err_invalid_mirror_todo": "Ugyldig to-do-liste",
"ws_err_not_configured": "Ikke sat op endnu", "ws_err_not_configured": "Ikke sat op endnu",
"ws_err_not_loaded": "Ikke indlæst endnu — prøv igen om lidt", "ws_err_not_loaded": "Ikke indlæst endnu — prøv igen om lidt",
"ws_err_limit_reached": "Grænsen er nået", "ws_err_limit_reached": "Grænsen er nået",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "Ingen standardværdier for hurtig fuldførelse", "ws_err_no_defaults": "Ingen standardværdier for hurtig fuldførelse",
"ws_err_self_link_device": "Et objekt kan ikke knyttes til sig selv", "ws_err_self_link_device": "Et objekt kan ikke knyttes til sig selv",
"ws_err_too_early": "For tidligt — opgaven kan først fuldføres tættere på forfaldsdatoen", "ws_err_too_early": "For tidligt — opgaven kan først fuldføres tættere på forfaldsdatoen",
"ws_err_invalid_search_template": "Søgelinket skal være en http(s)-URL, der indeholder {q}",
"feat_schedule_time": "Planlægning efter tidspunkt på dagen", "feat_schedule_time": "Planlægning efter tidspunkt på dagen",
"feat_schedule_time_desc": "Opgaver bliver forfaldne på et bestemt tidspunkt på dagen i stedet for midnat.", "feat_schedule_time_desc": "Opgaver bliver forfaldne på et bestemt tidspunkt på dagen i stedet for midnat.",
"schedule_time_toggle": "Forfalder på et bestemt tidspunkt", "schedule_time_toggle": "Forfalder på et bestemt tidspunkt",
@@ -201,6 +203,8 @@
"labels": "Etiketter", "labels": "Etiketter",
"labels_placeholder": "f.eks. sikkerhed, sæson, synlig-for-lejer", "labels_placeholder": "f.eks. sikkerhed, sæson, synlig-for-lejer",
"labels_help": "Kommaseparerede tags til filtrering og rapporter.", "labels_help": "Kommaseparerede tags til filtrering og rapporter.",
"task_mirror_todo": "Spejl til to-do-lister",
"task_mirror_todo_hint": "Opgaven vises på disse lister, mens den er aktuel; afkrydses den der, fuldføres den her.",
"priority_low": "Lav", "priority_low": "Lav",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Høj", "priority_high": "Høj",
@@ -498,6 +502,8 @@
"settings_default_warning": "Standard advarselsdage", "settings_default_warning": "Standard advarselsdage",
"settings_consumable_threshold": "Tærskel „forbrugsvare lav“ (%)", "settings_consumable_threshold": "Tærskel „forbrugsvare lav“ (%)",
"settings_battery_low_percent": "Tærskel „batteri lavt“ (%)", "settings_battery_low_percent": "Tærskel „batteri lavt“ (%)",
"settings_battery_recovered_percent": "Batteri regnes som udskiftet over (%)",
"settings_battery_recovered_percent_hint": "Et lavt batteri tælles som lavt, indtil niveauet stiger over denne værdi, eller et skift registreres — så kan et niveau, der svinger omkring tærsklen, ikke fuldføre flådeopgaven igen og igen.",
"settings_battery_lifetimes": "Typiske batterilevetider", "settings_battery_lifetimes": "Typiske batterilevetider",
"settings_battery_lifetimes_hint": "Bruges kun til batterier uden procent: en Battery Notes-note med kun type og udskiftningsdato, eller en sensor der kun melder \"lavt\". Forfaldsdato = seneste udskiftning + denne levetid. Batterier der melder niveau får prognosen fra den målte afladning. Når flåden har set tre udskiftninger af en type, overtager medianintervallet fra den indbyggede værdi — din egen værdi vinder altid.", "settings_battery_lifetimes_hint": "Bruges kun til batterier uden procent: en Battery Notes-note med kun type og udskiftningsdato, eller en sensor der kun melder \"lavt\". Forfaldsdato = seneste udskiftning + denne levetid. Batterier der melder niveau får prognosen fra den målte afladning. Når flåden har set tre udskiftninger af en type, overtager medianintervallet fra den indbyggede værdi — din egen værdi vinder altid.",
"settings_battery_lifetime_months": "måneder", "settings_battery_lifetime_months": "måneder",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "i din flåde", "settings_battery_lifetime_in_fleet": "i din flåde",
"settings_battery_lifetime_learned_models": "Lært pr. model: {list}", "settings_battery_lifetime_learned_models": "Lært pr. model: {list}",
"settings_thresholds_hint": "Standardværdier for nye Foreslåede opsætninger (resterende procent) og for flådebatterier uden egen Battery Notes-tærskel. Eksisterende opgaver beholder deres værdi.", "settings_thresholds_hint": "Standardværdier for nye Foreslåede opsætninger (resterende procent) og for flådebatterier uden egen Battery Notes-tærskel. Eksisterende opgaver beholder deres værdi.",
"settings_part_search_url": "Søgelink til indkøb",
"settings_part_search_url_hint": "URL med {q} i stedet for søgeordene, til dele uden produktlink. Lad stå tomt for den automatiske butik (efter land, ellers sprog).",
"settings_value_out_of_range": "Værdien skal være mellem {min} og {max}", "settings_value_out_of_range": "Værdien skal være mellem {min} og {max}",
"bn_summary": "{name}: {pct} % for {n} batterier", "bn_summary": "{name}: {pct} % for {n} batterier",
"bn_floor_decides": "Din tærskel på {floor} % afgør for alle; pr. batteri gælder den højeste af de to tærskler.", "bn_floor_decides": "Din tærskel på {floor} % afgør for alle; pr. batteri gælder den højeste af de to tærskler.",
@@ -717,6 +725,8 @@
"archived": "Arkiveret", "archived": "Arkiveret",
"show_archived": "Vis arkiverede", "show_archived": "Vis arkiverede",
"hide_archived": "Skjul arkiverede", "hide_archived": "Skjul arkiverede",
"section_collapse": "Fold sektionen sammen",
"section_expand": "Fold sektionen ud",
"confirm_archive_object": "Arkivér dette objekt og dets opgaver? Historikken bevares og kan gendannes senere.", "confirm_archive_object": "Arkivér dette objekt og dets opgaver? Historikken bevares og kan gendannes senere.",
"settings_archive": "Arkiv og opbevaring", "settings_archive": "Arkiv og opbevaring",
"settings_archive_desc": "Læg færdige engangsopgaver væk uden at slette dem. Arkiverede elementer er skjult og inaktive, men bevarer historik og omkostninger.", "settings_archive_desc": "Læg færdige engangsopgaver væk uden at slette dem. Arkiverede elementer er skjult og inaktive, men bevarer historik og omkostninger.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "Ungültiges Datum", "ws_err_invalid_date": "Ungültiges Datum",
"ws_err_invalid_format": "Ungültiges Format", "ws_err_invalid_format": "Ungültiges Format",
"ws_err_invalid_url": "Ungültiger Link", "ws_err_invalid_url": "Ungültiger Link",
"ws_err_invalid_mirror_todo": "Ungültige To-do-Liste",
"ws_err_not_configured": "Noch nicht eingerichtet", "ws_err_not_configured": "Noch nicht eingerichtet",
"ws_err_not_loaded": "Noch nicht geladen — gleich noch einmal versuchen", "ws_err_not_loaded": "Noch nicht geladen — gleich noch einmal versuchen",
"ws_err_limit_reached": "Limit erreicht", "ws_err_limit_reached": "Limit erreicht",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "Keine Vorgaben für das Schnell-Erledigen hinterlegt", "ws_err_no_defaults": "Keine Vorgaben für das Schnell-Erledigen hinterlegt",
"ws_err_self_link_device": "Ein Objekt kann nicht mit sich selbst verknüpft werden", "ws_err_self_link_device": "Ein Objekt kann nicht mit sich selbst verknüpft werden",
"ws_err_too_early": "Zu früh — diese Aufgabe kann erst näher am Fälligkeitsdatum erledigt werden", "ws_err_too_early": "Zu früh — diese Aufgabe kann erst näher am Fälligkeitsdatum erledigt werden",
"ws_err_invalid_search_template": "Der Suchlink muss eine http(s)-URL mit {q} sein",
"feat_schedule_time": "Uhrzeit-Scheduling", "feat_schedule_time": "Uhrzeit-Scheduling",
"feat_schedule_time_desc": "Tasks werden zu einer festen Uhrzeit fällig statt um Mitternacht.", "feat_schedule_time_desc": "Tasks werden zu einer festen Uhrzeit fällig statt um Mitternacht.",
"schedule_time_toggle": "Zu einer bestimmten Uhrzeit fällig", "schedule_time_toggle": "Zu einer bestimmten Uhrzeit fällig",
@@ -201,6 +203,8 @@
"labels": "Labels", "labels": "Labels",
"labels_placeholder": "z. B. Sicherheit, Saison, Mieter-sichtbar", "labels_placeholder": "z. B. Sicherheit, Saison, Mieter-sichtbar",
"labels_help": "Kommagetrennte Tags zum Filtern und für Berichte.", "labels_help": "Kommagetrennte Tags zum Filtern und für Berichte.",
"task_mirror_todo": "In To-do-Listen spiegeln",
"task_mirror_todo_hint": "Die Aufgabe erscheint in diesen Listen, solange sie fällig ist; wird sie dort abgehakt, gilt sie hier als erledigt.",
"priority_low": "Niedrig", "priority_low": "Niedrig",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Hoch", "priority_high": "Hoch",
@@ -498,6 +502,8 @@
"settings_default_warning": "Standard-Warntage", "settings_default_warning": "Standard-Warntage",
"settings_consumable_threshold": "Schwelle „Verbrauchsmaterial niedrig“ (%)", "settings_consumable_threshold": "Schwelle „Verbrauchsmaterial niedrig“ (%)",
"settings_battery_low_percent": "Schwelle „Batterie niedrig“ (%)", "settings_battery_low_percent": "Schwelle „Batterie niedrig“ (%)",
"settings_battery_recovered_percent": "Batterie gilt als ersetzt ab (%)",
"settings_battery_recovered_percent_hint": "Eine niedrige Batterie bleibt so lange als niedrig gezählt, bis ihr Stand über diesen Wert steigt oder ein Wechsel erfasst wird — ein Stand, der um die Schwelle pendelt, schließt die Flottenaufgabe so nicht immer wieder ab.",
"settings_battery_lifetimes": "Typische Batterie-Lebensdauern", "settings_battery_lifetimes": "Typische Batterie-Lebensdauern",
"settings_battery_lifetimes_hint": "Wird nur für Batterien ohne Prozentanzeige verwendet: eine Battery-Notes-Notiz, die nur Typ und Austauschdatum kennt, oder ein Sensor, der nur „schwach“ meldet. Deren Fälligkeit ist letzter Wechsel + diese Lebensdauer. Batterien mit Füllstand bekommen ihre Prognose aus der gemessenen Entladung. Sobald die Flotte drei Wechsel eines Typs gesehen hat, ersetzt das mittlere Intervall den eingebauten Wert — dein eigener Wert gewinnt immer.", "settings_battery_lifetimes_hint": "Wird nur für Batterien ohne Prozentanzeige verwendet: eine Battery-Notes-Notiz, die nur Typ und Austauschdatum kennt, oder ein Sensor, der nur „schwach“ meldet. Deren Fälligkeit ist letzter Wechsel + diese Lebensdauer. Batterien mit Füllstand bekommen ihre Prognose aus der gemessenen Entladung. Sobald die Flotte drei Wechsel eines Typs gesehen hat, ersetzt das mittlere Intervall den eingebauten Wert — dein eigener Wert gewinnt immer.",
"settings_battery_lifetime_months": "Monate", "settings_battery_lifetime_months": "Monate",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "in deiner Flotte", "settings_battery_lifetime_in_fleet": "in deiner Flotte",
"settings_battery_lifetime_learned_models": "Gelernt je Modell: {list}", "settings_battery_lifetime_learned_models": "Gelernt je Modell: {list}",
"settings_thresholds_hint": "Vorgaben für neue Vorgeschlagene Einrichtungen (Prozent-Restwert) und für Flotten-Batterien ohne eigene Battery-Notes-Schwelle. Bestehende Aufgaben behalten ihren Wert.", "settings_thresholds_hint": "Vorgaben für neue Vorgeschlagene Einrichtungen (Prozent-Restwert) und für Flotten-Batterien ohne eigene Battery-Notes-Schwelle. Bestehende Aufgaben behalten ihren Wert.",
"settings_part_search_url": "Link für die Einkaufssuche",
"settings_part_search_url_hint": "URL mit {q} anstelle der Suchbegriffe, für Teile ohne Produktlink. Leer lassen für den automatischen Shop (nach Land, sonst nach Sprache).",
"settings_value_out_of_range": "Der Wert muss zwischen {min} und {max} liegen", "settings_value_out_of_range": "Der Wert muss zwischen {min} und {max} liegen",
"bn_summary": "{name}: {pct} % für {n} Batterien", "bn_summary": "{name}: {pct} % für {n} Batterien",
"bn_floor_decides": "Deine {floor}-%-Schwelle entscheidet für alle; pro Batterie zählt die höhere der beiden Schwellen.", "bn_floor_decides": "Deine {floor}-%-Schwelle entscheidet für alle; pro Batterie zählt die höhere der beiden Schwellen.",
@@ -717,6 +725,8 @@
"archived": "Archiviert", "archived": "Archiviert",
"show_archived": "Archivierte anzeigen", "show_archived": "Archivierte anzeigen",
"hide_archived": "Archivierte ausblenden", "hide_archived": "Archivierte ausblenden",
"section_collapse": "Bereich einklappen",
"section_expand": "Bereich ausklappen",
"confirm_archive_object": "Dieses Objekt und seine Aufgaben archivieren? Verlauf bleibt erhalten, kann später wiederhergestellt werden.", "confirm_archive_object": "Dieses Objekt und seine Aufgaben archivieren? Verlauf bleibt erhalten, kann später wiederhergestellt werden.",
"settings_archive": "Archiv & Aufbewahrung", "settings_archive": "Archiv & Aufbewahrung",
"settings_archive_desc": "Erledigte einmalige Aufgaben archivieren statt löschen. Archivierte Einträge sind ausgeblendet und inaktiv, behalten aber Verlauf und Kosten.", "settings_archive_desc": "Erledigte einmalige Aufgaben archivieren statt löschen. Archivierte Einträge sind ausgeblendet und inaktiv, behalten aber Verlauf und Kosten.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "Invalid date", "ws_err_invalid_date": "Invalid date",
"ws_err_invalid_format": "Invalid format", "ws_err_invalid_format": "Invalid format",
"ws_err_invalid_url": "Invalid link", "ws_err_invalid_url": "Invalid link",
"ws_err_invalid_mirror_todo": "Invalid to-do list",
"ws_err_not_configured": "Not set up yet", "ws_err_not_configured": "Not set up yet",
"ws_err_not_loaded": "Not loaded yet — try again in a moment", "ws_err_not_loaded": "Not loaded yet — try again in a moment",
"ws_err_limit_reached": "Limit reached", "ws_err_limit_reached": "Limit reached",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "No quick-complete defaults set", "ws_err_no_defaults": "No quick-complete defaults set",
"ws_err_self_link_device": "An object cannot be linked to itself", "ws_err_self_link_device": "An object cannot be linked to itself",
"ws_err_too_early": "Too early — this task can only be completed closer to its due date", "ws_err_too_early": "Too early — this task can only be completed closer to its due date",
"ws_err_invalid_search_template": "The search link must be an http(s) URL containing {q}",
"feat_schedule_time": "Time-of-day scheduling", "feat_schedule_time": "Time-of-day scheduling",
"feat_schedule_time_desc": "Tasks become overdue at a specific time of day instead of midnight.", "feat_schedule_time_desc": "Tasks become overdue at a specific time of day instead of midnight.",
"schedule_time_toggle": "Due at a specific time", "schedule_time_toggle": "Due at a specific time",
@@ -201,6 +203,8 @@
"labels": "Labels", "labels": "Labels",
"labels_placeholder": "e.g. safety, seasonal, tenant-visible", "labels_placeholder": "e.g. safety, seasonal, tenant-visible",
"labels_help": "Comma-separated tags for filtering and reporting.", "labels_help": "Comma-separated tags for filtering and reporting.",
"task_mirror_todo": "Mirror into to-do lists",
"task_mirror_todo_hint": "The task appears in these lists while it is due; checking it off there completes it here.",
"priority_low": "Low", "priority_low": "Low",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "High", "priority_high": "High",
@@ -498,6 +502,8 @@
"settings_default_warning": "Default warning days", "settings_default_warning": "Default warning days",
"settings_consumable_threshold": "Consumable low threshold (%)", "settings_consumable_threshold": "Consumable low threshold (%)",
"settings_battery_low_percent": "Battery low threshold (%)", "settings_battery_low_percent": "Battery low threshold (%)",
"settings_battery_recovered_percent": "Battery counts as replaced above (%)",
"settings_battery_recovered_percent_hint": "A low battery stays counted as low until its level rises above this value or a replacement is recorded — so a level hovering around the low threshold cannot complete the fleet task again and again.",
"settings_battery_lifetimes": "Typical battery lifetimes", "settings_battery_lifetimes": "Typical battery lifetimes",
"settings_battery_lifetimes_hint": "Only used for batteries without a percentage: a Battery Notes note that has just a type and a last-replaced date, or a sensor that only reports \"low\". Their due date is last replaced + this lifetime. Batteries that report a level get their forecast from the measured discharge instead. Once the fleet has seen three replacements of a type, the median interval takes over from the built-in value — your own value always wins.", "settings_battery_lifetimes_hint": "Only used for batteries without a percentage: a Battery Notes note that has just a type and a last-replaced date, or a sensor that only reports \"low\". Their due date is last replaced + this lifetime. Batteries that report a level get their forecast from the measured discharge instead. Once the fleet has seen three replacements of a type, the median interval takes over from the built-in value — your own value always wins.",
"settings_battery_lifetime_months": "months", "settings_battery_lifetime_months": "months",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "in your fleet", "settings_battery_lifetime_in_fleet": "in your fleet",
"settings_battery_lifetime_learned_models": "Learned per model: {list}", "settings_battery_lifetime_learned_models": "Learned per model: {list}",
"settings_thresholds_hint": "Defaults for new Suggested setups (percent-remaining consumables) and for fleet batteries without their own Battery Notes threshold. Existing tasks keep their value.", "settings_thresholds_hint": "Defaults for new Suggested setups (percent-remaining consumables) and for fleet batteries without their own Battery Notes threshold. Existing tasks keep their value.",
"settings_part_search_url": "Shopping search link",
"settings_part_search_url_hint": "URL with {q} in place of the search terms, used for parts without a product link. Leave empty for the automatic store (by country, then by language).",
"settings_value_out_of_range": "Value must be between {min} and {max}", "settings_value_out_of_range": "Value must be between {min} and {max}",
"bn_summary": "{name}: {pct} % for {n} batteries", "bn_summary": "{name}: {pct} % for {n} batteries",
"bn_floor_decides": "Your {floor} % floor decides for all of them; the higher of the two thresholds counts per battery.", "bn_floor_decides": "Your {floor} % floor decides for all of them; the higher of the two thresholds counts per battery.",
@@ -723,6 +731,8 @@
"archived": "Archived", "archived": "Archived",
"show_archived": "Show archived", "show_archived": "Show archived",
"hide_archived": "Hide archived", "hide_archived": "Hide archived",
"section_collapse": "Collapse section",
"section_expand": "Expand section",
"confirm_archive_object": "Archive this object and its tasks? They keep their history and can be unarchived later.", "confirm_archive_object": "Archive this object and its tasks? They keep their history and can be unarchived later.",
"settings_archive": "Archive & Retention", "settings_archive": "Archive & Retention",
"settings_archive_desc": "Retire completed one-off tasks without deleting them. Archived items are hidden and inert but keep their history and cost.", "settings_archive_desc": "Retire completed one-off tasks without deleting them. Archived items are hidden and inert but keep their history and cost.",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Fecha no válida", "ws_err_invalid_date": "Fecha no válida",
"ws_err_invalid_format": "Formato no válido", "ws_err_invalid_format": "Formato no válido",
"ws_err_invalid_url": "Enlace no válido", "ws_err_invalid_url": "Enlace no válido",
"ws_err_invalid_mirror_todo": "Lista de tareas no válida",
"ws_err_not_configured": "Aún no configurado", "ws_err_not_configured": "Aún no configurado",
"ws_err_not_loaded": "Aún no cargado — inténtalo de nuevo en un momento", "ws_err_not_loaded": "Aún no cargado — inténtalo de nuevo en un momento",
"ws_err_limit_reached": "Límite alcanzado", "ws_err_limit_reached": "Límite alcanzado",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "No hay valores predeterminados para completar rápido", "ws_err_no_defaults": "No hay valores predeterminados para completar rápido",
"ws_err_self_link_device": "Un objeto no puede vincularse a sí mismo", "ws_err_self_link_device": "Un objeto no puede vincularse a sí mismo",
"ws_err_too_early": "Demasiado pronto — esta tarea solo puede completarse más cerca de su vencimiento", "ws_err_too_early": "Demasiado pronto — esta tarea solo puede completarse más cerca de su vencimiento",
"ws_err_invalid_search_template": "El enlace de búsqueda debe ser una URL http(s) que contenga {q}",
"feat_schedule_time": "Programación por hora", "feat_schedule_time": "Programación por hora",
"feat_schedule_time_desc": "Las tareas vencen a una hora específica en lugar de medianoche.", "feat_schedule_time_desc": "Las tareas vencen a una hora específica en lugar de medianoche.",
"schedule_time_toggle": "Vence a una hora concreta", "schedule_time_toggle": "Vence a una hora concreta",
@@ -199,6 +201,8 @@
"labels": "Etiquetas", "labels": "Etiquetas",
"labels_placeholder": "p. ej. seguridad, estacional, visible-inquilino", "labels_placeholder": "p. ej. seguridad, estacional, visible-inquilino",
"labels_help": "Etiquetas separadas por comas para filtrar e informes.", "labels_help": "Etiquetas separadas por comas para filtrar e informes.",
"task_mirror_todo": "Reflejar en listas de tareas",
"task_mirror_todo_hint": "La tarea aparece en estas listas mientras esté pendiente; marcarla allí la completa aquí.",
"priority_low": "Baja", "priority_low": "Baja",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Alta", "priority_high": "Alta",
@@ -496,6 +500,8 @@
"settings_default_warning": "Días de aviso predeterminados", "settings_default_warning": "Días de aviso predeterminados",
"settings_consumable_threshold": "Umbral „consumible bajo“ (%)", "settings_consumable_threshold": "Umbral „consumible bajo“ (%)",
"settings_battery_low_percent": "Umbral „pila baja“ (%)", "settings_battery_low_percent": "Umbral „pila baja“ (%)",
"settings_battery_recovered_percent": "Pila considerada sustituida por encima de (%)",
"settings_battery_recovered_percent_hint": "Una pila baja sigue contando como baja hasta que su nivel supere este valor o se registre una sustitución — así un nivel que oscila alrededor del umbral no completa la tarea de la flota una y otra vez.",
"settings_battery_lifetimes": "Duraciones típicas de las pilas", "settings_battery_lifetimes": "Duraciones típicas de las pilas",
"settings_battery_lifetimes_hint": "Solo se usa para pilas sin porcentaje: una nota de Battery Notes que solo tiene tipo y fecha de sustitución, o un sensor que solo avisa de « baja ». Su vencimiento es última sustitución + esta duración. Las pilas que informan de un nivel obtienen su previsión de la descarga medida. Cuando la flota ha visto tres sustituciones de un tipo, el intervalo mediano sustituye al valor integrado — tu valor siempre gana.", "settings_battery_lifetimes_hint": "Solo se usa para pilas sin porcentaje: una nota de Battery Notes que solo tiene tipo y fecha de sustitución, o un sensor que solo avisa de « baja ». Su vencimiento es última sustitución + esta duración. Las pilas que informan de un nivel obtienen su previsión de la descarga medida. Cuando la flota ha visto tres sustituciones de un tipo, el intervalo mediano sustituye al valor integrado — tu valor siempre gana.",
"settings_battery_lifetime_months": "meses", "settings_battery_lifetime_months": "meses",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "en tu flota", "settings_battery_lifetime_in_fleet": "en tu flota",
"settings_battery_lifetime_learned_models": "Aprendido por modelo: {list}", "settings_battery_lifetime_learned_models": "Aprendido por modelo: {list}",
"settings_thresholds_hint": "Valores predeterminados para nuevas Configuraciones sugeridas (porcentaje restante) y para pilas de la flota sin umbral propio de Battery Notes. Las tareas existentes conservan su valor.", "settings_thresholds_hint": "Valores predeterminados para nuevas Configuraciones sugeridas (porcentaje restante) y para pilas de la flota sin umbral propio de Battery Notes. Las tareas existentes conservan su valor.",
"settings_part_search_url": "Enlace de búsqueda de compra",
"settings_part_search_url_hint": "URL con {q} en lugar de los términos de búsqueda, para piezas sin enlace de producto. Dejar vacío para la tienda automática (por país, si no por idioma).",
"settings_value_out_of_range": "El valor debe estar entre {min} y {max}", "settings_value_out_of_range": "El valor debe estar entre {min} y {max}",
"bn_summary": "{name}: {pct} % para {n} pilas", "bn_summary": "{name}: {pct} % para {n} pilas",
"bn_floor_decides": "Tu umbral del {floor} % decide para todas; por pila cuenta el mayor de los dos umbrales.", "bn_floor_decides": "Tu umbral del {floor} % decide para todas; por pila cuenta el mayor de los dos umbrales.",
@@ -717,6 +725,8 @@
"archived": "Archivado", "archived": "Archivado",
"show_archived": "Mostrar archivados", "show_archived": "Mostrar archivados",
"hide_archived": "Ocultar archivados", "hide_archived": "Ocultar archivados",
"section_collapse": "Contraer sección",
"section_expand": "Expandir sección",
"confirm_archive_object": "¿Archivar este objeto y sus tareas? Se conserva el historial y se puede restaurar más tarde.", "confirm_archive_object": "¿Archivar este objeto y sus tareas? Se conserva el historial y se puede restaurar más tarde.",
"settings_archive": "Archivado y retención", "settings_archive": "Archivado y retención",
"settings_archive_desc": "Retira las tareas únicas completadas sin eliminarlas. Los elementos archivados se ocultan y quedan inactivos, pero conservan su historial y coste.", "settings_archive_desc": "Retira las tareas únicas completadas sin eliminarlas. Los elementos archivados se ocultan y quedan inactivos, pero conservan su historial y coste.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "Virheellinen päivämäärä", "ws_err_invalid_date": "Virheellinen päivämäärä",
"ws_err_invalid_format": "Virheellinen muoto", "ws_err_invalid_format": "Virheellinen muoto",
"ws_err_invalid_url": "Virheellinen linkki", "ws_err_invalid_url": "Virheellinen linkki",
"ws_err_invalid_mirror_todo": "Virheellinen tehtävälista",
"ws_err_not_configured": "Ei vielä määritetty", "ws_err_not_configured": "Ei vielä määritetty",
"ws_err_not_loaded": "Ei vielä ladattu — yritä hetken kuluttua uudelleen", "ws_err_not_loaded": "Ei vielä ladattu — yritä hetken kuluttua uudelleen",
"ws_err_limit_reached": "Raja saavutettu", "ws_err_limit_reached": "Raja saavutettu",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "Pikavalmistumisen oletuksia ei ole asetettu", "ws_err_no_defaults": "Pikavalmistumisen oletuksia ei ole asetettu",
"ws_err_self_link_device": "Objektia ei voi linkittää itseensä", "ws_err_self_link_device": "Objektia ei voi linkittää itseensä",
"ws_err_too_early": "Liian aikaista — tehtävän voi merkitä tehdyksi vasta lähempänä eräpäivää", "ws_err_too_early": "Liian aikaista — tehtävän voi merkitä tehdyksi vasta lähempänä eräpäivää",
"ws_err_invalid_search_template": "Hakulinkin on oltava http(s)-URL, joka sisältää {q}",
"feat_schedule_time": "Kellonajan ajoitus", "feat_schedule_time": "Kellonajan ajoitus",
"feat_schedule_time_desc": "Tehtävät erääntyvät tiettyyn kellonaikaan keskiyön sijaan.", "feat_schedule_time_desc": "Tehtävät erääntyvät tiettyyn kellonaikaan keskiyön sijaan.",
"schedule_time_toggle": "Erääntyy tiettyyn kellonaikaan", "schedule_time_toggle": "Erääntyy tiettyyn kellonaikaan",
@@ -201,6 +203,8 @@
"labels": "Tunnisteet", "labels": "Tunnisteet",
"labels_placeholder": "esim. turvallisuus, kausittainen, vuokralaiselle-näkyvä", "labels_placeholder": "esim. turvallisuus, kausittainen, vuokralaiselle-näkyvä",
"labels_help": "Pilkuin erotellut tunnisteet suodatusta ja raportointia varten.", "labels_help": "Pilkuin erotellut tunnisteet suodatusta ja raportointia varten.",
"task_mirror_todo": "Peilaa tehtävälistoihin",
"task_mirror_todo_hint": "Tehtävä näkyy näissä listoissa, kun se on ajankohtainen; sen kuittaaminen siellä suorittaa sen täällä.",
"priority_low": "Matala", "priority_low": "Matala",
"priority_normal": "Normaali", "priority_normal": "Normaali",
"priority_high": "Korkea", "priority_high": "Korkea",
@@ -498,6 +502,8 @@
"settings_default_warning": "Oletusvaroituspäivät", "settings_default_warning": "Oletusvaroituspäivät",
"settings_consumable_threshold": "Kynnys „kulutustarvike vähissä“ (%)", "settings_consumable_threshold": "Kynnys „kulutustarvike vähissä“ (%)",
"settings_battery_low_percent": "Kynnys „paristo vähissä“ (%)", "settings_battery_low_percent": "Kynnys „paristo vähissä“ (%)",
"settings_battery_recovered_percent": "Paristo lasketaan vaihdetuksi yli (%)",
"settings_battery_recovered_percent_hint": "Vähissä oleva paristo lasketaan vähissä olevaksi, kunnes sen taso nousee tämän arvon yli tai vaihto kirjataan — näin kynnyksen ympärillä heilahteleva taso ei suorita laivastotehtävää yhä uudelleen.",
"settings_battery_lifetimes": "Paristojen tyypilliset käyttöiät", "settings_battery_lifetimes": "Paristojen tyypilliset käyttöiät",
"settings_battery_lifetimes_hint": "Käytetään vain paristoille ilman prosenttilukua: Battery Notes -merkintä, jolla on vain tyyppi ja vaihtopäivä, tai anturi, joka ilmoittaa vain ”vähissä”. Erääntyminen = viimeisin vaihto + tämä käyttöikä. Tasoa raportoivien paristojen ennuste tulee mitatusta purkautumisesta. Kun laivasto on nähnyt kolme saman tyypin vaihtoa, mediaaniväli korvaa sisäänrakennetun arvon — oma arvosi voittaa aina.", "settings_battery_lifetimes_hint": "Käytetään vain paristoille ilman prosenttilukua: Battery Notes -merkintä, jolla on vain tyyppi ja vaihtopäivä, tai anturi, joka ilmoittaa vain ”vähissä”. Erääntyminen = viimeisin vaihto + tämä käyttöikä. Tasoa raportoivien paristojen ennuste tulee mitatusta purkautumisesta. Kun laivasto on nähnyt kolme saman tyypin vaihtoa, mediaaniväli korvaa sisäänrakennetun arvon — oma arvosi voittaa aina.",
"settings_battery_lifetime_months": "kuukautta", "settings_battery_lifetime_months": "kuukautta",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "laivastossasi", "settings_battery_lifetime_in_fleet": "laivastossasi",
"settings_battery_lifetime_learned_models": "Opittu mallikohtaisesti: {list}", "settings_battery_lifetime_learned_models": "Opittu mallikohtaisesti: {list}",
"settings_thresholds_hint": "Oletukset uusille Ehdotetuille asetuksille (jäljellä oleva prosentti) ja paristokannan paristoille ilman omaa Battery Notes -kynnystä. Olemassa olevat tehtävät säilyttävät arvonsa.", "settings_thresholds_hint": "Oletukset uusille Ehdotetuille asetuksille (jäljellä oleva prosentti) ja paristokannan paristoille ilman omaa Battery Notes -kynnystä. Olemassa olevat tehtävät säilyttävät arvonsa.",
"settings_part_search_url": "Ostohaun linkki",
"settings_part_search_url_hint": "URL, jossa {q} korvaa hakusanat, osille ilman tuotelinkkiä. Jätä tyhjäksi, niin kauppa valitaan automaattisesti (maan, muuten kielen mukaan).",
"settings_value_out_of_range": "Arvon on oltava välillä {min}–{max}", "settings_value_out_of_range": "Arvon on oltava välillä {min}–{max}",
"bn_summary": "{name}: {pct} % {n} paristolle", "bn_summary": "{name}: {pct} % {n} paristolle",
"bn_floor_decides": "Sinun {floor} %:n kynnyksesi ratkaisee kaikille; paristoa kohden pätee korkeampi kahdesta kynnyksestä.", "bn_floor_decides": "Sinun {floor} %:n kynnyksesi ratkaisee kaikille; paristoa kohden pätee korkeampi kahdesta kynnyksestä.",
@@ -717,6 +725,8 @@
"archived": "Arkistoitu", "archived": "Arkistoitu",
"show_archived": "Näytä arkistoidut", "show_archived": "Näytä arkistoidut",
"hide_archived": "Piilota arkistoidut", "hide_archived": "Piilota arkistoidut",
"section_collapse": "Pienennä osio",
"section_expand": "Laajenna osio",
"confirm_archive_object": "Arkistoidaanko tämä kohde ja sen tehtävät? Historia säilyy ja sen voi palauttaa myöhemmin.", "confirm_archive_object": "Arkistoidaanko tämä kohde ja sen tehtävät? Historia säilyy ja sen voi palauttaa myöhemmin.",
"settings_archive": "Arkistointi ja säilytys", "settings_archive": "Arkistointi ja säilytys",
"settings_archive_desc": "Siirrä valmiit kertatehtävät arkistoon poistamatta niitä. Arkistoidut kohteet ovat piilossa ja passiivisia, mutta säilyttävät historian ja kustannukset.", "settings_archive_desc": "Siirrä valmiit kertatehtävät arkistoon poistamatta niitä. Arkistoidut kohteet ovat piilossa ja passiivisia, mutta säilyttävät historian ja kustannukset.",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Date non valide", "ws_err_invalid_date": "Date non valide",
"ws_err_invalid_format": "Format non valide", "ws_err_invalid_format": "Format non valide",
"ws_err_invalid_url": "Lien non valide", "ws_err_invalid_url": "Lien non valide",
"ws_err_invalid_mirror_todo": "Liste de tâches non valide",
"ws_err_not_configured": "Pas encore configuré", "ws_err_not_configured": "Pas encore configuré",
"ws_err_not_loaded": "Pas encore chargé — réessayez dans un instant", "ws_err_not_loaded": "Pas encore chargé — réessayez dans un instant",
"ws_err_limit_reached": "Limite atteinte", "ws_err_limit_reached": "Limite atteinte",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "Aucune valeur par défaut pour la validation rapide", "ws_err_no_defaults": "Aucune valeur par défaut pour la validation rapide",
"ws_err_self_link_device": "Un objet ne peut pas être lié à lui-même", "ws_err_self_link_device": "Un objet ne peut pas être lié à lui-même",
"ws_err_too_early": "Trop tôt — cette tâche ne peut être terminée que plus près de son échéance", "ws_err_too_early": "Trop tôt — cette tâche ne peut être terminée que plus près de son échéance",
"ws_err_invalid_search_template": "Le lien de recherche doit être une URL http(s) contenant {q}",
"feat_schedule_time": "Planification à l'heure", "feat_schedule_time": "Planification à l'heure",
"feat_schedule_time_desc": "Les tâches arrivent à échéance à une heure précise plutôt qu'à minuit.", "feat_schedule_time_desc": "Les tâches arrivent à échéance à une heure précise plutôt qu'à minuit.",
"schedule_time_toggle": "Échéance à une heure précise", "schedule_time_toggle": "Échéance à une heure précise",
@@ -199,6 +201,8 @@
"labels": "Étiquettes", "labels": "Étiquettes",
"labels_placeholder": "p. ex. sécurité, saisonnier, visible-locataire", "labels_placeholder": "p. ex. sécurité, saisonnier, visible-locataire",
"labels_help": "Étiquettes séparées par des virgules pour le filtrage et les rapports.", "labels_help": "Étiquettes séparées par des virgules pour le filtrage et les rapports.",
"task_mirror_todo": "Refléter dans des listes de tâches",
"task_mirror_todo_hint": "La tâche apparaît dans ces listes tant qu'elle est à faire ; la cocher là-bas la termine ici.",
"priority_low": "Basse", "priority_low": "Basse",
"priority_normal": "Normale", "priority_normal": "Normale",
"priority_high": "Haute", "priority_high": "Haute",
@@ -496,6 +500,8 @@
"settings_default_warning": "Jours d'avertissement par défaut", "settings_default_warning": "Jours d'avertissement par défaut",
"settings_consumable_threshold": "Seuil « consommable bas » (%)", "settings_consumable_threshold": "Seuil « consommable bas » (%)",
"settings_battery_low_percent": "Seuil « pile faible » (%)", "settings_battery_low_percent": "Seuil « pile faible » (%)",
"settings_battery_recovered_percent": "Pile considérée remplacée au-dessus de (%)",
"settings_battery_recovered_percent_hint": "Une pile faible reste comptée comme faible tant que son niveau ne dépasse pas cette valeur ou qu'un remplacement n'est pas enregistré — un niveau qui oscille autour du seuil ne peut ainsi plus terminer la tâche du parc encore et encore.",
"settings_battery_lifetimes": "Durées de vie typiques des piles", "settings_battery_lifetimes": "Durées de vie typiques des piles",
"settings_battery_lifetimes_hint": "Utilisé uniquement pour les piles sans pourcentage : une note Battery Notes qui ne connaît qu'un type et une date de remplacement, ou un capteur qui ne signale que « faible ». Leur échéance est dernier remplacement + cette durée. Les piles qui remontent un niveau sont prévues d'après la décharge mesurée. Dès que le parc a vu trois remplacements d'un type, l'intervalle médian remplace la valeur intégrée — votre valeur l'emporte toujours.", "settings_battery_lifetimes_hint": "Utilisé uniquement pour les piles sans pourcentage : une note Battery Notes qui ne connaît qu'un type et une date de remplacement, ou un capteur qui ne signale que « faible ». Leur échéance est dernier remplacement + cette durée. Les piles qui remontent un niveau sont prévues d'après la décharge mesurée. Dès que le parc a vu trois remplacements d'un type, l'intervalle médian remplace la valeur intégrée — votre valeur l'emporte toujours.",
"settings_battery_lifetime_months": "mois", "settings_battery_lifetime_months": "mois",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "dans votre parc", "settings_battery_lifetime_in_fleet": "dans votre parc",
"settings_battery_lifetime_learned_models": "Appris par modèle : {list}", "settings_battery_lifetime_learned_models": "Appris par modèle : {list}",
"settings_thresholds_hint": "Valeurs par défaut pour les nouvelles Configurations suggérées (pourcentage restant) et pour les piles de la flotte sans seuil Battery Notes propre. Les tâches existantes gardent leur valeur.", "settings_thresholds_hint": "Valeurs par défaut pour les nouvelles Configurations suggérées (pourcentage restant) et pour les piles de la flotte sans seuil Battery Notes propre. Les tâches existantes gardent leur valeur.",
"settings_part_search_url": "Lien de recherche d'achat",
"settings_part_search_url_hint": "URL avec {q} à la place des termes de recherche, utilisée pour les pièces sans lien produit. Laisser vide pour la boutique automatique (selon le pays, sinon la langue).",
"settings_value_out_of_range": "La valeur doit être comprise entre {min} et {max}", "settings_value_out_of_range": "La valeur doit être comprise entre {min} et {max}",
"bn_summary": "{name} : {pct} % pour {n} piles", "bn_summary": "{name} : {pct} % pour {n} piles",
"bn_floor_decides": "Votre seuil de {floor} % décide pour toutes ; par pile, c'est le plus élevé des deux seuils qui compte.", "bn_floor_decides": "Votre seuil de {floor} % décide pour toutes ; par pile, c'est le plus élevé des deux seuils qui compte.",
@@ -717,6 +725,8 @@
"archived": "Archivé", "archived": "Archivé",
"show_archived": "Afficher les archivés", "show_archived": "Afficher les archivés",
"hide_archived": "Masquer les archivés", "hide_archived": "Masquer les archivés",
"section_collapse": "Réduire la section",
"section_expand": "Développer la section",
"confirm_archive_object": "Archiver cet objet et ses tâches ? L'historique est conservé et peut être restauré plus tard.", "confirm_archive_object": "Archiver cet objet et ses tâches ? L'historique est conservé et peut être restauré plus tard.",
"settings_archive": "Archivage et conservation", "settings_archive": "Archivage et conservation",
"settings_archive_desc": "Mettez de côté les tâches ponctuelles terminées sans les supprimer. Les éléments archivés sont masqués et inactifs, mais conservent leur historique et leurs coûts.", "settings_archive_desc": "Mettez de côté les tâches ponctuelles terminées sans les supprimer. Les éléments archivés sont masqués et inactifs, mais conservent leur historique et leurs coûts.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "अमान्य तारीख", "ws_err_invalid_date": "अमान्य तारीख",
"ws_err_invalid_format": "अमान्य प्रारूप", "ws_err_invalid_format": "अमान्य प्रारूप",
"ws_err_invalid_url": "अमान्य लिंक", "ws_err_invalid_url": "अमान्य लिंक",
"ws_err_invalid_mirror_todo": "अमान्य टू-डू सूची",
"ws_err_not_configured": "अभी सेट नहीं किया गया", "ws_err_not_configured": "अभी सेट नहीं किया गया",
"ws_err_not_loaded": "अभी लोड नहीं हुआ — कुछ देर बाद फिर से कोशिश करें", "ws_err_not_loaded": "अभी लोड नहीं हुआ — कुछ देर बाद फिर से कोशिश करें",
"ws_err_limit_reached": "सीमा पूरी हो गई", "ws_err_limit_reached": "सीमा पूरी हो गई",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "त्वरित पूर्णता के लिए डिफ़ॉल्ट सेट नहीं", "ws_err_no_defaults": "त्वरित पूर्णता के लिए डिफ़ॉल्ट सेट नहीं",
"ws_err_self_link_device": "कोई ऑब्जेक्ट स्वयं से लिंक नहीं हो सकता", "ws_err_self_link_device": "कोई ऑब्जेक्ट स्वयं से लिंक नहीं हो सकता",
"ws_err_too_early": "बहुत जल्दी — यह कार्य केवल नियत तारीख के करीब ही पूरा किया जा सकता है", "ws_err_too_early": "बहुत जल्दी — यह कार्य केवल नियत तारीख के करीब ही पूरा किया जा सकता है",
"ws_err_invalid_search_template": "खोज लिंक {q} वाला http(s) URL होना चाहिए",
"feat_schedule_time": "दिन का समय निर्धारण", "feat_schedule_time": "दिन का समय निर्धारण",
"feat_schedule_time_desc": "कार्य मध्यरात्रि के बजाय दिन के एक विशिष्ट समय पर अतिदेय हो जाते हैं।", "feat_schedule_time_desc": "कार्य मध्यरात्रि के बजाय दिन के एक विशिष्ट समय पर अतिदेय हो जाते हैं।",
"schedule_time_toggle": "किसी निश्चित समय पर देय", "schedule_time_toggle": "किसी निश्चित समय पर देय",
@@ -201,6 +203,8 @@
"labels": "लेबल", "labels": "लेबल",
"labels_placeholder": "जैसे सुरक्षा, मौसमी, किरायेदार-दृश्य", "labels_placeholder": "जैसे सुरक्षा, मौसमी, किरायेदार-दृश्य",
"labels_help": "फ़िल्टरिंग और रिपोर्टिंग के लिए अल्पविराम से अलग किए गए टैग।", "labels_help": "फ़िल्टरिंग और रिपोर्टिंग के लिए अल्पविराम से अलग किए गए टैग।",
"task_mirror_todo": "टू-डू सूचियों में मिरर करें",
"task_mirror_todo_hint": "जब तक कार्य देय है, यह इन सूचियों में दिखता है; वहाँ पूरा करने पर यह यहाँ भी पूरा हो जाता है।",
"priority_low": "कम", "priority_low": "कम",
"priority_normal": "सामान्य", "priority_normal": "सामान्य",
"priority_high": "उच्च", "priority_high": "उच्च",
@@ -498,6 +502,8 @@
"settings_default_warning": "डिफ़ॉल्ट चेतावनी दिन", "settings_default_warning": "डिफ़ॉल्ट चेतावनी दिन",
"settings_consumable_threshold": "उपभोग्य „कम“ सीमा (%)", "settings_consumable_threshold": "उपभोग्य „कम“ सीमा (%)",
"settings_battery_low_percent": "बैटरी „कम“ सीमा (%)", "settings_battery_low_percent": "बैटरी „कम“ सीमा (%)",
"settings_battery_recovered_percent": "इससे ऊपर बैटरी बदली हुई मानी जाएगी (%)",
"settings_battery_recovered_percent_hint": "कम बैटरी तब तक कम गिनी जाती है जब तक उसका स्तर इस मान से ऊपर न हो जाए या बदलाव दर्ज न हो — ताकि सीमा के आसपास झूलता स्तर बेड़े के कार्य को बार-बार पूरा न कर दे।",
"settings_battery_lifetimes": "बैटरी की सामान्य आयु", "settings_battery_lifetimes": "बैटरी की सामान्य आयु",
"settings_battery_lifetimes_hint": "केवल बिना प्रतिशत वाली बैटरियों के लिए: सिर्फ़ प्रकार और बदलने की तारीख वाला Battery Notes नोट, या केवल \"कम\" बताने वाला सेंसर। नियत तिथि = अंतिम बदलाव + यह आयु। स्तर बताने वाली बैटरियों का पूर्वानुमान मापे गए डिस्चार्ज से बनता है। एक प्रकार के तीन बदलाव देखने के बाद माध्यिका अंतराल अंतर्निहित मान की जगह लेता है — आपका अपना मान हमेशा प्राथमिकता पाता है।", "settings_battery_lifetimes_hint": "केवल बिना प्रतिशत वाली बैटरियों के लिए: सिर्फ़ प्रकार और बदलने की तारीख वाला Battery Notes नोट, या केवल \"कम\" बताने वाला सेंसर। नियत तिथि = अंतिम बदलाव + यह आयु। स्तर बताने वाली बैटरियों का पूर्वानुमान मापे गए डिस्चार्ज से बनता है। एक प्रकार के तीन बदलाव देखने के बाद माध्यिका अंतराल अंतर्निहित मान की जगह लेता है — आपका अपना मान हमेशा प्राथमिकता पाता है।",
"settings_battery_lifetime_months": "महीने", "settings_battery_lifetime_months": "महीने",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "आपके बेड़े में", "settings_battery_lifetime_in_fleet": "आपके बेड़े में",
"settings_battery_lifetime_learned_models": "मॉडल अनुसार सीखा: {list}", "settings_battery_lifetime_learned_models": "मॉडल अनुसार सीखा: {list}",
"settings_thresholds_hint": "नए सुझाए गए सेटअप (शेष प्रतिशत) और अपनी Battery Notes सीमा न रखने वाली बेड़े की बैटरियों के लिए डिफ़ॉल्ट। मौजूदा कार्य अपना मान रखते हैं।", "settings_thresholds_hint": "नए सुझाए गए सेटअप (शेष प्रतिशत) और अपनी Battery Notes सीमा न रखने वाली बेड़े की बैटरियों के लिए डिफ़ॉल्ट। मौजूदा कार्य अपना मान रखते हैं।",
"settings_part_search_url": "खरीदारी खोज लिंक",
"settings_part_search_url_hint": "खोज शब्दों की जगह {q} वाला URL, बिना उत्पाद लिंक वाले पुर्जों के लिए। स्वचालित स्टोर (देश, फिर भाषा के अनुसार) के लिए खाली छोड़ें।",
"settings_value_out_of_range": "मान {min} और {max} के बीच होना चाहिए", "settings_value_out_of_range": "मान {min} और {max} के बीच होना चाहिए",
"bn_summary": "{name}: {n} बैटरियों के लिए {pct} %", "bn_summary": "{name}: {n} बैटरियों के लिए {pct} %",
"bn_floor_decides": "आपकी {floor} % सीमा सभी के लिए निर्णायक है; प्रत्येक बैटरी के लिए दोनों में से ऊँची सीमा मान्य है।", "bn_floor_decides": "आपकी {floor} % सीमा सभी के लिए निर्णायक है; प्रत्येक बैटरी के लिए दोनों में से ऊँची सीमा मान्य है।",
@@ -717,6 +725,8 @@
"archived": "संग्रहीत", "archived": "संग्रहीत",
"show_archived": "संग्रहीत दिखाएँ", "show_archived": "संग्रहीत दिखाएँ",
"hide_archived": "संग्रहीत छिपाएँ", "hide_archived": "संग्रहीत छिपाएँ",
"section_collapse": "अनुभाग संक्षिप्त करें",
"section_expand": "अनुभाग विस्तृत करें",
"confirm_archive_object": "इस ऑब्जेक्ट और इसके कार्यों को संग्रहित करें? इतिहास सुरक्षित रहता है और बाद में पुनर्स्थापित किया जा सकता है।", "confirm_archive_object": "इस ऑब्जेक्ट और इसके कार्यों को संग्रहित करें? इतिहास सुरक्षित रहता है और बाद में पुनर्स्थापित किया जा सकता है।",
"settings_archive": "संग्रह और प्रतिधारण", "settings_archive": "संग्रह और प्रतिधारण",
"settings_archive_desc": "पूर्ण एक-बार के कार्यों को हटाए बिना अलग रखें। संग्रहीत आइटम छिपे और निष्क्रिय रहते हैं, पर इतिहास और लागत बनाए रखते हैं।", "settings_archive_desc": "पूर्ण एक-बार के कार्यों को हटाए बिना अलग रखें। संग्रहीत आइटम छिपे और निष्क्रिय रहते हैं, पर इतिहास और लागत बनाए रखते हैं।",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "Érvénytelen dátum", "ws_err_invalid_date": "Érvénytelen dátum",
"ws_err_invalid_format": "Érvénytelen formátum", "ws_err_invalid_format": "Érvénytelen formátum",
"ws_err_invalid_url": "Érvénytelen hivatkozás", "ws_err_invalid_url": "Érvénytelen hivatkozás",
"ws_err_invalid_mirror_todo": "Érvénytelen teendőlista",
"ws_err_not_configured": "Még nincs beállítva", "ws_err_not_configured": "Még nincs beállítva",
"ws_err_not_loaded": "Még nincs betöltve — próbálja újra egy pillanat múlva", "ws_err_not_loaded": "Még nincs betöltve — próbálja újra egy pillanat múlva",
"ws_err_limit_reached": "Elérte a korlátot", "ws_err_limit_reached": "Elérte a korlátot",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "Nincs beállítva gyors befejezési alapérték", "ws_err_no_defaults": "Nincs beállítva gyors befejezési alapérték",
"ws_err_self_link_device": "Egy objektum nem kapcsolható önmagához", "ws_err_self_link_device": "Egy objektum nem kapcsolható önmagához",
"ws_err_too_early": "Túl korai — ez a feladat csak a határidőhöz közelebb fejezhető be", "ws_err_too_early": "Túl korai — ez a feladat csak a határidőhöz közelebb fejezhető be",
"ws_err_invalid_search_template": "A keresőhivatkozásnak {q}-t tartalmazó http(s) URL-nek kell lennie",
"feat_schedule_time": "Napszakhoz kötött ütemezés", "feat_schedule_time": "Napszakhoz kötött ütemezés",
"feat_schedule_time_desc": "A feladatok nem éjfélkor, hanem egy megadott napszakban válnak lejárttá.", "feat_schedule_time_desc": "A feladatok nem éjfélkor, hanem egy megadott napszakban válnak lejárttá.",
"schedule_time_toggle": "Adott időpontban esedékes", "schedule_time_toggle": "Adott időpontban esedékes",
@@ -201,6 +203,8 @@
"labels": "Címkék", "labels": "Címkék",
"labels_placeholder": "pl. biztonság, szezonális, bérlőnek látható", "labels_placeholder": "pl. biztonság, szezonális, bérlőnek látható",
"labels_help": "Vesszővel elválasztott címkék szűréshez és jelentésekhez.", "labels_help": "Vesszővel elválasztott címkék szűréshez és jelentésekhez.",
"task_mirror_todo": "Tükrözés teendőlistákba",
"task_mirror_todo_hint": "A feladat addig jelenik meg ezekben a listákban, amíg esedékes; ha ott kipipálod, itt is elkészül.",
"priority_low": "Alacsony", "priority_low": "Alacsony",
"priority_normal": "Normál", "priority_normal": "Normál",
"priority_high": "Magas", "priority_high": "Magas",
@@ -498,6 +502,8 @@
"settings_default_warning": "Alapértelmezett figyelmeztetési napok", "settings_default_warning": "Alapértelmezett figyelmeztetési napok",
"settings_consumable_threshold": "„Fogyóeszköz alacsony” küszöb (%)", "settings_consumable_threshold": "„Fogyóeszköz alacsony” küszöb (%)",
"settings_battery_low_percent": "„Alacsony akkumulátor” küszöb (%)", "settings_battery_low_percent": "„Alacsony akkumulátor” küszöb (%)",
"settings_battery_recovered_percent": "Az elem cseréltnek számít e fölött (%)",
"settings_battery_recovered_percent_hint": "A lemerült elem addig számít lemerültnek, amíg a töltöttsége e fölé az érték fölé nem emelkedik, vagy egy cserét nem rögzítenek — így a küszöb körül ingadozó töltöttség nem zárja le újra és újra a flottafeladatot.",
"settings_battery_lifetimes": "Jellemző elem-élettartamok", "settings_battery_lifetimes": "Jellemző elem-élettartamok",
"settings_battery_lifetimes_hint": "Csak százalék nélküli elemeknél használjuk: olyan Battery Notes-bejegyzésnél, amelynek csak típusa és cseredátuma van, vagy csak „alacsony”-t jelentő érzékelőnél. Esedékesség = utolsó csere + ez az élettartam. A szintet jelentő elemek előrejelzése a mért kisülésből jön. Ha a flotta már három cserét látott egy típusból, a medián időköz veszi át a beépített értéket — a saját értéked mindig nyer.", "settings_battery_lifetimes_hint": "Csak százalék nélküli elemeknél használjuk: olyan Battery Notes-bejegyzésnél, amelynek csak típusa és cseredátuma van, vagy csak „alacsony”-t jelentő érzékelőnél. Esedékesség = utolsó csere + ez az élettartam. A szintet jelentő elemek előrejelzése a mért kisülésből jön. Ha a flotta már három cserét látott egy típusból, a medián időköz veszi át a beépített értéket — a saját értéked mindig nyer.",
"settings_battery_lifetime_months": "hónap", "settings_battery_lifetime_months": "hónap",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "a flottádban", "settings_battery_lifetime_in_fleet": "a flottádban",
"settings_battery_lifetime_learned_models": "Modellenként tanulva: {list}", "settings_battery_lifetime_learned_models": "Modellenként tanulva: {list}",
"settings_thresholds_hint": "Alapértékek az új Javasolt beállításokhoz (százalékos maradék) és a saját Battery Notes-küszöb nélküli flottaelemekhez. A meglévő feladatok megtartják az értéküket.", "settings_thresholds_hint": "Alapértékek az új Javasolt beállításokhoz (százalékos maradék) és a saját Battery Notes-küszöb nélküli flottaelemekhez. A meglévő feladatok megtartják az értéküket.",
"settings_part_search_url": "Vásárlási keresőhivatkozás",
"settings_part_search_url_hint": "URL {q}-val a keresőkifejezések helyén, a terméklink nélküli alkatrészekhez. Hagyja üresen az automatikus bolthoz (ország, különben nyelv szerint).",
"settings_value_out_of_range": "Az értéknek {min} és {max} között kell lennie", "settings_value_out_of_range": "Az értéknek {min} és {max} között kell lennie",
"bn_summary": "{name}: {pct} % {n} elemhez", "bn_summary": "{name}: {pct} % {n} elemhez",
"bn_floor_decides": "A te {floor} %-os küszöböd dönt mindegyiknél; elemenként a két küszöb közül a magasabb számít.", "bn_floor_decides": "A te {floor} %-os küszöböd dönt mindegyiknél; elemenként a két küszöb közül a magasabb számít.",
@@ -723,6 +731,8 @@
"archived": "Archiválva", "archived": "Archiválva",
"show_archived": "Archiváltak megjelenítése", "show_archived": "Archiváltak megjelenítése",
"hide_archived": "Archiváltak elrejtése", "hide_archived": "Archiváltak elrejtése",
"section_collapse": "Szakasz összecsukása",
"section_expand": "Szakasz kibontása",
"confirm_archive_object": "Archiválja az objektumot és a feladatait? Megtartják előzményeiket, és később visszaállíthatók.", "confirm_archive_object": "Archiválja az objektumot és a feladatait? Megtartják előzményeiket, és később visszaállíthatók.",
"settings_archive": "Archiválás és megőrzés", "settings_archive": "Archiválás és megőrzés",
"settings_archive_desc": "Elvégzett egyszeri feladatok kivezetése törlés nélkül. Az archivált elemek rejtettek és inaktívak, de megtartják előzményeiket és költségeiket.", "settings_archive_desc": "Elvégzett egyszeri feladatok kivezetése törlés nélkül. Az archivált elemek rejtettek és inaktívak, de megtartják előzményeiket és költségeiket.",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Data non valida", "ws_err_invalid_date": "Data non valida",
"ws_err_invalid_format": "Formato non valido", "ws_err_invalid_format": "Formato non valido",
"ws_err_invalid_url": "Link non valido", "ws_err_invalid_url": "Link non valido",
"ws_err_invalid_mirror_todo": "Lista di cose da fare non valida",
"ws_err_not_configured": "Non ancora configurato", "ws_err_not_configured": "Non ancora configurato",
"ws_err_not_loaded": "Non ancora caricato — riprova tra un istante", "ws_err_not_loaded": "Non ancora caricato — riprova tra un istante",
"ws_err_limit_reached": "Limite raggiunto", "ws_err_limit_reached": "Limite raggiunto",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "Nessun valore predefinito per il completamento rapido", "ws_err_no_defaults": "Nessun valore predefinito per il completamento rapido",
"ws_err_self_link_device": "Un oggetto non può essere collegato a sé stesso", "ws_err_self_link_device": "Un oggetto non può essere collegato a sé stesso",
"ws_err_too_early": "Troppo presto — questa attività può essere completata solo più vicino alla scadenza", "ws_err_too_early": "Troppo presto — questa attività può essere completata solo più vicino alla scadenza",
"ws_err_invalid_search_template": "Il link di ricerca deve essere un URL http(s) contenente {q}",
"feat_schedule_time": "Pianificazione oraria", "feat_schedule_time": "Pianificazione oraria",
"feat_schedule_time_desc": "Le attività scadono a un'ora specifica anziché a mezzanotte.", "feat_schedule_time_desc": "Le attività scadono a un'ora specifica anziché a mezzanotte.",
"schedule_time_toggle": "Scadenza a un orario preciso", "schedule_time_toggle": "Scadenza a un orario preciso",
@@ -199,6 +201,8 @@
"labels": "Etichette", "labels": "Etichette",
"labels_placeholder": "es. sicurezza, stagionale, visibile-inquilino", "labels_placeholder": "es. sicurezza, stagionale, visibile-inquilino",
"labels_help": "Tag separati da virgole per filtri e report.", "labels_help": "Tag separati da virgole per filtri e report.",
"task_mirror_todo": "Rispecchia nelle liste di cose da fare",
"task_mirror_todo_hint": "L'attività compare in queste liste finché è in scadenza; spuntarla lì la completa qui.",
"priority_low": "Bassa", "priority_low": "Bassa",
"priority_normal": "Normale", "priority_normal": "Normale",
"priority_high": "Alta", "priority_high": "Alta",
@@ -496,6 +500,8 @@
"settings_default_warning": "Giorni di avviso predefiniti", "settings_default_warning": "Giorni di avviso predefiniti",
"settings_consumable_threshold": "Soglia „consumabile basso“ (%)", "settings_consumable_threshold": "Soglia „consumabile basso“ (%)",
"settings_battery_low_percent": "Soglia „batteria scarica“ (%)", "settings_battery_low_percent": "Soglia „batteria scarica“ (%)",
"settings_battery_recovered_percent": "Batteria considerata sostituita sopra (%)",
"settings_battery_recovered_percent_hint": "Una batteria scarica resta conteggiata come scarica finché il livello non supera questo valore o non viene registrata una sostituzione — così un livello che oscilla attorno alla soglia non completa di continuo l'attività della flotta.",
"settings_battery_lifetimes": "Durate tipiche delle batterie", "settings_battery_lifetimes": "Durate tipiche delle batterie",
"settings_battery_lifetimes_hint": "Usato solo per batterie senza percentuale: una nota Battery Notes con solo tipo e data di sostituzione, o un sensore che segnala solo « scarica ». La scadenza è ultima sostituzione + questa durata. Le batterie che riportano un livello ricavano la previsione dalla scarica misurata. Dopo tre sostituzioni dello stesso tipo, l'intervallo mediano sostituisce il valore integrato — il tuo valore vince sempre.", "settings_battery_lifetimes_hint": "Usato solo per batterie senza percentuale: una nota Battery Notes con solo tipo e data di sostituzione, o un sensore che segnala solo « scarica ». La scadenza è ultima sostituzione + questa durata. Le batterie che riportano un livello ricavano la previsione dalla scarica misurata. Dopo tre sostituzioni dello stesso tipo, l'intervallo mediano sostituisce il valore integrato — il tuo valore vince sempre.",
"settings_battery_lifetime_months": "mesi", "settings_battery_lifetime_months": "mesi",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "nel tuo parco", "settings_battery_lifetime_in_fleet": "nel tuo parco",
"settings_battery_lifetime_learned_models": "Appreso per modello: {list}", "settings_battery_lifetime_learned_models": "Appreso per modello: {list}",
"settings_thresholds_hint": "Valori predefiniti per le nuove Configurazioni suggerite (percentuale residua) e per le batterie della flotta senza soglia Battery Notes propria. Le attività esistenti mantengono il loro valore.", "settings_thresholds_hint": "Valori predefiniti per le nuove Configurazioni suggerite (percentuale residua) e per le batterie della flotta senza soglia Battery Notes propria. Le attività esistenti mantengono il loro valore.",
"settings_part_search_url": "Link di ricerca per l'acquisto",
"settings_part_search_url_hint": "URL con {q} al posto dei termini di ricerca, usato per i ricambi senza link al prodotto. Lasciare vuoto per il negozio automatico (per paese, altrimenti per lingua).",
"settings_value_out_of_range": "Il valore deve essere compreso tra {min} e {max}", "settings_value_out_of_range": "Il valore deve essere compreso tra {min} e {max}",
"bn_summary": "{name}: {pct} % per {n} batterie", "bn_summary": "{name}: {pct} % per {n} batterie",
"bn_floor_decides": "La tua soglia del {floor} % decide per tutte; per ogni batteria conta la più alta delle due soglie.", "bn_floor_decides": "La tua soglia del {floor} % decide per tutte; per ogni batteria conta la più alta delle due soglie.",
@@ -717,6 +725,8 @@
"archived": "Archiviato", "archived": "Archiviato",
"show_archived": "Mostra archiviati", "show_archived": "Mostra archiviati",
"hide_archived": "Nascondi archiviati", "hide_archived": "Nascondi archiviati",
"section_collapse": "Comprimi sezione",
"section_expand": "Espandi sezione",
"confirm_archive_object": "Archiviare questo oggetto e le sue attività? La cronologia viene conservata e può essere ripristinata in seguito.", "confirm_archive_object": "Archiviare questo oggetto e le sue attività? La cronologia viene conservata e può essere ripristinata in seguito.",
"settings_archive": "Archiviazione e conservazione", "settings_archive": "Archiviazione e conservazione",
"settings_archive_desc": "Metti da parte le attività una tantum completate senza eliminarle. Gli elementi archiviati sono nascosti e inattivi, ma conservano cronologia e costi.", "settings_archive_desc": "Metti da parte le attività una tantum completate senza eliminarle. Gli elementi archiviati sono nascosti e inattivi, ma conservano cronologia e costi.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "日付が無効です", "ws_err_invalid_date": "日付が無効です",
"ws_err_invalid_format": "形式が無効です", "ws_err_invalid_format": "形式が無効です",
"ws_err_invalid_url": "リンクが無効です", "ws_err_invalid_url": "リンクが無効です",
"ws_err_invalid_mirror_todo": "無効なToDoリスト",
"ws_err_not_configured": "まだ設定されていません", "ws_err_not_configured": "まだ設定されていません",
"ws_err_not_loaded": "まだ読み込まれていません — しばらくしてからもう一度お試しください", "ws_err_not_loaded": "まだ読み込まれていません — しばらくしてからもう一度お試しください",
"ws_err_limit_reached": "上限に達しました", "ws_err_limit_reached": "上限に達しました",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "クイック完了の既定値が設定されていません", "ws_err_no_defaults": "クイック完了の既定値が設定されていません",
"ws_err_self_link_device": "オブジェクトを自分自身にリンクすることはできません", "ws_err_self_link_device": "オブジェクトを自分自身にリンクすることはできません",
"ws_err_too_early": "早すぎます — このタスクは期日が近づいてからのみ完了できます", "ws_err_too_early": "早すぎます — このタスクは期日が近づいてからのみ完了できます",
"ws_err_invalid_search_template": "検索リンクは {q} を含む http(s) URL である必要があります",
"feat_schedule_time": "時刻指定スケジュール", "feat_schedule_time": "時刻指定スケジュール",
"feat_schedule_time_desc": "タスクが深夜0時ではなく指定した時刻に期限超過となります。", "feat_schedule_time_desc": "タスクが深夜0時ではなく指定した時刻に期限超過となります。",
"schedule_time_toggle": "特定の時刻に期限", "schedule_time_toggle": "特定の時刻に期限",
@@ -201,6 +203,8 @@
"labels": "ラベル", "labels": "ラベル",
"labels_placeholder": "例:安全、季節、入居者に表示", "labels_placeholder": "例:安全、季節、入居者に表示",
"labels_help": "フィルタリングとレポート用のカンマ区切りタグ。", "labels_help": "フィルタリングとレポート用のカンマ区切りタグ。",
"task_mirror_todo": "ToDoリストにミラーする",
"task_mirror_todo_hint": "期限中はこれらのリストにタスクが表示され、そこで完了にするとここでも完了になります。",
"priority_low": "低", "priority_low": "低",
"priority_normal": "標準", "priority_normal": "標準",
"priority_high": "高", "priority_high": "高",
@@ -498,6 +502,8 @@
"settings_default_warning": "既定の警告日数", "settings_default_warning": "既定の警告日数",
"settings_consumable_threshold": "消耗品「残量少」しきい値(%)", "settings_consumable_threshold": "消耗品「残量少」しきい値(%)",
"settings_battery_low_percent": "電池「残量少」しきい値(%)", "settings_battery_low_percent": "電池「残量少」しきい値(%)",
"settings_battery_recovered_percent": "この値を超えたら交換済みとみなす(%)",
"settings_battery_recovered_percent_hint": "残量が少ない電池は、残量がこの値を超えるか交換が記録されるまで「残量少」として数えられます。しきい値付近で変動する残量が一括タスクを何度も完了させることを防ぎます。",
"settings_battery_lifetimes": "電池の標準寿命", "settings_battery_lifetimes": "電池の標準寿命",
"settings_battery_lifetimes_hint": "パーセント表示のない電池にのみ使います:種類と交換日だけの Battery Notes メモや「残量低下」しか報告しないセンサーです。期日は最終交換日+この寿命。残量を報告する電池は実測の放電から予測します。同じ種類の交換を3回記録すると、中央値の間隔が内蔵値に代わります。自分で設定した値が常に優先されます。", "settings_battery_lifetimes_hint": "パーセント表示のない電池にのみ使います:種類と交換日だけの Battery Notes メモや「残量低下」しか報告しないセンサーです。期日は最終交換日+この寿命。残量を報告する電池は実測の放電から予測します。同じ種類の交換を3回記録すると、中央値の間隔が内蔵値に代わります。自分で設定した値が常に優先されます。",
"settings_battery_lifetime_months": "か月", "settings_battery_lifetime_months": "か月",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "使用中", "settings_battery_lifetime_in_fleet": "使用中",
"settings_battery_lifetime_learned_models": "型番ごとの学習値:{list}", "settings_battery_lifetime_learned_models": "型番ごとの学習値:{list}",
"settings_thresholds_hint": "新しい「推奨セットアップ」(残量パーセント)と、独自の Battery Notes しきい値を持たないバッテリー一覧の電池に適用される既定値です。既存のタスクは値を保持します。", "settings_thresholds_hint": "新しい「推奨セットアップ」(残量パーセント)と、独自の Battery Notes しきい値を持たないバッテリー一覧の電池に適用される既定値です。既存のタスクは値を保持します。",
"settings_part_search_url": "購入検索リンク",
"settings_part_search_url_hint": "検索語の代わりに {q} を含む URL。製品リンクのない部品に使われます。空欄なら自動選択(国、次に言語で判定)。",
"settings_value_out_of_range": "値は {min} から {max} の間で指定してください", "settings_value_out_of_range": "値は {min} から {max} の間で指定してください",
"bn_summary": "{name}:{n} 個の電池に {pct} %", "bn_summary": "{name}:{n} 個の電池に {pct} %",
"bn_floor_decides": "あなたの {floor} % のしきい値がすべてに適用されます。電池ごとに高い方のしきい値が有効です。", "bn_floor_decides": "あなたの {floor} % のしきい値がすべてに適用されます。電池ごとに高い方のしきい値が有効です。",
@@ -717,6 +725,8 @@
"archived": "アーカイブ済み", "archived": "アーカイブ済み",
"show_archived": "アーカイブを表示", "show_archived": "アーカイブを表示",
"hide_archived": "アーカイブを非表示", "hide_archived": "アーカイブを非表示",
"section_collapse": "セクションを折りたたむ",
"section_expand": "セクションを展開する",
"confirm_archive_object": "このオブジェクトとそのタスクをアーカイブしますか?履歴は保持され、後で元に戻せます。", "confirm_archive_object": "このオブジェクトとそのタスクをアーカイブしますか?履歴は保持され、後で元に戻せます。",
"settings_archive": "アーカイブと保持", "settings_archive": "アーカイブと保持",
"settings_archive_desc": "完了した単発タスクを削除せずに片付けます。アーカイブされた項目は非表示で動作しませんが、履歴とコストは保持されます。", "settings_archive_desc": "完了した単発タスクを削除せずに片付けます。アーカイブされた項目は非表示で動作しませんが、履歴とコストは保持されます。",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "잘못된 날짜", "ws_err_invalid_date": "잘못된 날짜",
"ws_err_invalid_format": "잘못된 형식", "ws_err_invalid_format": "잘못된 형식",
"ws_err_invalid_url": "잘못된 링크", "ws_err_invalid_url": "잘못된 링크",
"ws_err_invalid_mirror_todo": "잘못된 할 일 목록",
"ws_err_not_configured": "아직 설정되지 않음", "ws_err_not_configured": "아직 설정되지 않음",
"ws_err_not_loaded": "아직 로드되지 않음 — 잠시 후 다시 시도하세요", "ws_err_not_loaded": "아직 로드되지 않음 — 잠시 후 다시 시도하세요",
"ws_err_limit_reached": "한도에 도달함", "ws_err_limit_reached": "한도에 도달함",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "빠른 완료 기본값이 설정되지 않음", "ws_err_no_defaults": "빠른 완료 기본값이 설정되지 않음",
"ws_err_self_link_device": "객체는 자기 자신에게 연결할 수 없음", "ws_err_self_link_device": "객체는 자기 자신에게 연결할 수 없음",
"ws_err_too_early": "너무 이름 — 이 작업은 기한에 가까워져야 완료할 수 있습니다", "ws_err_too_early": "너무 이름 — 이 작업은 기한에 가까워져야 완료할 수 있습니다",
"ws_err_invalid_search_template": "검색 링크는 {q}를 포함한 http(s) URL이어야 합니다",
"feat_schedule_time": "시각 지정 일정", "feat_schedule_time": "시각 지정 일정",
"feat_schedule_time_desc": "작업이 자정이 아닌 지정한 시각에 기한 초과로 전환됩니다.", "feat_schedule_time_desc": "작업이 자정이 아닌 지정한 시각에 기한 초과로 전환됩니다.",
"schedule_time_toggle": "특정 시각에 기한", "schedule_time_toggle": "특정 시각에 기한",
@@ -201,6 +203,8 @@
"labels": "라벨", "labels": "라벨",
"labels_placeholder": "예: 안전, 계절, 세입자용", "labels_placeholder": "예: 안전, 계절, 세입자용",
"labels_help": "필터링과 보고서에 쓰이는 쉼표로 구분된 태그입니다.", "labels_help": "필터링과 보고서에 쓰이는 쉼표로 구분된 태그입니다.",
"task_mirror_todo": "할 일 목록에 미러링",
"task_mirror_todo_hint": "작업이 예정된 동안 이 목록에 표시되며, 거기서 완료하면 여기서도 완료됩니다.",
"priority_low": "낮음", "priority_low": "낮음",
"priority_normal": "보통", "priority_normal": "보통",
"priority_high": "높음", "priority_high": "높음",
@@ -498,6 +502,8 @@
"settings_default_warning": "기본 경고 일수", "settings_default_warning": "기본 경고 일수",
"settings_consumable_threshold": "소모품 „부족“ 임계값 (%)", "settings_consumable_threshold": "소모품 „부족“ 임계값 (%)",
"settings_battery_low_percent": "배터리 „부족“ 임계값 (%)", "settings_battery_low_percent": "배터리 „부족“ 임계값 (%)",
"settings_battery_recovered_percent": "이 값 초과 시 배터리 교체됨으로 간주 (%)",
"settings_battery_recovered_percent_hint": "부족한 배터리는 잔량이 이 값을 초과하거나 교체가 기록될 때까지 부족으로 계속 집계됩니다. 임계값 근처에서 오르내리는 잔량이 배터리 일괄 작업을 반복 완료하지 못하게 합니다.",
"settings_battery_lifetimes": "배터리 일반 수명", "settings_battery_lifetimes": "배터리 일반 수명",
"settings_battery_lifetimes_hint": "백분율이 없는 배터리에만 사용됩니다: 종류와 교체일만 있는 Battery Notes 메모나 \"낮음\"만 알리는 센서입니다. 만기 = 마지막 교체 + 이 수명. 잔량을 보고하는 배터리는 실측 방전으로 예측합니다. 같은 종류의 교체를 3회 기록하면 중앙값 간격이 내장값을 대체합니다. 직접 설정한 값이 항상 우선합니다.", "settings_battery_lifetimes_hint": "백분율이 없는 배터리에만 사용됩니다: 종류와 교체일만 있는 Battery Notes 메모나 \"낮음\"만 알리는 센서입니다. 만기 = 마지막 교체 + 이 수명. 잔량을 보고하는 배터리는 실측 방전으로 예측합니다. 같은 종류의 교체를 3회 기록하면 중앙값 간격이 내장값을 대체합니다. 직접 설정한 값이 항상 우선합니다.",
"settings_battery_lifetime_months": "개월", "settings_battery_lifetime_months": "개월",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "내 장치에 사용 중", "settings_battery_lifetime_in_fleet": "내 장치에 사용 중",
"settings_battery_lifetime_learned_models": "모델별 학습값: {list}", "settings_battery_lifetime_learned_models": "모델별 학습값: {list}",
"settings_thresholds_hint": "새 추천 설정(남은 비율)과 자체 Battery Notes 임계값이 없는 배터리 목록 배터리의 기본값입니다. 기존 작업은 값을 유지합니다.", "settings_thresholds_hint": "새 추천 설정(남은 비율)과 자체 Battery Notes 임계값이 없는 배터리 목록 배터리의 기본값입니다. 기존 작업은 값을 유지합니다.",
"settings_part_search_url": "구매 검색 링크",
"settings_part_search_url_hint": "검색어 자리에 {q}가 들어가는 URL로, 제품 링크가 없는 부품에 사용됩니다. 비워 두면 자동 선택(국가, 그다음 언어 기준)됩니다.",
"settings_value_out_of_range": "값은 {min}에서 {max} 사이여야 합니다", "settings_value_out_of_range": "값은 {min}에서 {max} 사이여야 합니다",
"bn_summary": "{name}: 배터리 {n}개에 {pct} %", "bn_summary": "{name}: 배터리 {n}개에 {pct} %",
"bn_floor_decides": "당신의 {floor} % 임계값이 모두에 적용됩니다. 배터리마다 두 임계값 중 높은 쪽이 적용됩니다.", "bn_floor_decides": "당신의 {floor} % 임계값이 모두에 적용됩니다. 배터리마다 두 임계값 중 높은 쪽이 적용됩니다.",
@@ -723,6 +731,8 @@
"archived": "보관됨", "archived": "보관됨",
"show_archived": "보관된 항목 보기", "show_archived": "보관된 항목 보기",
"hide_archived": "보관된 항목 숨기기", "hide_archived": "보관된 항목 숨기기",
"section_collapse": "섹션 접기",
"section_expand": "섹션 펼치기",
"confirm_archive_object": "이 객체와 작업을 보관할까요? 기록은 유지되며 나중에 보관 해제할 수 있습니다.", "confirm_archive_object": "이 객체와 작업을 보관할까요? 기록은 유지되며 나중에 보관 해제할 수 있습니다.",
"settings_archive": "보관 및 보존", "settings_archive": "보관 및 보존",
"settings_archive_desc": "완료된 일회성 작업을 삭제하지 않고 정리합니다. 보관된 항목은 숨겨지고 동작하지 않지만 기록과 비용은 유지됩니다.", "settings_archive_desc": "완료된 일회성 작업을 삭제하지 않고 정리합니다. 보관된 항목은 숨겨지고 동작하지 않지만 기록과 비용은 유지됩니다.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "Ugyldig dato", "ws_err_invalid_date": "Ugyldig dato",
"ws_err_invalid_format": "Ugyldig format", "ws_err_invalid_format": "Ugyldig format",
"ws_err_invalid_url": "Ugyldig lenke", "ws_err_invalid_url": "Ugyldig lenke",
"ws_err_invalid_mirror_todo": "Ugyldig gjøremålsliste",
"ws_err_not_configured": "Ikke satt opp ennå", "ws_err_not_configured": "Ikke satt opp ennå",
"ws_err_not_loaded": "Ikke lastet ennå — prøv igjen om et øyeblikk", "ws_err_not_loaded": "Ikke lastet ennå — prøv igjen om et øyeblikk",
"ws_err_limit_reached": "Grensen er nådd", "ws_err_limit_reached": "Grensen er nådd",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "Ingen standardverdier for hurtigfullføring", "ws_err_no_defaults": "Ingen standardverdier for hurtigfullføring",
"ws_err_self_link_device": "Et objekt kan ikke kobles til seg selv", "ws_err_self_link_device": "Et objekt kan ikke kobles til seg selv",
"ws_err_too_early": "For tidlig — oppgaven kan først fullføres nærmere forfallsdatoen", "ws_err_too_early": "For tidlig — oppgaven kan først fullføres nærmere forfallsdatoen",
"ws_err_invalid_search_template": "Søkelenken må være en http(s)-URL som inneholder {q}",
"feat_schedule_time": "Planlegging med klokkeslett", "feat_schedule_time": "Planlegging med klokkeslett",
"feat_schedule_time_desc": "Oppgaver forfaller på et bestemt klokkeslett i stedet for ved midnatt.", "feat_schedule_time_desc": "Oppgaver forfaller på et bestemt klokkeslett i stedet for ved midnatt.",
"schedule_time_toggle": "Forfaller på et bestemt klokkeslett", "schedule_time_toggle": "Forfaller på et bestemt klokkeslett",
@@ -201,6 +203,8 @@
"labels": "Etiketter", "labels": "Etiketter",
"labels_placeholder": "f.eks. sikkerhet, sesong, synlig-for-leietaker", "labels_placeholder": "f.eks. sikkerhet, sesong, synlig-for-leietaker",
"labels_help": "Kommaseparerte etiketter for filtrering og rapporter.", "labels_help": "Kommaseparerte etiketter for filtrering og rapporter.",
"task_mirror_todo": "Speil til gjøremålslister",
"task_mirror_todo_hint": "Oppgaven vises i disse listene mens den er aktuell; krysses den av der, fullføres den her.",
"priority_low": "Lav", "priority_low": "Lav",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Høy", "priority_high": "Høy",
@@ -498,6 +502,8 @@
"settings_default_warning": "Standard varslingsdager", "settings_default_warning": "Standard varslingsdager",
"settings_consumable_threshold": "Terskel „forbruksvare lav“ (%)", "settings_consumable_threshold": "Terskel „forbruksvare lav“ (%)",
"settings_battery_low_percent": "Terskel „batteri lavt“ (%)", "settings_battery_low_percent": "Terskel „batteri lavt“ (%)",
"settings_battery_recovered_percent": "Batteri regnes som byttet over (%)",
"settings_battery_recovered_percent_hint": "Et lavt batteri telles som lavt til nivået stiger over denne verdien eller et bytte registreres — slik kan et nivå som svinger rundt terskelen ikke fullføre flåteoppgaven igjen og igjen.",
"settings_battery_lifetimes": "Typiske batterilevetider", "settings_battery_lifetimes": "Typiske batterilevetider",
"settings_battery_lifetimes_hint": "Brukes bare for batterier uten prosent: et Battery Notes-notat med bare type og byttedato, eller en sensor som bare melder «lavt». Forfall = siste bytte + denne levetiden. Batterier som melder nivå får prognosen fra målt utlading. Når flåten har sett tre bytter av en type, overtar medianintervallet fra den innebygde verdien — din egen verdi vinner alltid.", "settings_battery_lifetimes_hint": "Brukes bare for batterier uten prosent: et Battery Notes-notat med bare type og byttedato, eller en sensor som bare melder «lavt». Forfall = siste bytte + denne levetiden. Batterier som melder nivå får prognosen fra målt utlading. Når flåten har sett tre bytter av en type, overtar medianintervallet fra den innebygde verdien — din egen verdi vinner alltid.",
"settings_battery_lifetime_months": "måneder", "settings_battery_lifetime_months": "måneder",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "i flåten din", "settings_battery_lifetime_in_fleet": "i flåten din",
"settings_battery_lifetime_learned_models": "Lært per modell: {list}", "settings_battery_lifetime_learned_models": "Lært per modell: {list}",
"settings_thresholds_hint": "Standardverdier for nye Foreslåtte oppsett (gjenværende prosent) og for flåtebatterier uten egen Battery Notes-terskel. Eksisterende oppgaver beholder verdien sin.", "settings_thresholds_hint": "Standardverdier for nye Foreslåtte oppsett (gjenværende prosent) og for flåtebatterier uten egen Battery Notes-terskel. Eksisterende oppgaver beholder verdien sin.",
"settings_part_search_url": "Søkelenke for innkjøp",
"settings_part_search_url_hint": "URL med {q} i stedet for søkeordene, for deler uten produktlenke. La stå tomt for den automatiske butikken (etter land, ellers språk).",
"settings_value_out_of_range": "Verdien må være mellom {min} og {max}", "settings_value_out_of_range": "Verdien må være mellom {min} og {max}",
"bn_summary": "{name}: {pct} % for {n} batterier", "bn_summary": "{name}: {pct} % for {n} batterier",
"bn_floor_decides": "Din terskel på {floor} % avgjør for alle; per batteri gjelder den høyeste av de to tersklene.", "bn_floor_decides": "Din terskel på {floor} % avgjør for alle; per batteri gjelder den høyeste av de to tersklene.",
@@ -717,6 +725,8 @@
"archived": "Arkivert", "archived": "Arkivert",
"show_archived": "Vis arkiverte", "show_archived": "Vis arkiverte",
"hide_archived": "Skjul arkiverte", "hide_archived": "Skjul arkiverte",
"section_collapse": "Fold sammen seksjonen",
"section_expand": "Fold ut seksjonen",
"confirm_archive_object": "Arkivere dette objektet og oppgavene? Historikken beholdes og kan gjenopprettes senere.", "confirm_archive_object": "Arkivere dette objektet og oppgavene? Historikken beholdes og kan gjenopprettes senere.",
"settings_archive": "Arkiv og oppbevaring", "settings_archive": "Arkiv og oppbevaring",
"settings_archive_desc": "Legg bort fullførte engangsoppgaver uten å slette dem. Arkiverte elementer er skjult og inaktive, men beholder historikk og kostnad.", "settings_archive_desc": "Legg bort fullførte engangsoppgaver uten å slette dem. Arkiverte elementer er skjult og inaktive, men beholder historikk og kostnad.",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Ongeldige datum", "ws_err_invalid_date": "Ongeldige datum",
"ws_err_invalid_format": "Ongeldig formaat", "ws_err_invalid_format": "Ongeldig formaat",
"ws_err_invalid_url": "Ongeldige link", "ws_err_invalid_url": "Ongeldige link",
"ws_err_invalid_mirror_todo": "Ongeldige takenlijst",
"ws_err_not_configured": "Nog niet ingesteld", "ws_err_not_configured": "Nog niet ingesteld",
"ws_err_not_loaded": "Nog niet geladen — probeer het zo opnieuw", "ws_err_not_loaded": "Nog niet geladen — probeer het zo opnieuw",
"ws_err_limit_reached": "Limiet bereikt", "ws_err_limit_reached": "Limiet bereikt",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "Geen standaardwaarden voor snel afronden ingesteld", "ws_err_no_defaults": "Geen standaardwaarden voor snel afronden ingesteld",
"ws_err_self_link_device": "Een object kan niet aan zichzelf worden gekoppeld", "ws_err_self_link_device": "Een object kan niet aan zichzelf worden gekoppeld",
"ws_err_too_early": "Te vroeg — deze taak kan pas dichter bij de vervaldatum worden afgerond", "ws_err_too_early": "Te vroeg — deze taak kan pas dichter bij de vervaldatum worden afgerond",
"ws_err_invalid_search_template": "De zoeklink moet een http(s)-URL met {q} zijn",
"feat_schedule_time": "Tijd-van-dag-planning", "feat_schedule_time": "Tijd-van-dag-planning",
"feat_schedule_time_desc": "Taken vervallen op een specifieke tijd in plaats van middernacht.", "feat_schedule_time_desc": "Taken vervallen op een specifieke tijd in plaats van middernacht.",
"schedule_time_toggle": "Vervalt op een vast tijdstip", "schedule_time_toggle": "Vervalt op een vast tijdstip",
@@ -199,6 +201,8 @@
"labels": "Labels", "labels": "Labels",
"labels_placeholder": "bijv. veiligheid, seizoensgebonden, zichtbaar-voor-huurder", "labels_placeholder": "bijv. veiligheid, seizoensgebonden, zichtbaar-voor-huurder",
"labels_help": "Kommagescheiden tags voor filteren en rapportages.", "labels_help": "Kommagescheiden tags voor filteren en rapportages.",
"task_mirror_todo": "Spiegelen naar takenlijsten",
"task_mirror_todo_hint": "De taak verschijnt in deze lijsten zolang ze te doen is; afvinken daar voltooit ze hier.",
"priority_low": "Laag", "priority_low": "Laag",
"priority_normal": "Normaal", "priority_normal": "Normaal",
"priority_high": "Hoog", "priority_high": "Hoog",
@@ -496,6 +500,8 @@
"settings_default_warning": "Standaard waarschuwingsdagen", "settings_default_warning": "Standaard waarschuwingsdagen",
"settings_consumable_threshold": "Drempel „verbruiksartikel laag“ (%)", "settings_consumable_threshold": "Drempel „verbruiksartikel laag“ (%)",
"settings_battery_low_percent": "Drempel „batterij laag“ (%)", "settings_battery_low_percent": "Drempel „batterij laag“ (%)",
"settings_battery_recovered_percent": "Batterij geldt als vervangen boven (%)",
"settings_battery_recovered_percent_hint": "Een lege batterij blijft als laag geteld tot het niveau boven deze waarde stijgt of een vervanging wordt vastgelegd — zo kan een niveau dat rond de drempel schommelt de vloottaak niet steeds opnieuw afronden.",
"settings_battery_lifetimes": "Gebruikelijke batterijlevensduur", "settings_battery_lifetimes": "Gebruikelijke batterijlevensduur",
"settings_battery_lifetimes_hint": "Alleen gebruikt voor batterijen zonder percentage: een Battery Notes-notitie met enkel een type en een vervangdatum, of een sensor die alleen „bijna leeg“ meldt. Hun vervaldatum is laatste vervanging + deze levensduur. Batterijen die een niveau melden krijgen hun voorspelling uit de gemeten ontlading. Zodra de vloot drie vervangingen van een type heeft gezien, vervangt het mediane interval de ingebouwde waarde — je eigen waarde wint altijd.", "settings_battery_lifetimes_hint": "Alleen gebruikt voor batterijen zonder percentage: een Battery Notes-notitie met enkel een type en een vervangdatum, of een sensor die alleen „bijna leeg“ meldt. Hun vervaldatum is laatste vervanging + deze levensduur. Batterijen die een niveau melden krijgen hun voorspelling uit de gemeten ontlading. Zodra de vloot drie vervangingen van een type heeft gezien, vervangt het mediane interval de ingebouwde waarde — je eigen waarde wint altijd.",
"settings_battery_lifetime_months": "maanden", "settings_battery_lifetime_months": "maanden",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "in je vloot", "settings_battery_lifetime_in_fleet": "in je vloot",
"settings_battery_lifetime_learned_models": "Geleerd per model: {list}", "settings_battery_lifetime_learned_models": "Geleerd per model: {list}",
"settings_thresholds_hint": "Standaardwaarden voor nieuwe Voorgestelde installaties (resterend percentage) en voor vlootbatterijen zonder eigen Battery Notes-drempel. Bestaande taken behouden hun waarde.", "settings_thresholds_hint": "Standaardwaarden voor nieuwe Voorgestelde installaties (resterend percentage) en voor vlootbatterijen zonder eigen Battery Notes-drempel. Bestaande taken behouden hun waarde.",
"settings_part_search_url": "Zoeklink voor aankopen",
"settings_part_search_url_hint": "URL met {q} op de plaats van de zoektermen, voor onderdelen zonder productlink. Leeg laten voor de automatische winkel (per land, anders per taal).",
"settings_value_out_of_range": "De waarde moet tussen {min} en {max} liggen", "settings_value_out_of_range": "De waarde moet tussen {min} en {max} liggen",
"bn_summary": "{name}: {pct} % voor {n} batterijen", "bn_summary": "{name}: {pct} % voor {n} batterijen",
"bn_floor_decides": "Jouw drempel van {floor} % beslist voor allemaal; per batterij telt de hoogste van de twee drempels.", "bn_floor_decides": "Jouw drempel van {floor} % beslist voor allemaal; per batterij telt de hoogste van de twee drempels.",
@@ -717,6 +725,8 @@
"archived": "Gearchiveerd", "archived": "Gearchiveerd",
"show_archived": "Gearchiveerde tonen", "show_archived": "Gearchiveerde tonen",
"hide_archived": "Gearchiveerde verbergen", "hide_archived": "Gearchiveerde verbergen",
"section_collapse": "Sectie inklappen",
"section_expand": "Sectie uitklappen",
"confirm_archive_object": "Dit object en zijn taken archiveren? De geschiedenis blijft behouden en kan later worden hersteld.", "confirm_archive_object": "Dit object en zijn taken archiveren? De geschiedenis blijft behouden en kan later worden hersteld.",
"settings_archive": "Archief & bewaring", "settings_archive": "Archief & bewaring",
"settings_archive_desc": "Voltooide eenmalige taken archiveren in plaats van verwijderen. Gearchiveerde items zijn verborgen en inactief, maar behouden geschiedenis en kosten.", "settings_archive_desc": "Voltooide eenmalige taken archiveren in plaats van verwijderen. Gearchiveerde items zijn verborgen en inactief, maar behouden geschiedenis en kosten.",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Nieprawidłowa data", "ws_err_invalid_date": "Nieprawidłowa data",
"ws_err_invalid_format": "Nieprawidłowy format", "ws_err_invalid_format": "Nieprawidłowy format",
"ws_err_invalid_url": "Nieprawidłowy link", "ws_err_invalid_url": "Nieprawidłowy link",
"ws_err_invalid_mirror_todo": "Nieprawidłowa lista zadań",
"ws_err_not_configured": "Jeszcze nie skonfigurowano", "ws_err_not_configured": "Jeszcze nie skonfigurowano",
"ws_err_not_loaded": "Jeszcze nie załadowano — spróbuj ponownie za chwilę", "ws_err_not_loaded": "Jeszcze nie załadowano — spróbuj ponownie za chwilę",
"ws_err_limit_reached": "Osiągnięto limit", "ws_err_limit_reached": "Osiągnięto limit",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "Brak domyślnych wartości szybkiego ukończenia", "ws_err_no_defaults": "Brak domyślnych wartości szybkiego ukończenia",
"ws_err_self_link_device": "Obiekt nie może być powiązany sam ze sobą", "ws_err_self_link_device": "Obiekt nie może być powiązany sam ze sobą",
"ws_err_too_early": "Za wcześnie — to zadanie można ukończyć dopiero bliżej terminu", "ws_err_too_early": "Za wcześnie — to zadanie można ukończyć dopiero bliżej terminu",
"ws_err_invalid_search_template": "Link wyszukiwania musi być adresem URL http(s) zawierającym {q}",
"feat_schedule_time": "Harmonogram według pory dnia", "feat_schedule_time": "Harmonogram według pory dnia",
"feat_schedule_time_desc": "Zadania stają się zaległe o określonej porze dnia zamiast o północy.", "feat_schedule_time_desc": "Zadania stają się zaległe o określonej porze dnia zamiast o północy.",
"schedule_time_toggle": "Termin o określonej godzinie", "schedule_time_toggle": "Termin o określonej godzinie",
@@ -199,6 +201,8 @@
"labels": "Etykiety", "labels": "Etykiety",
"labels_placeholder": "np. bezpieczeństwo, sezonowe, widoczne-dla-najemcy", "labels_placeholder": "np. bezpieczeństwo, sezonowe, widoczne-dla-najemcy",
"labels_help": "Tagi rozdzielone przecinkami do filtrowania i raportów.", "labels_help": "Tagi rozdzielone przecinkami do filtrowania i raportów.",
"task_mirror_todo": "Odzwierciedlaj na listach zadań",
"task_mirror_todo_hint": "Zadanie pojawia się na tych listach, dopóki jest do zrobienia; odhaczenie go tam kończy je tutaj.",
"priority_low": "Niski", "priority_low": "Niski",
"priority_normal": "Normalny", "priority_normal": "Normalny",
"priority_high": "Wysoki", "priority_high": "Wysoki",
@@ -496,6 +500,8 @@
"settings_default_warning": "Domyślne dni ostrzeżenia", "settings_default_warning": "Domyślne dni ostrzeżenia",
"settings_consumable_threshold": "Próg „materiał eksploatacyjny niski” (%)", "settings_consumable_threshold": "Próg „materiał eksploatacyjny niski” (%)",
"settings_battery_low_percent": "Próg „bateria słaba” (%)", "settings_battery_low_percent": "Próg „bateria słaba” (%)",
"settings_battery_recovered_percent": "Bateria uznana za wymienioną powyżej (%)",
"settings_battery_recovered_percent_hint": "Słaba bateria pozostaje liczona jako słaba, dopóki jej poziom nie wzrośnie powyżej tej wartości lub nie zostanie zapisana wymiana — poziom oscylujący wokół progu nie kończy więc zadania floty raz za razem.",
"settings_battery_lifetimes": "Typowa żywotność baterii", "settings_battery_lifetimes": "Typowa żywotność baterii",
"settings_battery_lifetimes_hint": "Używane tylko dla baterii bez procentu: notatka Battery Notes z samym typem i datą wymiany albo czujnik zgłaszający tylko „niski”. Termin = ostatnia wymiana + ta żywotność. Baterie raportujące poziom dostają prognozę z mierzonego rozładowania. Po trzech wymianach danego typu mediana odstępów zastępuje wbudowaną wartość — Twoja wartość zawsze wygrywa.", "settings_battery_lifetimes_hint": "Używane tylko dla baterii bez procentu: notatka Battery Notes z samym typem i datą wymiany albo czujnik zgłaszający tylko „niski”. Termin = ostatnia wymiana + ta żywotność. Baterie raportujące poziom dostają prognozę z mierzonego rozładowania. Po trzech wymianach danego typu mediana odstępów zastępuje wbudowaną wartość — Twoja wartość zawsze wygrywa.",
"settings_battery_lifetime_months": "mies.", "settings_battery_lifetime_months": "mies.",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "w Twojej flocie", "settings_battery_lifetime_in_fleet": "w Twojej flocie",
"settings_battery_lifetime_learned_models": "Nauczone według modelu: {list}", "settings_battery_lifetime_learned_models": "Nauczone według modelu: {list}",
"settings_thresholds_hint": "Wartości domyślne dla nowych Sugerowanych konfiguracji (procent pozostały) i dla baterii floty bez własnego progu Battery Notes. Istniejące zadania zachowują swoją wartość.", "settings_thresholds_hint": "Wartości domyślne dla nowych Sugerowanych konfiguracji (procent pozostały) i dla baterii floty bez własnego progu Battery Notes. Istniejące zadania zachowują swoją wartość.",
"settings_part_search_url": "Link wyszukiwania zakupów",
"settings_part_search_url_hint": "Adres URL z {q} w miejscu wyszukiwanych słów, dla części bez linku do produktu. Pozostaw puste dla automatycznego sklepu (według kraju, w przeciwnym razie języka).",
"settings_value_out_of_range": "Wartość musi mieścić się w zakresie od {min} do {max}", "settings_value_out_of_range": "Wartość musi mieścić się w zakresie od {min} do {max}",
"bn_summary": "{name}: {pct} % dla {n} baterii", "bn_summary": "{name}: {pct} % dla {n} baterii",
"bn_floor_decides": "Twój próg {floor} % decyduje dla wszystkich; dla każdej baterii liczy się wyższy z dwóch progów.", "bn_floor_decides": "Twój próg {floor} % decyduje dla wszystkich; dla każdej baterii liczy się wyższy z dwóch progów.",
@@ -717,6 +725,8 @@
"archived": "Zarchiwizowane", "archived": "Zarchiwizowane",
"show_archived": "Pokaż zarchiwizowane", "show_archived": "Pokaż zarchiwizowane",
"hide_archived": "Ukryj zarchiwizowane", "hide_archived": "Ukryj zarchiwizowane",
"section_collapse": "Zwiń sekcję",
"section_expand": "Rozwiń sekcję",
"confirm_archive_object": "Zarchiwizować ten obiekt i jego zadania? Historia zostanie zachowana i można ją później przywrócić.", "confirm_archive_object": "Zarchiwizować ten obiekt i jego zadania? Historia zostanie zachowana i można ją później przywrócić.",
"settings_archive": "Archiwum i przechowywanie", "settings_archive": "Archiwum i przechowywanie",
"settings_archive_desc": "Odkładaj ukończone zadania jednorazowe bez usuwania. Zarchiwizowane elementy są ukryte i nieaktywne, ale zachowują historię i koszty.", "settings_archive_desc": "Odkładaj ukończone zadania jednorazowe bez usuwania. Zarchiwizowane elementy są ukryte i nieaktywne, ale zachowują historię i koszty.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "Data inválida", "ws_err_invalid_date": "Data inválida",
"ws_err_invalid_format": "Formato inválido", "ws_err_invalid_format": "Formato inválido",
"ws_err_invalid_url": "Link inválido", "ws_err_invalid_url": "Link inválido",
"ws_err_invalid_mirror_todo": "Lista de tarefas inválida",
"ws_err_not_configured": "Ainda não configurado", "ws_err_not_configured": "Ainda não configurado",
"ws_err_not_loaded": "Ainda não carregado — tente novamente em instantes", "ws_err_not_loaded": "Ainda não carregado — tente novamente em instantes",
"ws_err_limit_reached": "Limite atingido", "ws_err_limit_reached": "Limite atingido",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "Sem padrões para conclusão rápida", "ws_err_no_defaults": "Sem padrões para conclusão rápida",
"ws_err_self_link_device": "Um objeto não pode ser vinculado a si mesmo", "ws_err_self_link_device": "Um objeto não pode ser vinculado a si mesmo",
"ws_err_too_early": "Cedo demais — esta tarefa só pode ser concluída mais perto do vencimento", "ws_err_too_early": "Cedo demais — esta tarefa só pode ser concluída mais perto do vencimento",
"ws_err_invalid_search_template": "O link de busca deve ser uma URL http(s) contendo {q}",
"feat_schedule_time": "Agendamento por horário", "feat_schedule_time": "Agendamento por horário",
"feat_schedule_time_desc": "As tarefas ficam atrasadas em um horário específico do dia, em vez de à meia-noite.", "feat_schedule_time_desc": "As tarefas ficam atrasadas em um horário específico do dia, em vez de à meia-noite.",
"schedule_time_toggle": "Vence em um horário específico", "schedule_time_toggle": "Vence em um horário específico",
@@ -201,6 +203,8 @@
"labels": "Etiquetas", "labels": "Etiquetas",
"labels_placeholder": "ex.: segurança, sazonal, visível ao inquilino", "labels_placeholder": "ex.: segurança, sazonal, visível ao inquilino",
"labels_help": "Tags separadas por vírgula para filtragem e relatórios.", "labels_help": "Tags separadas por vírgula para filtragem e relatórios.",
"task_mirror_todo": "Espelhar nas listas de tarefas",
"task_mirror_todo_hint": "A tarefa aparece nessas listas enquanto estiver pendente; marcá-la lá a conclui aqui.",
"priority_low": "Baixa", "priority_low": "Baixa",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Alta", "priority_high": "Alta",
@@ -498,6 +502,8 @@
"settings_default_warning": "Dias de aviso padrão", "settings_default_warning": "Dias de aviso padrão",
"settings_consumable_threshold": "Limite „consumível baixo“ (%)", "settings_consumable_threshold": "Limite „consumível baixo“ (%)",
"settings_battery_low_percent": "Limite „pilha fraca“ (%)", "settings_battery_low_percent": "Limite „pilha fraca“ (%)",
"settings_battery_recovered_percent": "Pilha considerada trocada acima de (%)",
"settings_battery_recovered_percent_hint": "Uma pilha fraca continua contando como fraca até o nível subir acima deste valor ou uma troca ser registrada — assim um nível oscilando em torno do limite não conclui a tarefa da frota repetidamente.",
"settings_battery_lifetimes": "Vida útil típica das pilhas", "settings_battery_lifetimes": "Vida útil típica das pilhas",
"settings_battery_lifetimes_hint": "Usado apenas para pilhas sem porcentagem: uma nota do Battery Notes só com tipo e data de troca, ou um sensor que apenas informa « fraca ». O vencimento é última troca + esta vida útil. Pilhas que informam nível têm a previsão pela descarga medida. Após três trocas de um tipo, o intervalo mediano substitui o valor integrado — seu valor sempre vence.", "settings_battery_lifetimes_hint": "Usado apenas para pilhas sem porcentagem: uma nota do Battery Notes só com tipo e data de troca, ou um sensor que apenas informa « fraca ». O vencimento é última troca + esta vida útil. Pilhas que informam nível têm a previsão pela descarga medida. Após três trocas de um tipo, o intervalo mediano substitui o valor integrado — seu valor sempre vence.",
"settings_battery_lifetime_months": "meses", "settings_battery_lifetime_months": "meses",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "na sua frota", "settings_battery_lifetime_in_fleet": "na sua frota",
"settings_battery_lifetime_learned_models": "Aprendido por modelo: {list}", "settings_battery_lifetime_learned_models": "Aprendido por modelo: {list}",
"settings_thresholds_hint": "Padrões para novas Configurações sugeridas (porcentagem restante) e para pilhas da frota sem limite próprio do Battery Notes. As tarefas existentes mantêm seu valor.", "settings_thresholds_hint": "Padrões para novas Configurações sugeridas (porcentagem restante) e para pilhas da frota sem limite próprio do Battery Notes. As tarefas existentes mantêm seu valor.",
"settings_part_search_url": "Link de busca para compra",
"settings_part_search_url_hint": "URL com {q} no lugar dos termos de busca, usada para peças sem link de produto. Deixe vazio para a loja automática (por país, senão por idioma).",
"settings_value_out_of_range": "O valor deve estar entre {min} e {max}", "settings_value_out_of_range": "O valor deve estar entre {min} e {max}",
"bn_summary": "{name}: {pct} % para {n} pilhas", "bn_summary": "{name}: {pct} % para {n} pilhas",
"bn_floor_decides": "Seu limite de {floor} % decide para todas; por pilha vale o maior dos dois limites.", "bn_floor_decides": "Seu limite de {floor} % decide para todas; por pilha vale o maior dos dois limites.",
@@ -723,6 +731,8 @@
"archived": "Arquivada", "archived": "Arquivada",
"show_archived": "Mostrar arquivados", "show_archived": "Mostrar arquivados",
"hide_archived": "Ocultar arquivados", "hide_archived": "Ocultar arquivados",
"section_collapse": "Recolher seção",
"section_expand": "Expandir seção",
"confirm_archive_object": "Arquivar este objeto e suas tarefas? Eles mantêm o histórico e podem ser desarquivados depois.", "confirm_archive_object": "Arquivar este objeto e suas tarefas? Eles mantêm o histórico e podem ser desarquivados depois.",
"settings_archive": "Arquivamento e retenção", "settings_archive": "Arquivamento e retenção",
"settings_archive_desc": "Aposente tarefas únicas concluídas sem excluí-las. Itens arquivados ficam ocultos e inativos, mas mantêm o histórico e o custo.", "settings_archive_desc": "Aposente tarefas únicas concluídas sem excluí-las. Itens arquivados ficam ocultos e inativos, mas mantêm o histórico e o custo.",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Data inválida", "ws_err_invalid_date": "Data inválida",
"ws_err_invalid_format": "Formato inválido", "ws_err_invalid_format": "Formato inválido",
"ws_err_invalid_url": "Ligação inválida", "ws_err_invalid_url": "Ligação inválida",
"ws_err_invalid_mirror_todo": "Lista de tarefas inválida",
"ws_err_not_configured": "Ainda não configurado", "ws_err_not_configured": "Ainda não configurado",
"ws_err_not_loaded": "Ainda não carregado — tente novamente daqui a pouco", "ws_err_not_loaded": "Ainda não carregado — tente novamente daqui a pouco",
"ws_err_limit_reached": "Limite atingido", "ws_err_limit_reached": "Limite atingido",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "Sem predefinições para conclusão rápida", "ws_err_no_defaults": "Sem predefinições para conclusão rápida",
"ws_err_self_link_device": "Um objeto não pode ser ligado a si próprio", "ws_err_self_link_device": "Um objeto não pode ser ligado a si próprio",
"ws_err_too_early": "Demasiado cedo — esta tarefa só pode ser concluída mais perto do prazo", "ws_err_too_early": "Demasiado cedo — esta tarefa só pode ser concluída mais perto do prazo",
"ws_err_invalid_search_template": "A ligação de pesquisa tem de ser um URL http(s) com {q}",
"feat_schedule_time": "Agendamento por hora", "feat_schedule_time": "Agendamento por hora",
"feat_schedule_time_desc": "Tarefas vencem em um horário específico em vez de meia-noite.", "feat_schedule_time_desc": "Tarefas vencem em um horário específico em vez de meia-noite.",
"schedule_time_toggle": "Vence a uma hora específica", "schedule_time_toggle": "Vence a uma hora específica",
@@ -199,6 +201,8 @@
"labels": "Etiquetas", "labels": "Etiquetas",
"labels_placeholder": "p. ex. segurança, sazonal, visível-inquilino", "labels_placeholder": "p. ex. segurança, sazonal, visível-inquilino",
"labels_help": "Etiquetas separadas por vírgulas para filtragem e relatórios.", "labels_help": "Etiquetas separadas por vírgulas para filtragem e relatórios.",
"task_mirror_todo": "Espelhar em listas de tarefas",
"task_mirror_todo_hint": "A tarefa aparece nestas listas enquanto estiver pendente; marcá-la lá conclui-a aqui.",
"priority_low": "Baixa", "priority_low": "Baixa",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Alta", "priority_high": "Alta",
@@ -496,6 +500,8 @@
"settings_default_warning": "Dias de aviso predefinidos", "settings_default_warning": "Dias de aviso predefinidos",
"settings_consumable_threshold": "Limiar „consumível baixo“ (%)", "settings_consumable_threshold": "Limiar „consumível baixo“ (%)",
"settings_battery_low_percent": "Limiar „pilha fraca“ (%)", "settings_battery_low_percent": "Limiar „pilha fraca“ (%)",
"settings_battery_recovered_percent": "Pilha considerada substituída acima de (%)",
"settings_battery_recovered_percent_hint": "Uma pilha fraca continua a contar como fraca até o nível subir acima deste valor ou ser registada uma substituição — assim, um nível que oscila em torno do limiar não conclui a tarefa da frota vezes sem conta.",
"settings_battery_lifetimes": "Durações típicas das pilhas", "settings_battery_lifetimes": "Durações típicas das pilhas",
"settings_battery_lifetimes_hint": "Usado apenas para pilhas sem percentagem: uma nota do Battery Notes só com tipo e data de substituição, ou um sensor que apenas reporta « fraca ». O vencimento é última substituição + esta duração. Pilhas que reportam nível obtêm a previsão da descarga medida. Após três substituições de um tipo, o intervalo mediano substitui o valor integrado — o seu valor ganha sempre.", "settings_battery_lifetimes_hint": "Usado apenas para pilhas sem percentagem: uma nota do Battery Notes só com tipo e data de substituição, ou um sensor que apenas reporta « fraca ». O vencimento é última substituição + esta duração. Pilhas que reportam nível obtêm a previsão da descarga medida. Após três substituições de um tipo, o intervalo mediano substitui o valor integrado — o seu valor ganha sempre.",
"settings_battery_lifetime_months": "meses", "settings_battery_lifetime_months": "meses",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "na sua frota", "settings_battery_lifetime_in_fleet": "na sua frota",
"settings_battery_lifetime_learned_models": "Aprendido por modelo: {list}", "settings_battery_lifetime_learned_models": "Aprendido por modelo: {list}",
"settings_thresholds_hint": "Predefinições para novas Configurações sugeridas (percentagem restante) e para pilhas da frota sem limiar Battery Notes próprio. As tarefas existentes mantêm o seu valor.", "settings_thresholds_hint": "Predefinições para novas Configurações sugeridas (percentagem restante) e para pilhas da frota sem limiar Battery Notes próprio. As tarefas existentes mantêm o seu valor.",
"settings_part_search_url": "Ligação de pesquisa de compra",
"settings_part_search_url_hint": "URL com {q} no lugar dos termos de pesquisa, usada para peças sem ligação de produto. Deixar vazio para a loja automática (por país, senão por idioma).",
"settings_value_out_of_range": "O valor tem de estar entre {min} e {max}", "settings_value_out_of_range": "O valor tem de estar entre {min} e {max}",
"bn_summary": "{name}: {pct} % para {n} pilhas", "bn_summary": "{name}: {pct} % para {n} pilhas",
"bn_floor_decides": "O teu limiar de {floor} % decide para todas; por pilha conta o mais alto dos dois limiares.", "bn_floor_decides": "O teu limiar de {floor} % decide para todas; por pilha conta o mais alto dos dois limiares.",
@@ -717,6 +725,8 @@
"archived": "Arquivado", "archived": "Arquivado",
"show_archived": "Mostrar arquivados", "show_archived": "Mostrar arquivados",
"hide_archived": "Ocultar arquivados", "hide_archived": "Ocultar arquivados",
"section_collapse": "Recolher secção",
"section_expand": "Expandir secção",
"confirm_archive_object": "Arquivar este objeto e as suas tarefas? O histórico é mantido e pode ser restaurado mais tarde.", "confirm_archive_object": "Arquivar este objeto e as suas tarefas? O histórico é mantido e pode ser restaurado mais tarde.",
"settings_archive": "Arquivo e retenção", "settings_archive": "Arquivo e retenção",
"settings_archive_desc": "Retire tarefas únicas concluídas sem as eliminar. Os itens arquivados ficam ocultos e inativos, mas mantêm histórico e custos.", "settings_archive_desc": "Retire tarefas únicas concluídas sem as eliminar. Os itens arquivados ficam ocultos e inativos, mas mantêm histórico e custos.",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Недопустимая дата", "ws_err_invalid_date": "Недопустимая дата",
"ws_err_invalid_format": "Недопустимый формат", "ws_err_invalid_format": "Недопустимый формат",
"ws_err_invalid_url": "Недопустимая ссылка", "ws_err_invalid_url": "Недопустимая ссылка",
"ws_err_invalid_mirror_todo": "Недопустимый список дел",
"ws_err_not_configured": "Ещё не настроено", "ws_err_not_configured": "Ещё не настроено",
"ws_err_not_loaded": "Ещё не загружено — попробуйте чуть позже", "ws_err_not_loaded": "Ещё не загружено — попробуйте чуть позже",
"ws_err_limit_reached": "Достигнут предел", "ws_err_limit_reached": "Достигнут предел",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "Не заданы значения по умолчанию для быстрого завершения", "ws_err_no_defaults": "Не заданы значения по умолчанию для быстрого завершения",
"ws_err_self_link_device": "Объект нельзя связать с самим собой", "ws_err_self_link_device": "Объект нельзя связать с самим собой",
"ws_err_too_early": "Слишком рано — эту задачу можно завершить только ближе к сроку", "ws_err_too_early": "Слишком рано — эту задачу можно завершить только ближе к сроку",
"ws_err_invalid_search_template": "Ссылка для поиска должна быть URL http(s) с {q}",
"feat_schedule_time": "Планирование по времени дня", "feat_schedule_time": "Планирование по времени дня",
"feat_schedule_time_desc": "Задачи становятся просроченными в определённое время дня, а не в полночь.", "feat_schedule_time_desc": "Задачи становятся просроченными в определённое время дня, а не в полночь.",
"schedule_time_toggle": "Срок в определённое время", "schedule_time_toggle": "Срок в определённое время",
@@ -199,6 +201,8 @@
"labels": "Метки", "labels": "Метки",
"labels_placeholder": "напр. безопасность, сезонное, видно-арендатору", "labels_placeholder": "напр. безопасность, сезонное, видно-арендатору",
"labels_help": "Теги через запятую для фильтрации и отчётов.", "labels_help": "Теги через запятую для фильтрации и отчётов.",
"task_mirror_todo": "Отражать в списках дел",
"task_mirror_todo_hint": "Задача появляется в этих списках, пока она актуальна; отметка там завершает её здесь.",
"priority_low": "Низкий", "priority_low": "Низкий",
"priority_normal": "Обычный", "priority_normal": "Обычный",
"priority_high": "Высокий", "priority_high": "Высокий",
@@ -496,6 +500,8 @@
"settings_default_warning": "Дни предупреждения по умолчанию", "settings_default_warning": "Дни предупреждения по умолчанию",
"settings_consumable_threshold": "Порог «расходник заканчивается» (%)", "settings_consumable_threshold": "Порог «расходник заканчивается» (%)",
"settings_battery_low_percent": "Порог «батарея разряжена» (%)", "settings_battery_low_percent": "Порог «батарея разряжена» (%)",
"settings_battery_recovered_percent": "Батарея считается заменённой выше (%)",
"settings_battery_recovered_percent_hint": "Разряженная батарея считается разряженной, пока её уровень не поднимется выше этого значения или не будет записана замена — уровень, колеблющийся около порога, больше не завершает задачу парка снова и снова.",
"settings_battery_lifetimes": "Типичный срок службы батарей", "settings_battery_lifetimes": "Типичный срок службы батарей",
"settings_battery_lifetimes_hint": "Используется только для батарей без процента: заметка Battery Notes лишь с типом и датой замены или датчик, сообщающий только «низкий». Срок = последняя замена + этот срок службы. Для батарей с уровнем прогноз строится по измеренному разряду. После трёх замен одного типа медианный интервал заменяет встроенное значение — ваше значение всегда главнее.", "settings_battery_lifetimes_hint": "Используется только для батарей без процента: заметка Battery Notes лишь с типом и датой замены или датчик, сообщающий только «низкий». Срок = последняя замена + этот срок службы. Для батарей с уровнем прогноз строится по измеренному разряду. После трёх замен одного типа медианный интервал заменяет встроенное значение — ваше значение всегда главнее.",
"settings_battery_lifetime_months": "мес.", "settings_battery_lifetime_months": "мес.",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "в вашем парке", "settings_battery_lifetime_in_fleet": "в вашем парке",
"settings_battery_lifetime_learned_models": "Изучено по моделям: {list}", "settings_battery_lifetime_learned_models": "Изучено по моделям: {list}",
"settings_thresholds_hint": "Значения по умолчанию для новых «Предлагаемых настроек» (остаток в процентах) и для батарей парка без собственного порога Battery Notes. Существующие задачи сохраняют своё значение.", "settings_thresholds_hint": "Значения по умолчанию для новых «Предлагаемых настроек» (остаток в процентах) и для батарей парка без собственного порога Battery Notes. Существующие задачи сохраняют своё значение.",
"settings_part_search_url": "Ссылка для поиска покупки",
"settings_part_search_url_hint": "URL с {q} вместо поискового запроса, для деталей без ссылки на товар. Оставьте пустым для автоматического магазина (по стране, иначе по языку).",
"settings_value_out_of_range": "Значение должно быть от {min} до {max}", "settings_value_out_of_range": "Значение должно быть от {min} до {max}",
"bn_summary": "{name}: {pct} % для {n} батарей", "bn_summary": "{name}: {pct} % для {n} батарей",
"bn_floor_decides": "Ваш порог {floor} % действует для всех; для каждой батареи учитывается больший из двух порогов.", "bn_floor_decides": "Ваш порог {floor} % действует для всех; для каждой батареи учитывается больший из двух порогов.",
@@ -717,6 +725,8 @@
"archived": "В архиве", "archived": "В архиве",
"show_archived": "Показать архив", "show_archived": "Показать архив",
"hide_archived": "Скрыть архив", "hide_archived": "Скрыть архив",
"section_collapse": "Свернуть раздел",
"section_expand": "Развернуть раздел",
"confirm_archive_object": "Архивировать этот объект и его задачи? История сохранится, позже можно восстановить.", "confirm_archive_object": "Архивировать этот объект и его задачи? История сохранится, позже можно восстановить.",
"settings_archive": "Архив и хранение", "settings_archive": "Архив и хранение",
"settings_archive_desc": "Убирайте выполненные разовые задачи в архив, не удаляя их. Архивные элементы скрыты и неактивны, но сохраняют историю и расходы.", "settings_archive_desc": "Убирайте выполненные разовые задачи в архив, не удаляя их. Архивные элементы скрыты и неактивны, но сохраняют историю и расходы.",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Ogiltigt datum", "ws_err_invalid_date": "Ogiltigt datum",
"ws_err_invalid_format": "Ogiltigt format", "ws_err_invalid_format": "Ogiltigt format",
"ws_err_invalid_url": "Ogiltig länk", "ws_err_invalid_url": "Ogiltig länk",
"ws_err_invalid_mirror_todo": "Ogiltig att-göra-lista",
"ws_err_not_configured": "Inte inställt ännu", "ws_err_not_configured": "Inte inställt ännu",
"ws_err_not_loaded": "Inte inläst ännu — försök igen om en stund", "ws_err_not_loaded": "Inte inläst ännu — försök igen om en stund",
"ws_err_limit_reached": "Gränsen nådd", "ws_err_limit_reached": "Gränsen nådd",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "Inga standardvärden för snabbslutförande", "ws_err_no_defaults": "Inga standardvärden för snabbslutförande",
"ws_err_self_link_device": "Ett objekt kan inte länkas till sig självt", "ws_err_self_link_device": "Ett objekt kan inte länkas till sig självt",
"ws_err_too_early": "För tidigt — uppgiften kan bara slutföras närmare förfallodatumet", "ws_err_too_early": "För tidigt — uppgiften kan bara slutföras närmare förfallodatumet",
"ws_err_invalid_search_template": "Söklänken måste vara en http(s)-URL som innehåller {q}",
"feat_schedule_time": "Schemaläggning per tid på dygnet", "feat_schedule_time": "Schemaläggning per tid på dygnet",
"feat_schedule_time_desc": "Uppgifter blir försenade vid en specifik tid på dygnet istället för midnatt.", "feat_schedule_time_desc": "Uppgifter blir försenade vid en specifik tid på dygnet istället för midnatt.",
"schedule_time_toggle": "Förfaller vid en viss tid", "schedule_time_toggle": "Förfaller vid en viss tid",
@@ -199,6 +201,8 @@
"labels": "Etiketter", "labels": "Etiketter",
"labels_placeholder": "t.ex. säkerhet, säsong, synlig-för-hyresgäst", "labels_placeholder": "t.ex. säkerhet, säsong, synlig-för-hyresgäst",
"labels_help": "Kommaseparerade taggar för filtrering och rapporter.", "labels_help": "Kommaseparerade taggar för filtrering och rapporter.",
"task_mirror_todo": "Spegla till att-göra-listor",
"task_mirror_todo_hint": "Uppgiften visas i dessa listor så länge den är aktuell; bockar du av den där slutförs den här.",
"priority_low": "Låg", "priority_low": "Låg",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Hög", "priority_high": "Hög",
@@ -496,6 +500,8 @@
"settings_default_warning": "Standard varningsdagar", "settings_default_warning": "Standard varningsdagar",
"settings_consumable_threshold": "Tröskel „förbrukningsartikel låg“ (%)", "settings_consumable_threshold": "Tröskel „förbrukningsartikel låg“ (%)",
"settings_battery_low_percent": "Tröskel „batteri lågt“ (%)", "settings_battery_low_percent": "Tröskel „batteri lågt“ (%)",
"settings_battery_recovered_percent": "Batteri räknas som bytt över (%)",
"settings_battery_recovered_percent_hint": "Ett lågt batteri räknas som lågt tills nivån stiger över detta värde eller ett byte registreras — så kan en nivå som pendlar kring tröskeln inte slutföra flottuppgiften om och om igen.",
"settings_battery_lifetimes": "Typiska batterilivslängder", "settings_battery_lifetimes": "Typiska batterilivslängder",
"settings_battery_lifetimes_hint": "Används bara för batterier utan procent: en Battery Notes-anteckning med bara typ och bytesdatum, eller en sensor som bara rapporterar ”lågt”. Deras förfallodatum är senaste byte + denna livslängd. Batterier som rapporterar nivå får sin prognos från den uppmätta urladdningen. När flottan sett tre byten av en typ tar medianintervallet över från det inbyggda värdet — ditt eget värde vinner alltid.", "settings_battery_lifetimes_hint": "Används bara för batterier utan procent: en Battery Notes-anteckning med bara typ och bytesdatum, eller en sensor som bara rapporterar ”lågt”. Deras förfallodatum är senaste byte + denna livslängd. Batterier som rapporterar nivå får sin prognos från den uppmätta urladdningen. När flottan sett tre byten av en typ tar medianintervallet över från det inbyggda värdet — ditt eget värde vinner alltid.",
"settings_battery_lifetime_months": "månader", "settings_battery_lifetime_months": "månader",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "i din flotta", "settings_battery_lifetime_in_fleet": "i din flotta",
"settings_battery_lifetime_learned_models": "Inlärt per modell: {list}", "settings_battery_lifetime_learned_models": "Inlärt per modell: {list}",
"settings_thresholds_hint": "Standardvärden för nya Föreslagna inställningar (återstående procent) och för flottans batterier utan egen Battery Notes-tröskel. Befintliga uppgifter behåller sitt värde.", "settings_thresholds_hint": "Standardvärden för nya Föreslagna inställningar (återstående procent) och för flottans batterier utan egen Battery Notes-tröskel. Befintliga uppgifter behåller sitt värde.",
"settings_part_search_url": "Söklänk för inköp",
"settings_part_search_url_hint": "URL med {q} i stället för söktermerna, för delar utan produktlänk. Lämna tomt för den automatiska butiken (efter land, annars språk).",
"settings_value_out_of_range": "Värdet måste vara mellan {min} och {max}", "settings_value_out_of_range": "Värdet måste vara mellan {min} och {max}",
"bn_summary": "{name}: {pct} % för {n} batterier", "bn_summary": "{name}: {pct} % för {n} batterier",
"bn_floor_decides": "Din tröskel på {floor} % avgör för alla; per batteri gäller den högre av de två trösklarna.", "bn_floor_decides": "Din tröskel på {floor} % avgör för alla; per batteri gäller den högre av de två trösklarna.",
@@ -717,6 +725,8 @@
"archived": "Arkiverad", "archived": "Arkiverad",
"show_archived": "Visa arkiverade", "show_archived": "Visa arkiverade",
"hide_archived": "Dölj arkiverade", "hide_archived": "Dölj arkiverade",
"section_collapse": "Fäll ihop sektionen",
"section_expand": "Fäll ut sektionen",
"confirm_archive_object": "Arkivera detta objekt och dess uppgifter? Historiken behålls och kan återställas senare.", "confirm_archive_object": "Arkivera detta objekt och dess uppgifter? Historiken behålls och kan återställas senare.",
"settings_archive": "Arkiv och lagring", "settings_archive": "Arkiv och lagring",
"settings_archive_desc": "Lägg undan slutförda engångsuppgifter utan att radera dem. Arkiverade objekt döljs och är inaktiva men behåller historik och kostnad.", "settings_archive_desc": "Lägg undan slutförda engångsuppgifter utan att radera dem. Arkiverade objekt döljs och är inaktiva men behåller historik och kostnad.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "Geçersiz tarih", "ws_err_invalid_date": "Geçersiz tarih",
"ws_err_invalid_format": "Geçersiz biçim", "ws_err_invalid_format": "Geçersiz biçim",
"ws_err_invalid_url": "Geçersiz bağlantı", "ws_err_invalid_url": "Geçersiz bağlantı",
"ws_err_invalid_mirror_todo": "Geçersiz yapılacaklar listesi",
"ws_err_not_configured": "Henüz ayarlanmadı", "ws_err_not_configured": "Henüz ayarlanmadı",
"ws_err_not_loaded": "Henüz yüklenmedi — birazdan tekrar deneyin", "ws_err_not_loaded": "Henüz yüklenmedi — birazdan tekrar deneyin",
"ws_err_limit_reached": "Sınıra ulaşıldı", "ws_err_limit_reached": "Sınıra ulaşıldı",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "Hızlı tamamlama varsayılanları ayarlanmamış", "ws_err_no_defaults": "Hızlı tamamlama varsayılanları ayarlanmamış",
"ws_err_self_link_device": "Bir nesne kendisine bağlanamaz", "ws_err_self_link_device": "Bir nesne kendisine bağlanamaz",
"ws_err_too_early": "Çok erken — bu görev ancak son tarihine yaklaşınca tamamlanabilir", "ws_err_too_early": "Çok erken — bu görev ancak son tarihine yaklaşınca tamamlanabilir",
"ws_err_invalid_search_template": "Arama bağlantısı {q} içeren bir http(s) URL olmalıdır",
"feat_schedule_time": "Gün içi saat zamanlaması", "feat_schedule_time": "Gün içi saat zamanlaması",
"feat_schedule_time_desc": "Görevler gece yarısı yerine günün belirli bir saatinde gecikmiş olur.", "feat_schedule_time_desc": "Görevler gece yarısı yerine günün belirli bir saatinde gecikmiş olur.",
"schedule_time_toggle": "Belirli bir saatte vadesi dolar", "schedule_time_toggle": "Belirli bir saatte vadesi dolar",
@@ -201,6 +203,8 @@
"labels": "Etiketler", "labels": "Etiketler",
"labels_placeholder": "örn. güvenlik, mevsimlik, kiracıya görünür", "labels_placeholder": "örn. güvenlik, mevsimlik, kiracıya görünür",
"labels_help": "Filtreleme ve raporlama için virgülle ayrılmış etiketler.", "labels_help": "Filtreleme ve raporlama için virgülle ayrılmış etiketler.",
"task_mirror_todo": "Yapılacaklar listelerine yansıt",
"task_mirror_todo_hint": "Görev, zamanı geldiği sürece bu listelerde görünür; orada tamamlandı olarak işaretlemek burada da tamamlar.",
"priority_low": "Düşük", "priority_low": "Düşük",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Yüksek", "priority_high": "Yüksek",
@@ -498,6 +502,8 @@
"settings_default_warning": "Varsayılan uyarı günleri", "settings_default_warning": "Varsayılan uyarı günleri",
"settings_consumable_threshold": "„Sarf malzemesi düşük“ eşiği (%)", "settings_consumable_threshold": "„Sarf malzemesi düşük“ eşiği (%)",
"settings_battery_low_percent": "„Pil zayıf“ eşiği (%)", "settings_battery_low_percent": "„Pil zayıf“ eşiği (%)",
"settings_battery_recovered_percent": "Pil şu değerin üzerinde değiştirilmiş sayılır (%)",
"settings_battery_recovered_percent_hint": "Zayıf bir pil, seviyesi bu değerin üzerine çıkana veya bir değişim kaydedilene kadar zayıf sayılmaya devam eder — böylece eşik çevresinde salınan bir seviye filo görevini tekrar tekrar tamamlayamaz.",
"settings_battery_lifetimes": "Tipik pil ömürleri", "settings_battery_lifetimes": "Tipik pil ömürleri",
"settings_battery_lifetimes_hint": "Yalnızca yüzdesi olmayan piller için kullanılır: sadece tür ve değişim tarihi olan bir Battery Notes notu ya da yalnızca \"düşük\" bildiren bir sensör. Vade = son değişim + bu ömür. Seviye bildiren pillerin tahmini ölçülen deşarjdan gelir. Filo bir türden üç değişim gördüğünde ortanca aralık yerleşik değerin yerini alır — kendi değerin her zaman kazanır.", "settings_battery_lifetimes_hint": "Yalnızca yüzdesi olmayan piller için kullanılır: sadece tür ve değişim tarihi olan bir Battery Notes notu ya da yalnızca \"düşük\" bildiren bir sensör. Vade = son değişim + bu ömür. Seviye bildiren pillerin tahmini ölçülen deşarjdan gelir. Filo bir türden üç değişim gördüğünde ortanca aralık yerleşik değerin yerini alır — kendi değerin her zaman kazanır.",
"settings_battery_lifetime_months": "ay", "settings_battery_lifetime_months": "ay",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "filonda", "settings_battery_lifetime_in_fleet": "filonda",
"settings_battery_lifetime_learned_models": "Modele göre öğrenilen: {list}", "settings_battery_lifetime_learned_models": "Modele göre öğrenilen: {list}",
"settings_thresholds_hint": "Yeni Önerilen kurulumlar (kalan yüzde) ve kendi Battery Notes eşiği olmayan filo pilleri için varsayılanlar. Mevcut görevler değerlerini korur.", "settings_thresholds_hint": "Yeni Önerilen kurulumlar (kalan yüzde) ve kendi Battery Notes eşiği olmayan filo pilleri için varsayılanlar. Mevcut görevler değerlerini korur.",
"settings_part_search_url": "Alışveriş arama bağlantısı",
"settings_part_search_url_hint": "Arama terimleri yerine {q} içeren URL; ürün bağlantısı olmayan parçalar için kullanılır. Otomatik mağaza için boş bırakın (ülkeye, yoksa dile göre).",
"settings_value_out_of_range": "Değer {min} ile {max} arasında olmalıdır", "settings_value_out_of_range": "Değer {min} ile {max} arasında olmalıdır",
"bn_summary": "{name}: {n} pil için % {pct}", "bn_summary": "{name}: {n} pil için % {pct}",
"bn_floor_decides": "Senin % {floor} eşiğin hepsi için belirleyici; her pil için iki eşikten yüksek olanı geçerli.", "bn_floor_decides": "Senin % {floor} eşiğin hepsi için belirleyici; her pil için iki eşikten yüksek olanı geçerli.",
@@ -723,6 +731,8 @@
"archived": "Arşivlendi", "archived": "Arşivlendi",
"show_archived": "Arşivlenenleri göster", "show_archived": "Arşivlenenleri göster",
"hide_archived": "Arşivlenenleri gizle", "hide_archived": "Arşivlenenleri gizle",
"section_collapse": "Bölümü daralt",
"section_expand": "Bölümü genişlet",
"confirm_archive_object": "Bu nesne ve görevleri arşivlensin mi? Geçmişleri korunur ve daha sonra arşivden çıkarılabilirler.", "confirm_archive_object": "Bu nesne ve görevleri arşivlensin mi? Geçmişleri korunur ve daha sonra arşivden çıkarılabilirler.",
"settings_archive": "Arşiv ve Saklama", "settings_archive": "Arşiv ve Saklama",
"settings_archive_desc": "Tamamlanmış tek seferlik görevleri silmeden emekliye ayırın. Arşivlenen öğeler gizlenir ve pasiftir ancak geçmişlerini ve maliyetlerini korurlar.", "settings_archive_desc": "Tamamlanmış tek seferlik görevleri silmeden emekliye ayırın. Arşivlenen öğeler gizlenir ve pasiftir ancak geçmişlerini ve maliyetlerini korurlar.",
@@ -129,6 +129,7 @@
"ws_err_invalid_date": "Неприпустима дата", "ws_err_invalid_date": "Неприпустима дата",
"ws_err_invalid_format": "Неприпустимий формат", "ws_err_invalid_format": "Неприпустимий формат",
"ws_err_invalid_url": "Неприпустиме посилання", "ws_err_invalid_url": "Неприпустиме посилання",
"ws_err_invalid_mirror_todo": "Неприпустимий список справ",
"ws_err_not_configured": "Ще не налаштовано", "ws_err_not_configured": "Ще не налаштовано",
"ws_err_not_loaded": "Ще не завантажено — спробуйте трохи пізніше", "ws_err_not_loaded": "Ще не завантажено — спробуйте трохи пізніше",
"ws_err_limit_reached": "Досягнуто межу", "ws_err_limit_reached": "Досягнуто межу",
@@ -163,6 +164,7 @@
"ws_err_no_defaults": "Не задано значення за замовчуванням для швидкого завершення", "ws_err_no_defaults": "Не задано значення за замовчуванням для швидкого завершення",
"ws_err_self_link_device": "Об'єкт не можна пов'язати із самим собою", "ws_err_self_link_device": "Об'єкт не можна пов'язати із самим собою",
"ws_err_too_early": "Зарано — це завдання можна завершити лише ближче до терміну", "ws_err_too_early": "Зарано — це завдання можна завершити лише ближче до терміну",
"ws_err_invalid_search_template": "Посилання для пошуку має бути URL http(s) із {q}",
"feat_schedule_time": "Планування за часом доби", "feat_schedule_time": "Планування за часом доби",
"feat_schedule_time_desc": "Задачі стають простроченими у певний час доби, а не опівночі.", "feat_schedule_time_desc": "Задачі стають простроченими у певний час доби, а не опівночі.",
"schedule_time_toggle": "Термін у визначений час", "schedule_time_toggle": "Термін у визначений час",
@@ -199,6 +201,8 @@
"labels": "Мітки", "labels": "Мітки",
"labels_placeholder": "напр. безпека, сезонне, видно-орендарю", "labels_placeholder": "напр. безпека, сезонне, видно-орендарю",
"labels_help": "Теги через кому для фільтрації та звітів.", "labels_help": "Теги через кому для фільтрації та звітів.",
"task_mirror_todo": "Відображати у списках справ",
"task_mirror_todo_hint": "Завдання з'являється в цих списках, поки воно актуальне; відмітка там завершує його тут.",
"priority_low": "Низький", "priority_low": "Низький",
"priority_normal": "Звичайний", "priority_normal": "Звичайний",
"priority_high": "Високий", "priority_high": "Високий",
@@ -496,6 +500,8 @@
"settings_default_warning": "Днів попередження за замовчуванням", "settings_default_warning": "Днів попередження за замовчуванням",
"settings_consumable_threshold": "Поріг «витратний матеріал закінчується» (%)", "settings_consumable_threshold": "Поріг «витратний матеріал закінчується» (%)",
"settings_battery_low_percent": "Поріг «батарея розряджена» (%)", "settings_battery_low_percent": "Поріг «батарея розряджена» (%)",
"settings_battery_recovered_percent": "Батарея вважається заміненою вище (%)",
"settings_battery_recovered_percent_hint": "Розряджена батарея вважається розрядженою, доки її рівень не підніметься вище цього значення або не буде записано заміну — рівень, що коливається біля порога, більше не завершує завдання парку знову й знову.",
"settings_battery_lifetimes": "Типовий строк служби батарей", "settings_battery_lifetimes": "Типовий строк служби батарей",
"settings_battery_lifetimes_hint": "Використовується лише для батарей без відсотка: нотатка Battery Notes лише з типом і датою заміни або датчик, що повідомляє тільки «низький». Термін = остання заміна + цей строк служби. Для батарей з рівнем прогноз будується за виміряним розрядом. Після трьох замін одного типу медіанний інтервал замінює вбудоване значення — ваше значення завжди головніше.", "settings_battery_lifetimes_hint": "Використовується лише для батарей без відсотка: нотатка Battery Notes лише з типом і датою заміни або датчик, що повідомляє тільки «низький». Термін = остання заміна + цей строк служби. Для батарей з рівнем прогноз будується за виміряним розрядом. Після трьох замін одного типу медіанний інтервал замінює вбудоване значення — ваше значення завжди головніше.",
"settings_battery_lifetime_months": "міс.", "settings_battery_lifetime_months": "міс.",
@@ -503,6 +509,8 @@
"settings_battery_lifetime_in_fleet": "у вашому парку", "settings_battery_lifetime_in_fleet": "у вашому парку",
"settings_battery_lifetime_learned_models": "Вивчено за моделями: {list}", "settings_battery_lifetime_learned_models": "Вивчено за моделями: {list}",
"settings_thresholds_hint": "Значення за замовчуванням для нових «Запропонованих налаштувань» (залишок у відсотках) і для батарей парку без власного порогу Battery Notes. Наявні завдання зберігають своє значення.", "settings_thresholds_hint": "Значення за замовчуванням для нових «Запропонованих налаштувань» (залишок у відсотках) і для батарей парку без власного порогу Battery Notes. Наявні завдання зберігають своє значення.",
"settings_part_search_url": "Посилання для пошуку покупки",
"settings_part_search_url_hint": "URL із {q} замість пошукового запиту, для деталей без посилання на товар. Залиште порожнім для автоматичного магазину (за країною, інакше за мовою).",
"settings_value_out_of_range": "Значення має бути від {min} до {max}", "settings_value_out_of_range": "Значення має бути від {min} до {max}",
"bn_summary": "{name}: {pct} % для {n} батарей", "bn_summary": "{name}: {pct} % для {n} батарей",
"bn_floor_decides": "Ваш поріг {floor} % діє для всіх; для кожної батареї враховується більший із двох порогів.", "bn_floor_decides": "Ваш поріг {floor} % діє для всіх; для кожної батареї враховується більший із двох порогів.",
@@ -717,6 +725,8 @@
"archived": "В архіві", "archived": "В архіві",
"show_archived": "Показати архів", "show_archived": "Показати архів",
"hide_archived": "Сховати архів", "hide_archived": "Сховати архів",
"section_collapse": "Згорнути розділ",
"section_expand": "Розгорнути розділ",
"confirm_archive_object": "Архівувати цей об'єкт та його завдання? Історія збережеться, згодом можна відновити.", "confirm_archive_object": "Архівувати цей об'єкт та його завдання? Історія збережеться, згодом можна відновити.",
"settings_archive": "Архів і зберігання", "settings_archive": "Архів і зберігання",
"settings_archive_desc": "Відкладайте виконані одноразові завдання в архів, не видаляючи їх. Архівні елементи приховані й неактивні, але зберігають історію та витрати.", "settings_archive_desc": "Відкладайте виконані одноразові завдання в архів, не видаляючи їх. Архівні елементи приховані й неактивні, але зберігають історію та витрати.",
@@ -131,6 +131,7 @@
"ws_err_invalid_date": "日期无效", "ws_err_invalid_date": "日期无效",
"ws_err_invalid_format": "格式无效", "ws_err_invalid_format": "格式无效",
"ws_err_invalid_url": "链接无效", "ws_err_invalid_url": "链接无效",
"ws_err_invalid_mirror_todo": "无效的待办清单",
"ws_err_not_configured": "尚未设置", "ws_err_not_configured": "尚未设置",
"ws_err_not_loaded": "尚未加载 — 请稍后重试", "ws_err_not_loaded": "尚未加载 — 请稍后重试",
"ws_err_limit_reached": "已达上限", "ws_err_limit_reached": "已达上限",
@@ -165,6 +166,7 @@
"ws_err_no_defaults": "未设置快速完成默认值", "ws_err_no_defaults": "未设置快速完成默认值",
"ws_err_self_link_device": "对象不能链接到自身", "ws_err_self_link_device": "对象不能链接到自身",
"ws_err_too_early": "为时过早 — 此任务只能在临近到期日时完成", "ws_err_too_early": "为时过早 — 此任务只能在临近到期日时完成",
"ws_err_invalid_search_template": "搜索链接必须是包含 {q} 的 http(s) 网址",
"feat_schedule_time": "具体时间调度", "feat_schedule_time": "具体时间调度",
"feat_schedule_time_desc": "任务将在特定时间点变为逾期,而非默认的午夜。", "feat_schedule_time_desc": "任务将在特定时间点变为逾期,而非默认的午夜。",
"schedule_time_toggle": "在特定时间到期", "schedule_time_toggle": "在特定时间到期",
@@ -201,6 +203,8 @@
"labels": "标签", "labels": "标签",
"labels_placeholder": "例如:安全、季节性、租户可见", "labels_placeholder": "例如:安全、季节性、租户可见",
"labels_help": "用于筛选和报表的逗号分隔标签。", "labels_help": "用于筛选和报表的逗号分隔标签。",
"task_mirror_todo": "镜像到待办清单",
"task_mirror_todo_hint": "任务到期期间会出现在这些清单中;在那里勾选即在此处完成。",
"priority_low": "低", "priority_low": "低",
"priority_normal": "普通", "priority_normal": "普通",
"priority_high": "高", "priority_high": "高",
@@ -498,6 +502,8 @@
"settings_default_warning": "默认预警天数", "settings_default_warning": "默认预警天数",
"settings_consumable_threshold": "耗材“不足”阈值(%)", "settings_consumable_threshold": "耗材“不足”阈值(%)",
"settings_battery_low_percent": "电池“电量低”阈值(%)", "settings_battery_low_percent": "电池“电量低”阈值(%)",
"settings_battery_recovered_percent": "电量高于此值视为已更换(%)",
"settings_battery_recovered_percent_hint": "电量低的电池会一直计为低电量,直到电量高于此值或记录了更换——这样在阈值附近波动的电量不会反复完成电池组任务。",
"settings_battery_lifetimes": "电池典型寿命", "settings_battery_lifetimes": "电池典型寿命",
"settings_battery_lifetimes_hint": "仅用于没有百分比的电池:只有类型和更换日期的 Battery Notes 记录,或只报告“低电量”的传感器。其到期日 = 上次更换 + 此寿命。报告电量的电池改用实测放电来预测。同一类型出现三次更换后,中位间隔将取代内置值——你自己的值始终优先。", "settings_battery_lifetimes_hint": "仅用于没有百分比的电池:只有类型和更换日期的 Battery Notes 记录,或只报告“低电量”的传感器。其到期日 = 上次更换 + 此寿命。报告电量的电池改用实测放电来预测。同一类型出现三次更换后,中位间隔将取代内置值——你自己的值始终优先。",
"settings_battery_lifetime_months": "个月", "settings_battery_lifetime_months": "个月",
@@ -505,6 +511,8 @@
"settings_battery_lifetime_in_fleet": "在你的电池群中", "settings_battery_lifetime_in_fleet": "在你的电池群中",
"settings_battery_lifetime_learned_models": "按型号学习:{list}", "settings_battery_lifetime_learned_models": "按型号学习:{list}",
"settings_thresholds_hint": "用于新的“建议设置”(剩余百分比)以及没有自身 Battery Notes 阈值的电池组电池。现有任务保留其值。", "settings_thresholds_hint": "用于新的“建议设置”(剩余百分比)以及没有自身 Battery Notes 阈值的电池组电池。现有任务保留其值。",
"settings_part_search_url": "购物搜索链接",
"settings_part_search_url_hint": "以 {q} 代替搜索词的网址,用于没有产品链接的配件。留空则自动选择商店(先按国家,再按语言)。",
"settings_value_out_of_range": "数值必须介于 {min} 和 {max} 之间", "settings_value_out_of_range": "数值必须介于 {min} 和 {max} 之间",
"bn_summary": "{name}:{n} 块电池为 {pct}%", "bn_summary": "{name}:{n} 块电池为 {pct}%",
"bn_floor_decides": "你的 {floor}% 阈值对所有电池生效;每块电池取两个阈值中较高者。", "bn_floor_decides": "你的 {floor}% 阈值对所有电池生效;每块电池取两个阈值中较高者。",
@@ -717,6 +725,8 @@
"archived": "已归档", "archived": "已归档",
"show_archived": "显示已归档", "show_archived": "显示已归档",
"hide_archived": "隐藏已归档", "hide_archived": "隐藏已归档",
"section_collapse": "折叠此部分",
"section_expand": "展开此部分",
"confirm_archive_object": "归档此对象及其任务?历史记录将保留,以后可恢复。", "confirm_archive_object": "归档此对象及其任务?历史记录将保留,以后可恢复。",
"settings_archive": "归档与保留", "settings_archive": "归档与保留",
"settings_archive_desc": "将已完成的一次性任务归档而不删除。已归档项目会被隐藏且不再活动,但保留其历史记录和费用。", "settings_archive_desc": "将已完成的一次性任务归档而不删除。已归档项目会被隐藏且不再活动,但保留其历史记录和费用。",
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,250 @@
/*! maintenance_supporter frontend 2.87.0 */
import{e as f}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-KRAXVQN3.js";import{a as p}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-6FKJJO4T.js";import{a as o,b as _,c as i,f as l,h,l as g,m as n,q as t,s as u,u as v}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-BFRW5MGC.js";var r=class extends h{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._sensors=[];this._selected=new Set;this._users=[];this._responsible="";this._forMinutes="0";this._localeReady=!1;this._userService=null;this._toggle=s=>{let a=new Set(this._selected);a.has(s)?a.delete(s):a.add(s),this._selected=a};this._toggleAll=()=>{this._selected.size===this._sensors.length?this._selected=new Set:this._selected=new Set(this._sensors.map(s=>s.entity_id))};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let s=this._sensors.filter(e=>this._selected.has(e.entity_id)).map(e=>({entity_id:e.entity_id,name:e.name,entry_id:e.suggested_entry_id??void 0,object_name:e.suggested_object_name,device_id:e.device_id??void 0,part_id:e.suggested_part_id??void 0,responsible_user_id:this._responsible||void 0,for_minutes:parseInt(this._forMinutes,10)>0?parseInt(this._forMinutes,10):void 0})),a=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/problem_sensors/adopt",selections:s});this.dispatchEvent(new CustomEvent("problem-sensors-adopted",{bubbles:!0,composed:!0,detail:a})),this._open=!1}catch(s){this._error=p(s,this._lang)}finally{this._adopting=!1}}}}get _lang(){return u(this.hass)}updated(s){s.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,v(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._sensors=[],this._selected=new Set,this._responsible="",this._forMinutes="0";try{this._userService?this._userService.updateHass(this.hass):this._userService=new f(this.hass);let[s,a]=await Promise.all([this.hass.connection.sendMessagePromise({type:"maintenance_supporter/problem_sensors/discover"}),this._userService.getUsers().catch(()=>[])]);this._sensors=s.sensors||[],this._selected=new Set(this._sensors.map(e=>e.entity_id)),this._users=a}catch(s){this._error=p(s,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return i``;let s=this._lang,a=this._sensors.length>0&&this._selected.size===this._sensors.length;return i`
<div class="overlay" @click=${this._close}>
<div class="card" @click=${e=>e.stopPropagation()}>
<div class="title">${t("adopt_problem_title",s)}</div>
<div class="hint">${t("adopt_problem_hint",s)}</div>
${this._error?i`<div class="error">${this._error}</div>`:l}
${this._loading?i`<div class="loading">…</div>`:this._sensors.length===0?i`<div class="empty">${t("adopt_problem_none",s)}</div>`:i`
<label class="select-all">
<input
type="checkbox"
.checked=${a}
@change=${this._toggleAll}
/>
<span>${t("selected",s)}: ${this._selected.size} / ${this._sensors.length}</span>
</label>
<div class="list">
${this._sensors.map(e=>{let m=this._selected.has(e.entity_id),d=e.state==="on",c=[e.device_name,e.area_name].filter(Boolean).join(" \xB7 ");return i`
<label class="row">
<input
type="checkbox"
.checked=${m}
@change=${()=>this._toggle(e.entity_id)}
/>
<div class="row-main">
<div class="row-top">
<span class="row-name">${e.name}</span>
<span class="chip ${d?"chip-active":"chip-ok"}">
${d?t("adopt_problem_active",s):t("adopt_problem_ok",s)}
</span>
</div>
${c?i`<div class="row-sub">${c}</div>`:l}
<div class="row-target">
→ ${e.suggested_object_name}${e.suggested_entry_id?l:i` <span class="new-tag">${t("adopt_problem_new_object",s)}</span>`}
</div>
${e.suggested_part_name?i`<div class="row-part">
<ha-icon icon="mdi:package-variant-closed"></ha-icon>
${t("adopt_problem_part",s).replace("{name}",e.suggested_part_name)}
</div>`:l}
</div>
</label>
`})}
</div>
`}
${!this._loading&&this._sensors.length>0?i`
<label class="responsible">
<span>${t("for_at_least_minutes",s)}</span>
<input
class="for-input"
type="number"
min="0"
max="1440"
.value=${this._forMinutes}
@input=${e=>this._forMinutes=e.target.value}
/>
</label>
<div class="for-hint">${t("adopt_for_minutes_hint",s)}</div>
`:l}
${!this._loading&&this._sensors.length>0&&this._users.length>0?i`
<label class="responsible">
<span>${t("adopt_problem_responsible",s)}</span>
<select
.value=${this._responsible}
@change=${e=>{this._responsible=e.target.value}}
>
<option value="" ?selected=${!this._responsible}>${t("no_user_assigned",s)}</option>
${this._users.map(e=>i`<option value=${e.id} ?selected=${e.id===this._responsible}>${e.name}</option>`)}
</select>
</label>
`:l}
<div class="actions">
<ha-button appearance="plain" @click=${this._close}>
${t("cancel",s)}
</ha-button>
<ha-button
@click=${this._adopt}
.disabled=${this._selected.size===0||this._adopting}
>
${t("adopt_problem_adopt",s)}
</ha-button>
</div>
</div>
</div>
`}};r.styles=_`
.overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.card {
background: var(--card-background-color, #fff);
color: var(--primary-text-color);
border-radius: 12px;
padding: 20px;
display: flex;
flex-direction: column;
gap: 12px;
min-width: min(360px, calc(100vw - 24px));
max-width: 560px;
width: 90vw;
max-height: 80vh;
overflow: hidden;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}
.title {
font-size: 18px;
font-weight: 500;
}
.hint {
color: var(--secondary-text-color);
font-size: 13px;
}
.error {
color: var(--error-color, #f44336);
font-size: 13px;
}
.loading,
.empty {
color: var(--secondary-text-color);
font-size: 14px;
padding: 12px 0;
}
.select-all {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
color: var(--secondary-text-color);
cursor: pointer;
}
.select-all input {
cursor: pointer;
}
.list {
display: flex;
flex-direction: column;
gap: 6px;
overflow-y: auto;
max-height: 50vh;
}
.row {
display: flex;
align-items: flex-start;
gap: 10px;
padding: 8px;
border: 1px solid var(--divider-color);
border-radius: 6px;
cursor: pointer;
}
.row input {
margin-top: 2px;
cursor: pointer;
}
.row-main {
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
flex: 1;
}
.row-top {
display: flex;
align-items: center;
gap: 8px;
}
.row-name {
font-weight: 500;
font-size: 13px;
}
.row-sub {
color: var(--secondary-text-color);
font-size: 12px;
}
.row-target {
color: var(--secondary-text-color);
font-size: 12px;
}
.row-part {
color: var(--secondary-text-color);
font-size: 12px;
display: flex;
align-items: center;
gap: 4px;
}
.row-part ha-icon {
--mdc-icon-size: 14px;
}
.new-tag {
font-style: italic;
}
.chip {
font-size: 11px;
padding: 1px 8px;
border-radius: 10px;
white-space: nowrap;
}
.chip-active {
background: var(--error-color, #f44336);
color: #fff;
}
.chip-ok {
background: var(--divider-color);
color: var(--secondary-text-color);
}
.responsible {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
color: var(--secondary-text-color);
flex-wrap: wrap;
}
.for-input {
width: 70px;
background: var(--card-background-color);
color: var(--primary-text-color);
border: 1px solid var(--divider-color);
border-radius: 4px;
padding: 4px 6px;
}
.for-hint {
font-size: 11px;
color: var(--secondary-text-color);
margin: -4px 0 2px;
}
.responsible select {
flex: 1;
min-width: 140px;
padding: 4px 6px;
border-radius: 4px;
border: 1px solid var(--divider-color);
background: var(--card-background-color, #fff);
color: var(--primary-text-color);
font-size: 13px;
}
.actions {
display: flex;
justify-content: flex-end;
gap: 8px;
padding-top: 8px;
}
`,o([g({attribute:!1})],r.prototype,"hass",2),o([n()],r.prototype,"_open",2),o([n()],r.prototype,"_loading",2),o([n()],r.prototype,"_adopting",2),o([n()],r.prototype,"_error",2),o([n()],r.prototype,"_sensors",2),o([n()],r.prototype,"_selected",2),o([n()],r.prototype,"_users",2),o([n()],r.prototype,"_responsible",2),o([n()],r.prototype,"_forMinutes",2);customElements.get("maintenance-adopt-problem-sensors-dialog")||customElements.define("maintenance-adopt-problem-sensors-dialog",r);export{r as MaintenanceAdoptProblemSensorsDialog};
@@ -0,0 +1,2 @@
/*! maintenance_supporter frontend 2.87.0 */
import{q as o}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-BFRW5MGC.js";var v={already_archived:"ws_err_already_archived",already_paused:"ws_err_already_paused",archived:"ws_err_archived",create_failed:"ws_err_create_failed",duplicate_failed:"ws_err_duplicate_failed",empty:"ws_err_empty",empty_csv:"ws_err_empty_csv",invalid_cursor:"ws_err_invalid_cursor",invalid_date:"ws_err_invalid_date",invalid_device:"ws_err_invalid_device",invalid_entity_slug:"ws_err_invalid_entity_slug",invalid_format:"ws_err_invalid_format",invalid_input:"ws_err_invalid_input",invalid_mirror_todo:"ws_err_invalid_mirror_todo",invalid_parent:"ws_err_invalid_parent",invalid_range:"ws_err_invalid_range",invalid_search_template:"ws_err_invalid_search_template",invalid_target:"ws_err_invalid_target",invalid_trigger_config:"ws_err_invalid_trigger_config",invalid_url:"ws_err_invalid_url",invalid_user:"ws_err_invalid_user",invalid_view:"ws_err_invalid_view",limit_reached:"ws_err_limit_reached",no_defaults:"ws_err_no_defaults",no_phases:"ws_err_no_phases",no_url:"ws_err_no_url",not_archived:"ws_err_not_archived",not_available:"ws_err_not_available",not_configured:"ws_err_not_configured",not_found:"ws_err_not_found",not_loaded:"ws_err_not_loaded",not_paused:"ws_err_not_paused",replace_failed:"ws_err_replace_failed",self_link_device:"ws_err_self_link_device",storage_unavailable:"ws_err_storage_unavailable",too_early:"ws_err_too_early",too_large:"ws_err_too_large",too_many:"ws_err_too_many",too_many_views:"ws_err_too_many_views",unauthorized:"ws_err_unauthorized",unavailable:"ws_err_unavailable"},p={entry_id:"object",name:"name",task_type:"maintenance_type",schedule_type:"schedule_type",interval_days:"interval_days",interval_anchor:"interval_anchor",warning_days:"warning_days",last_performed:"last_performed_optional",notes:"notes_optional",documentation_url:"documentation_url_optional",custom_icon:"custom_icon_optional",nfc_tag_id:"nfc_tag_id_optional",responsible_user_id:"responsible_user",entity_slug:"entity_slug",entity_id:"entity_id",area_id:"area_id_optional",manufacturer:"manufacturer_optional",model:"model_optional",serial_number:"serial_number_optional",installation_date:"installation_date_optional",warranty_expiry:"warranty_expiry_optional",checklist:"checklist_steps_optional",reason:"reason",feedback:"feedback",cost:"cost",duration:"duration",description:"description_optional",environmental_entity:"environmental_entity_optional",environmental_attribute:"environmental_attribute_optional",trigger_above:"trigger_above",trigger_below:"trigger_below",trigger_equals:"trigger_equals",trigger_not_equals:"trigger_not_equals",trigger_for_minutes:"trigger_for_minutes"};function g(e){let _=e.replace(/_ids?$/,"").split("_").filter(Boolean);if(_.length===0)return e;let r=_.join(" ");return r.charAt(0).toUpperCase()+r.slice(1)}function w(e,_){let r=p[e];if(r){let t=o(r,_);if(t&&t!==r)return t}return g(e)}function f(e){let _=[...e.matchAll(/\['([^']+)'\]/g)].map(n=>n[1]),r=_.length?_[_.length-1]:void 0,t;return(t=e.match(/length of value must be at most (\d+)/))?{field:r,rule:"too_long",param:t[1]}:(t=e.match(/length of value must be at least (\d+)/))?{field:r,rule:"too_short",param:t[1]}:(t=e.match(/value must be at most (\S+)/))?{field:r,rule:"value_too_high",param:t[1]}:(t=e.match(/value must be at least (\S+)/))?{field:r,rule:"value_too_low",param:t[1]}:/required key not provided/.test(e)?{field:r,rule:"required"}:(t=e.match(/expected (\w+)/))?{field:r,rule:"wrong_type",param:t[1]}:/value must be one of/.test(e)?{field:r,rule:"invalid_choice"}:/not a valid value/.test(e)?{field:r,rule:"invalid_value"}:{field:r,rule:"unknown"}}var u=e=>e.toLowerCase().split(/[^a-z0-9]+/).filter(_=>_.length>1);function m(e,_){let r=new Set(u(_));return u(e).every(t=>r.has(t))}function y(e,_,r){if(r=r??o("action_error",_),typeof e=="string")return e;if(typeof e!="object"||e===null)return r;let t=e,n=t.message||t.error?.message||"",s=t.code||t.error?.code||"",d=s?v[s]:void 0;if(!n&&!d)return r;let a=f(n),c=a.field?w(a.field,_):"",i=l=>o(l,_).replace("{field}",c).replace("{n}",a.param??"");switch(a.rule){case"too_long":return i("err_too_long");case"too_short":return i("err_too_short");case"value_too_high":return i("err_value_too_high");case"value_too_low":return i("err_value_too_low");case"required":return i("err_required");case"wrong_type":return i("err_wrong_type").replace("{type}",a.param??"");case"invalid_choice":return i("err_invalid_choice");case"invalid_value":return i("err_invalid_value");default:if(d){let l=o(d,_);return n&&!m(n,s)?`${l} (${n})`:l}return n||r}}export{y as a};
@@ -0,0 +1,2 @@
/*! maintenance_supporter frontend 2.87.0 */
import{a as i}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-6FKJJO4T.js";import{q as s,s as o}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-BFRW5MGC.js";async function f(e,a,n={}){n.busy?.(!0);try{return await e.hass.connection.sendMessagePromise(a)}catch(t){let r=o(e.hass);n.onError?.(i(t,r,n.fallbackKey?s(n.fallbackKey,r):void 0));return}finally{n.busy?.(!1)}}export{f as a};
@@ -0,0 +1,79 @@
/*! maintenance_supporter frontend 2.87.0 */
import{a as r,b as l,c as i,f as o,h as n,l as t}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-BFRW5MGC.js";var e=class extends n{constructor(){super(...arguments);this.label="";this.value="";this.placeholder="";this.type="text";this.required=!1;this.disabled=!1;this.multiline=!1;this.rows=3}_onInput(s){let a=s.target.value;this.value=a,this.dispatchEvent(new CustomEvent("input",{bubbles:!0,composed:!0,detail:{value:a}}))}render(){return i`
<label class="field">
${this.label?i`<span class="label">${this.label}${this.required?i`<span class="req">*</span>`:o}</span>`:o}
${this.multiline?i`
<textarea
.value=${this.value??""}
rows=${this.rows}
?required=${this.required}
?disabled=${this.disabled}
placeholder=${this.placeholder}
@input=${this._onInput}
@change=${this._onInput}
></textarea>`:i`
<input
.value=${this.value??""}
.type=${this.type}
?required=${this.required}
?disabled=${this.disabled}
placeholder=${this.placeholder}
step=${this.step??o}
min=${this.min??o}
max=${this.max??o}
pattern=${this.pattern??o}
@input=${this._onInput}
@change=${this._onInput}
/>`}
${this.helper?i`<span class="helper">${this.helper}</span>`:o}
</label>
`}};e.styles=l`
:host { display: block; }
.field {
display: flex;
flex-direction: column;
gap: 4px;
}
.label {
font-size: 12px;
color: var(--secondary-text-color, #888);
font-weight: 500;
}
.req { color: var(--error-color, #f44336); margin-left: 2px; }
input {
padding: 8px 10px;
font-size: 14px;
background: var(--secondary-background-color, rgba(0,0,0,0.06));
color: var(--primary-text-color);
border: 1px solid var(--divider-color, rgba(255,255,255,0.12));
border-radius: 6px;
font-family: inherit;
width: 100%;
box-sizing: border-box;
outline: none;
}
input:focus {
border-color: var(--primary-color);
}
input:disabled { opacity: 0.5; cursor: not-allowed; }
textarea {
padding: 8px 10px;
font-size: 14px;
background: var(--secondary-background-color, rgba(0,0,0,0.06));
color: var(--primary-text-color);
border: 1px solid var(--divider-color, rgba(255,255,255,0.12));
border-radius: 6px;
font-family: inherit;
width: 100%;
box-sizing: border-box;
outline: none;
resize: vertical;
}
textarea:focus { border-color: var(--primary-color); }
textarea:disabled { opacity: 0.5; cursor: not-allowed; }
.helper {
font-size: 11px;
color: var(--secondary-text-color);
font-style: italic;
}
`,r([t()],e.prototype,"label",2),r([t()],e.prototype,"value",2),r([t()],e.prototype,"placeholder",2),r([t()],e.prototype,"type",2),r([t({type:Boolean})],e.prototype,"required",2),r([t({type:Boolean})],e.prototype,"disabled",2),r([t()],e.prototype,"step",2),r([t()],e.prototype,"min",2),r([t()],e.prototype,"max",2),r([t()],e.prototype,"pattern",2),r([t()],e.prototype,"helper",2),r([t({type:Boolean})],e.prototype,"multiline",2),r([t({type:Number})],e.prototype,"rows",2);customElements.get("ms-textfield")||customElements.define("ms-textfield",e);
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,213 @@
/*! maintenance_supporter frontend 2.87.0 */
import{a as x}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NOXOKE42.js";import{a,b as v,c as n,f as p,h as b,l as h,m as c,q as t}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-BFRW5MGC.js";function d(l){return l.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function f(l){return!l.startsWith("data:image/svg+xml,")&&!l.startsWith("data:image/png;base64,")?"":d(l)}function q(l){return l.replace(/[/\\:*?"<>|#%]+/g,"").replace(/\s+/g,"-").toLowerCase().substring(0,100)}var o=class extends b{constructor(){super(...arguments);this.lang="en";this._open=!1;this._loading=!1;this._error="";this._viewResult=null;this._completeResult=null;this._urlMode="companion";this._entryId="";this._taskId=null;this._objectName="";this._taskName="";this._generateSeq=0}openForObject(e,i){this._entryId=e,this._taskId=null,this._objectName=i,this._taskName="",this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}openForTask(e,i,r,s){this._entryId=e,this._taskId=i,this._objectName=r,this._taskName=s,this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}async _generate(){let e=++this._generateSeq;this._loading=!0,this._error="",this._viewResult=null,this._completeResult=null;try{let i={type:"maintenance_supporter/qr/generate",entry_id:this._entryId,url_mode:this._urlMode};this._taskId&&(i.task_id=this._taskId);let r=[this.hass.connection.sendMessagePromise({...i,action:"view"})];this._taskId&&r.push(this.hass.connection.sendMessagePromise({...i,action:"complete"}));let s=await Promise.all(r);if(e!==this._generateSeq)return;this._viewResult=s[0],s.length>1&&(this._completeResult=s[1])}catch(i){if(e!==this._generateSeq)return;let r=i?.code,s=i?.message;this._error=r==="no_url"||typeof s=="string"&&s.includes("No Home Assistant URL")?t("qr_error_no_url",this.lang):t("qr_error",this.lang)}finally{e===this._generateSeq&&(this._loading=!1)}}_setUrlMode(e){this._urlMode!==e&&(this._urlMode=e,this._generate())}_print(){if(!this._viewResult)return;let e=this._viewResult,i=e.label.task_name?`${e.label.object_name} \u2014 ${e.label.task_name}`:e.label.object_name,r=[e.label.manufacturer,e.label.model].filter(Boolean).join(" "),s=window.open("","_blank","width=600,height=500");if(!s)return;let g=this.lang||"en",u=d(i),m=d(r),_=!!this._completeResult,w=d(t("qr_action_view",g)),$=d(t("qr_action_complete",g));s.document.write(`<!DOCTYPE html><html><head><meta charset="utf-8">
<meta name="color-scheme" content="light">
<title>${u}</title>
<style>
/* Printable sheet \u2014 must not inherit the phone's dark theme. The QR images
carry their own white quiet zone and stay scannable either way, but the
labels below are explicit dark greys and would vanish on a WebView's dark
canvas. Same reasoning as helpers/report.ts. */
:root{color-scheme:light}
body{font-family:sans-serif;text-align:center;padding:20px;background:#fff;color:#1a1a1a}
h2{margin:0 0 4px}
.sub{color:#666;font-size:14px;margin-bottom:16px}
.qr-row{display:flex;justify-content:center;gap:24px;margin:12px 0}
.qr-col{display:flex;flex-direction:column;align-items:center;gap:6px}
.qr-col img{width:${_?"200px":"280px"}}
.qr-label{font-size:13px;font-weight:500;color:#333}
.url{font-size:10px;color:#999;word-break:break-all;margin-top:8px;max-width:480px}
</style></head><body>
<h2>${u}</h2>
${m?`<div class="sub">${m}</div>`:""}
<div class="qr-row">
<div class="qr-col">
<img src="${f(this._viewResult.svg_data_uri)}" alt="QR Info" />
<div class="qr-label">${w}</div>
</div>
${_?`<div class="qr-col">
<img src="${f(this._completeResult.svg_data_uri)}" alt="QR Complete" />
<div class="qr-label">${$}</div>
</div>`:""}
</div>
<div class="url">${d(this._viewResult.url)}</div>
<script>setTimeout(()=>window.print(),300)<\/script>
</body></html>`),s.document.close()}_downloadSvg(e,i){let r=decodeURIComponent(e.svg_data_uri.replace("data:image/svg+xml,","")),s=this._taskName?`${this._objectName}-${this._taskName}`:this._objectName;x(r,`qr-${q(s)}-${i}.svg`,"image/svg+xml")}_close(){this._open=!1,this._viewResult=null,this._completeResult=null,this._error="",this._loading=!1}render(){if(!this._open)return n``;let e=this.lang||this.hass?.language||"en",i=this._taskName?`${t("qr_code",e)}: ${this._objectName} \u2014 ${this._taskName}`:`${t("qr_code",e)}: ${this._objectName}`,r=!!this._viewResult;return n`
<ha-dialog open @closed=${this._close}>
<div class="dialog-title">${i}</div>
<div class="content">
${this._loading?n`<div class="loading">${t("qr_generating",e)}</div>`:this._error?n`<div class="error">${this._error}</div>`:r?n`
<div class="qr-pair">
<div class="qr-item">
<img
class="qr-image ${this._completeResult?"small":""}"
src="${this._viewResult.svg_data_uri}"
alt="QR Info"
/>
<div class="qr-item-label">${t("qr_action_view",e)}</div>
<button class="dl-btn"
@click=${()=>this._downloadSvg(this._viewResult,"info")}>
<ha-icon icon="mdi:download"></ha-icon>
${t("qr_download",e)}
</button>
</div>
${this._completeResult?n`
<div class="qr-item">
<img
class="qr-image small"
src="${this._completeResult.svg_data_uri}"
alt="QR Complete"
/>
<div class="qr-item-label">${t("qr_action_complete",e)}</div>
<button class="dl-btn"
@click=${()=>this._downloadSvg(this._completeResult,"complete")}>
<ha-icon icon="mdi:download"></ha-icon>
${t("qr_download",e)}
</button>
</div>
`:p}
</div>
<div class="url-display">${this._viewResult.url}</div>
`:p}
<div class="action-row">
<label>${t("qr_url_mode",e)}</label>
<div class="action-toggle">
<button class="toggle-btn ${this._urlMode==="companion"?"active":""}"
@click=${()=>this._setUrlMode("companion")}>${t("qr_mode_companion",e)}</button>
<button class="toggle-btn ${this._urlMode==="local"?"active":""}"
@click=${()=>this._setUrlMode("local")}>${t("qr_mode_local",e)}</button>
<button class="toggle-btn ${this._urlMode==="server"?"active":""}"
@click=${()=>this._setUrlMode("server")}>${t("qr_mode_server",e)}</button>
</div>
</div>
</div>
<div class="dialog-actions">
<ha-button appearance="plain" @click=${this._close}>
${t("cancel",e)}
</ha-button>
<ha-button
@click=${this._print}
.disabled=${!r}
>
${t("qr_print",e)}
</ha-button>
</div>
</ha-dialog>
`}};o.styles=v`
.dialog-title {
font-size: 18px;
font-weight: 500;
padding-bottom: 12px;
}
.content {
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
min-width: 300px;
}
.dialog-actions {
display: flex;
justify-content: flex-end;
gap: 8px;
padding-top: 16px;
}
.qr-pair {
display: flex;
gap: 20px;
justify-content: center;
width: 100%;
}
.qr-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
}
.qr-image {
width: 240px;
height: 240px;
image-rendering: pixelated;
}
.qr-image.small {
width: 180px;
height: 180px;
}
.qr-item-label {
font-size: 12px;
font-weight: 500;
color: var(--secondary-text-color);
text-align: center;
}
.dl-btn {
display: inline-flex;
align-items: center;
gap: 6px;
background: none;
border: 1px solid var(--divider-color, #e0e0e0);
cursor: pointer;
font-size: 13px;
color: var(--primary-text-color);
padding: 6px 14px;
border-radius: 18px;
transition: background 0.2s, border-color 0.2s;
}
.dl-btn:hover {
background: var(--secondary-background-color, #f5f5f5);
border-color: var(--primary-color);
}
.dl-btn ha-icon {
--mdc-icon-size: 18px;
}
.url-display {
font-size: 11px;
color: var(--secondary-text-color);
word-break: break-all;
text-align: center;
max-width: 400px;
}
.loading {
padding: 40px 0;
color: var(--secondary-text-color);
}
.error {
padding: 20px 0;
color: var(--error-color, #f44336);
}
.action-row {
display: flex;
flex-direction: column;
gap: 6px;
width: 100%;
}
.action-row label {
font-size: 13px;
color: var(--secondary-text-color);
}
.action-toggle {
display: flex;
gap: 4px;
background: var(--divider-color, #e0e0e0);
border-radius: 6px;
padding: 3px;
}
.toggle-btn {
flex: 1;
padding: 8px 12px;
border: none;
background: transparent;
color: var(--primary-text-color);
cursor: pointer;
border-radius: 4px;
font-size: 13px;
transition: all 0.2s;
line-height: 1.3;
}
.toggle-btn:hover {
background: rgba(0, 0, 0, 0.05);
}
.toggle-btn.active {
background: var(--primary-color);
color: var(--text-primary-color, #fff);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
}
`,a([h({attribute:!1})],o.prototype,"hass",2),a([h()],o.prototype,"lang",2),a([c()],o.prototype,"_open",2),a([c()],o.prototype,"_loading",2),a([c()],o.prototype,"_error",2),a([c()],o.prototype,"_viewResult",2),a([c()],o.prototype,"_completeResult",2),a([c()],o.prototype,"_urlMode",2);customElements.get("maintenance-qr-dialog")||customElements.define("maintenance-qr-dialog",o);export{o as a};
@@ -0,0 +1,153 @@
/*! maintenance_supporter frontend 2.87.0 */
import{a as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-6FKJJO4T.js";import{a as r,b as _,c as l,f as o,h,l as d,m as s,q as i,s as p}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-BFRW5MGC.js";var a=class extends h{constructor(){super(...arguments);this.objects=[];this._open=!1;this._loading=!1;this._error="";this._name="";this._manufacturer="";this._model="";this._serialNumber="";this._areaId="";this._installationDate="";this._warrantyExpiry="";this._documentationUrl="";this._notes="";this._haDeviceId="";this._parentEntryId="";this._entryId=null}get _lang(){return p(this.hass)}openCreate(){this._entryId=null,this._name="",this._manufacturer="",this._model="",this._serialNumber="",this._areaId="",this._installationDate="",this._warrantyExpiry="",this._documentationUrl="",this._notes="",this._haDeviceId="",this._parentEntryId="",this._error="",this._open=!0}openEdit(e,n){this._entryId=e,this._name=n.name||"",this._manufacturer=n.manufacturer||"",this._model=n.model||"",this._serialNumber=n.serial_number||"",this._areaId=n.area_id||"",this._installationDate=n.installation_date||"",this._warrantyExpiry=n.warranty_expiry||"",this._documentationUrl=n.documentation_url||"",this._notes=n.notes||"",this._haDeviceId=n.ha_device_id||"",this._parentEntryId=n.parent_entry_id||"",this._error="",this._open=!0}async _save(){if(!this._loading&&this._name.trim()){this._loading=!0,this._error="";try{this._entryId?await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/update",entry_id:this._entryId,name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}):await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/create",name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}),this._open=!1,this.dispatchEvent(new CustomEvent("object-saved"))}catch(e){this._error=u(e,this._lang,i("save_error",this._lang))}finally{this._loading=!1}}}_parentChoices(){return(this.objects||[]).filter(e=>e.entry_id!==this._entryId)}_close(){this._open=!1}render(){if(!this._open)return l``;let e=this._lang,n=this._entryId?i("edit_object",e):i("new_object",e);return l`
<ha-dialog open @closed=${this._close}>
<div class="dialog-title">${n}</div>
<div class="content">
${this._error?l`<div class="error">${this._error}</div>`:o}
<ms-textfield
label="${i("name",e)}"
required
.value=${this._name}
@input=${t=>this._name=t.target.value}
></ms-textfield>
<ms-textfield
label="${i("manufacturer_optional",e)}"
.value=${this._manufacturer}
@input=${t=>this._manufacturer=t.target.value}
></ms-textfield>
<ms-textfield
label="${i("model_optional",e)}"
.value=${this._model}
@input=${t=>this._model=t.target.value}
></ms-textfield>
<ms-textfield
label="${i("serial_number_optional",e)}"
.value=${this._serialNumber}
@input=${t=>this._serialNumber=t.target.value}
></ms-textfield>
<ms-textfield
label="${i("documentation_url_optional",e)}"
type="url"
.value=${this._documentationUrl}
@input=${t=>this._documentationUrl=t.target.value}
></ms-textfield>
<ha-area-picker
.hass=${this.hass}
label="${i("area_id_optional",e)}"
.value=${this._areaId}
@value-changed=${t=>this._areaId=t.detail.value||""}
></ha-area-picker>
<ms-date-field
kind="date"
clearable
.hass=${this.hass}
.lang=${e}
label="${i("installation_date_optional",e)}"
.value=${this._installationDate}
@value-changed=${t=>this._installationDate=t.detail.value}
></ms-date-field>
<ms-date-field
kind="date"
clearable
.hass=${this.hass}
.lang=${e}
label="${i("warranty_expiry_optional",e)}"
.value=${this._warrantyExpiry}
@value-changed=${t=>this._warrantyExpiry=t.detail.value}
></ms-date-field>
<ha-form
.hass=${this.hass}
.data=${{device:this._haDeviceId||void 0}}
.schema=${[{name:"device",selector:{device:{}}}]}
.computeLabel=${()=>i("link_device_optional",e)}
@value-changed=${t=>this._haDeviceId=t.detail.value?.device||""}
></ha-form>
${this._parentChoices().length?l`<label class="textarea-field">
<span class="textarea-label">${i("parent_object_optional",e)}</span>
<select
class="parent-select"
.value=${this._parentEntryId}
@change=${t=>this._parentEntryId=t.target.value}
>
<option value="" ?selected=${!this._parentEntryId}>
${i("parent_none",e)}
</option>
${this._parentChoices().map(t=>l`<option
value=${t.entry_id}
?selected=${this._parentEntryId===t.entry_id}
>${t.object.name}</option>`)}
</select>
</label>`:o}
<label class="textarea-field">
<span class="textarea-label">${i("object_notes_optional",e)}</span>
<textarea
rows="3"
.value=${this._notes}
@input=${t=>this._notes=t.target.value}
></textarea>
<span class="md-hint">${i("notes_markdown_hint",e)}</span>
</label>
</div>
<div class="dialog-actions">
<ha-button appearance="plain" @click=${this._close}>
${i("cancel",this._lang)}
</ha-button>
<ha-button
@click=${this._save}
.disabled=${this._loading||!this._name.trim()}
>
${this._loading?i("saving",this._lang):i("save",this._lang)}
</ha-button>
</div>
</ha-dialog>
`}};a.styles=_`
.dialog-title {
font-size: 18px;
font-weight: 500;
padding-bottom: 12px;
}
.content {
display: flex;
flex-direction: column;
gap: 16px;
min-width: 300px;
}
.dialog-actions {
display: flex;
justify-content: flex-end;
gap: 8px;
padding-top: 16px;
}
ms-textfield {
display: block;
}
.textarea-field {
display: flex; flex-direction: column; gap: 4px;
}
.textarea-label {
font-size: 12px; color: var(--secondary-text-color, #888); font-weight: 500;
}
.textarea-field textarea {
padding: 8px 10px; font-size: 14px; font-family: inherit;
background: var(--secondary-background-color, rgba(0,0,0,0.06));
color: var(--primary-text-color);
border: 1px solid var(--divider-color); border-radius: 6px;
resize: vertical;
}
.textarea-field textarea:focus {
outline: none; border-color: var(--primary-color);
}
.md-hint {
font-size: 11px; color: var(--secondary-text-color); font-style: italic;
}
.parent-select {
padding: 8px 10px; font-size: 14px; font-family: inherit;
background: var(--secondary-background-color, rgba(0,0,0,0.06));
color: var(--primary-text-color);
border: 1px solid var(--divider-color); border-radius: 6px;
}
.error {
color: var(--error-color, #f44336);
font-size: 13px;
}
`,r([d({attribute:!1})],a.prototype,"hass",2),r([d({attribute:!1})],a.prototype,"objects",2),r([s()],a.prototype,"_open",2),r([s()],a.prototype,"_loading",2),r([s()],a.prototype,"_error",2),r([s()],a.prototype,"_name",2),r([s()],a.prototype,"_manufacturer",2),r([s()],a.prototype,"_model",2),r([s()],a.prototype,"_serialNumber",2),r([s()],a.prototype,"_areaId",2),r([s()],a.prototype,"_installationDate",2),r([s()],a.prototype,"_warrantyExpiry",2),r([s()],a.prototype,"_documentationUrl",2),r([s()],a.prototype,"_notes",2),r([s()],a.prototype,"_haDeviceId",2),r([s()],a.prototype,"_parentEntryId",2),r([s()],a.prototype,"_entryId",2);customElements.get("maintenance-object-dialog")||customElements.define("maintenance-object-dialog",a);export{a};
@@ -0,0 +1,2 @@
/*! maintenance_supporter frontend 2.87.0 */
import{c as r,f as i}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-BFRW5MGC.js";var a=["#c62828","#ad1457","#6a1b9a","#4527a0","#283593","#1565c0","#00838f","#2e7d32","#558b2f","#ef6c00","#6d4c41","#546e7a"];function u(e){let s=(e||"").split(/\s+/).filter(Boolean);return s.length===0?"?":s.length===1?s[0][0].toUpperCase():(s[0][0]+s[s.length-1][0]).toUpperCase()}function c(e){let s=0;for(let n of e)s=s*31+n.charCodeAt(0)>>>0;return a[s%a.length]}function o(e){return e?{id:e.id,name:e.name,initials:e.initials||u(e.name),color:e.color||c(e.id)}:null}function h(e){return e?r`<span class="person-avatar" style="--person-color: ${e.color}" title=${e.name}>${e.initials}</span>`:i}function m(e,s=""){return e?r`<span class="person-chip ${s}" title=${e.name}>${h(e)}<span class="person-name">${e.name}</span></span>`:i}var l=class{constructor(s){this.usersCache=null;this.cacheTimestamp=0;this.CACHE_TTL_MS=6e4;this.hass=s}updateHass(s){this.hass=s}async getUsers(s=!1){let n=Date.now();if(!s&&this.usersCache&&n-this.cacheTimestamp<this.CACHE_TTL_MS)return this.usersCache;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/users/list"});return this.usersCache=t.users,this.cacheTimestamp=n,this.usersCache}catch(t){return console.error("Failed to fetch users:",t),this.usersCache||[]}}async assignUser(s,n,t){await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/task/assign_user",entry_id:s,task_id:n,user_id:t})}async getTasksByUser(s){return(await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/tasks/by_user",user_id:s})).tasks}getUserName(s){return!s||!this.usersCache?null:this.usersCache.find(t=>t.id===s)?.name||null}getPerson(s){return o(this.getUser(s))}getUser(s){return!s||!this.usersCache?null:this.usersCache.find(n=>n.id===s)||null}getCurrentUserId(){return this.hass.user?.id||null}isCurrentUser(s){return s?s===this.getCurrentUserId():!1}clearCache(){this.usersCache=null,this.cacheTimestamp=0}};export{a,o as b,h as c,m as d,l as e};
@@ -0,0 +1,2 @@
/*! maintenance_supporter frontend 2.87.0 */
function c(o,t,e){let l=new Blob([o],{type:e}),d=URL.createObjectURL(l),n=document.createElement("a");n.href=d,n.download=t,n.target="_blank",n.rel="noopener",n.style.display="none",document.body.appendChild(n),n.dispatchEvent(new MouseEvent("click")),document.body.removeChild(n),setTimeout(()=>URL.revokeObjectURL(d),6e4)}function r(o,t){let e=document.createElement("a");e.href=o,e.download=t,e.target="_blank",e.rel="noopener",e.style.display="none",document.body.appendChild(e),e.dispatchEvent(new MouseEvent("click")),document.body.removeChild(e)}export{c as a,r as b};
@@ -0,0 +1,2 @@
/*! maintenance_supporter frontend 2.87.0 */
var l=[{key:"name",labelKey:"name",required:!0},{key:"ref_no",labelKey:"ref_number"},{key:"manufacturer",labelKey:"manufacturer"},{key:"model",labelKey:"model"},{key:"serial_number",labelKey:"serial_number_label"},{key:"installation_date",labelKey:"installed"},{key:"warranty_expiry",labelKey:"warranty"},{key:"area_id",labelKey:"area"},{key:"documentation_url",labelKey:"documentation_url_label"},{key:"notes",labelKey:"object_notes_label"},{key:"task_count",labelKey:"tasks"},{key:"actions",labelKey:"actions"}],i=l.map(a=>a.key),r=["name","manufacturer","model","serial_number","installation_date","warranty_expiry","area_id","task_count","actions"];function o(a){if(!Array.isArray(a))return[...r];let t=new Set,e=[];for(let n of a)typeof n=="string"&&i.includes(n)&&!t.has(n)&&(t.add(n),e.push(n));return e.length?(e.includes("name")||e.unshift("name"),e):[...r]}export{l as a,r as b,o as c};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,88 @@
/*! maintenance_supporter frontend 2.87.0 */
import{A as m,a,b as y,c as s,f as l,h as g,l as o,m as f,q as d}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-BFRW5MGC.js";function $(n){let t=m("2001-02-03",n).match(/\d+/g)||[],e=v=>t.findIndex(_=>Number(_)===v),h=e(2001),c=e(2),u=e(3);return h===0?"YMD":c>=0&&u>=0&&c<u?"MDY":"DMY"}function p(n,i,t){if(n<1e3||n>9999||i<1||i>12||t<1||t>31)return null;let e=new Date(n,i-1,t);return e.getFullYear()!==n||e.getMonth()!==i-1||e.getDate()!==t?null:`${n}-${String(i).padStart(2,"0")}-${String(t).padStart(2,"0")}`}function b(n,i){let t=n.trim(),e;if(e=t.match(/^(\d{4})-(\d{1,2})-(\d{1,2})$/))return p(+e[1],+e[2],+e[3]);if(e=t.match(/^(\d{4})$/))return p(+e[1],1,1);if(e=t.match(/^(\d{1,2})[./](\d{4})$/))return p(+e[2],+e[1],1);if(e=t.match(/^(\d{1,2})\.(\d{1,2})\.(\d{4})$/))return p(+e[3],+e[2],+e[1]);if(e=t.match(/^(\d{1,2})[/-](\d{1,2})[/-](\d{4})$/)){let h=+e[1],c=+e[2],u=+e[3];return $(i)==="MDY"?p(u,h,c):p(u,c,h)}return null}function x(n,i){if(i)switch(n){case"date":return i.split("T")[0];case"time":return i.length===5?`${i}:00`:i;case"datetime":{let[t,e="00:00:00"]=i.split("T");return`${t} ${e.length===5?`${e}:00`:e}`}}}function k(n,i){if(typeof i!="string"||!i)return"";switch(n){case"date":return i.slice(0,10);case"time":return i.slice(0,5);case"datetime":{let[t,e="00:00:00"]=i.split(" ");return`${t}T${e.length===5?`${e}:00`:e}`}}}var r=class extends g{constructor(){super(...arguments);this.kind="date";this.label="";this.value="";this.clearable=!1;this.disabled=!1;this.required=!1;this.lang="en";this._typing=!1;this._typed="";this._typedInvalid=!1}_startTyping(){this._typed=this.value,this._typedInvalid=!1,this._typing=!0,this.updateComplete.then(()=>this.shadowRoot?.querySelector("input.typed")?.focus())}_commitTyped(){if(!this._typed.trim()){this._typing=!1;return}let t=b(this._typed,this.lang);if(!t){this._typedInvalid=!0;return}this._typing=!1,this._typedInvalid=!1,this._emit(t)}_onTypedKey(t){t.key==="Enter"?(t.preventDefault(),this._commitTyped()):t.key==="Escape"&&(t.preventDefault(),this._typing=!1,this._typedInvalid=!1)}_selector(){switch(this.kind){case"date":return{date:{}};case"time":return{time:{no_second:!0}};case"datetime":return{datetime:{}}}}_onSelectorChange(t){t.stopPropagation(),this._emit(k(this.kind,t.detail?.value))}_clear(){this._emit("")}_emit(t){t!==this.value&&(this.value=t,this.dispatchEvent(new CustomEvent("value-changed",{bubbles:!0,composed:!0,detail:{value:t}})))}render(){return s`
<div class="field">
${this.label?s`<span class="label">${this.label}${this.required?s`<span class="req">*</span>`:l}</span>`:l}
<div class="row">
${this._typing?s`<input class="typed" type="text" inputmode="numeric" autocomplete="off"
.value=${this._typed}
placeholder=${m("1978-03-15",this.lang)}
aria-invalid=${this._typedInvalid?"true":"false"}
@input=${t=>{this._typed=t.target.value,this._typedInvalid=!1}}
@keydown=${this._onTypedKey}
@blur=${this._commitTyped} />`:s`<ha-selector
.hass=${this.hass}
.selector=${this._selector()}
.value=${x(this.kind,this.value)}
.required=${this.required}
.disabled=${this.disabled}
@value-changed=${this._onSelectorChange}
></ha-selector>`}
${this.kind==="date"&&!this.disabled&&!this._typing?s`<button type="button" class="type-toggle" title=${d("date_type_toggle",this.lang)} aria-label=${d("date_type_toggle",this.lang)} @click=${this._startTyping}>
<ha-icon icon="mdi:keyboard-outline"></ha-icon>
</button>`:l}
${this.clearable&&this.value&&!this.disabled&&!this._typing?s`<button type="button" class="clear" title=${d("clear",this.lang)} aria-label=${d("clear",this.lang)} @click=${this._clear}>
<ha-icon icon="mdi:close"></ha-icon>
</button>`:l}
</div>
${this._typedInvalid?s`<span class="helper invalid">${d("date_type_invalid",this.lang)}</span>`:this.helper?s`<span class="helper">${this.helper}</span>`:l}
</div>
`}};r.styles=y`
:host { display: block; }
.field {
display: flex;
flex-direction: column;
gap: 4px;
}
.label {
font-size: 12px;
color: var(--secondary-text-color, #888);
font-weight: 500;
}
.req { color: var(--error-color, #f44336); margin-left: 2px; }
.row {
display: flex;
align-items: center;
gap: 4px;
}
ha-selector {
flex: 1;
min-width: 0;
}
.clear, .type-toggle {
flex: none;
display: inline-flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
padding: 0;
border: none;
border-radius: 50%;
background: transparent;
color: var(--secondary-text-color);
cursor: pointer;
--mdc-icon-size: 20px;
}
.clear:hover, .type-toggle:hover { background: rgba(var(--rgb-primary-text-color, 0, 0, 0), 0.08); }
.clear:focus-visible, .type-toggle:focus-visible { outline: 2px solid var(--primary-color); }
.helper {
font-size: 11px;
color: var(--secondary-text-color);
font-style: italic;
}
.helper.invalid { color: var(--error-color, #f44336); font-style: normal; }
input.typed {
flex: 1;
min-width: 0;
height: 40px;
box-sizing: border-box;
padding: 0 12px;
border: 1px solid var(--divider-color, #ccc);
border-radius: 4px;
background: var(--card-background-color, #fff);
color: var(--primary-text-color);
font: inherit;
}
input.typed[aria-invalid="true"] { border-color: var(--error-color, #f44336); }
input.typed:focus { outline: 2px solid var(--primary-color); outline-offset: -1px; }
`,a([o({attribute:!1})],r.prototype,"hass",2),a([o()],r.prototype,"kind",2),a([o()],r.prototype,"label",2),a([o()],r.prototype,"value",2),a([o()],r.prototype,"helper",2),a([o({type:Boolean})],r.prototype,"clearable",2),a([o({type:Boolean})],r.prototype,"disabled",2),a([o({type:Boolean})],r.prototype,"required",2),a([o()],r.prototype,"lang",2),a([f()],r.prototype,"_typing",2),a([f()],r.prototype,"_typed",2),a([f()],r.prototype,"_typedInvalid",2);customElements.get("ms-date-field")||customElements.define("ms-date-field",r);
File diff suppressed because one or more lines are too long
@@ -0,0 +1,2 @@
/*! maintenance_supporter frontend 2.87.0 */
import{q as p}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-BFRW5MGC.js";function f(r){return`${r.entry_id??""}\0${r.part_id}`}function g(r,n,i,o){let t=!!r.entry_id&&r.entry_id!==n,e=t?r.entry_id:n,s=i.find(l=>l.entry_id===e),a=(s?.parts||[]).find(l=>l.id===r.part_id)||null,u=t&&s?.object?.name||"",d=a?.name||p("shared_part_unknown",o);return{part:a,foreign:t,ownerName:u,label:u?`${d} (${u})`:d}}function _(r,n,i,o){let{part:t,label:e}=g(r,n,i,o),s=t&&t.stock!==null&&t.stock!==void 0?` (${t.stock}${t.unit?" "+t.unit:""})`:"",a=t?.storage_location?` \u2014 ${t.storage_location}`:"";return`${r.quantity}\xD7 ${e}${s}${a}`}function R(r,n,i,o){let e=(i.find(a=>a.entry_id===n)?.parts||[]).map(a=>({...a})),s=new Set(e.map(a=>f({part_id:a.id})));for(let a of r?.consumes_parts||[]){if(!a.entry_id||a.entry_id===n)continue;let u=f(a);if(s.has(u))continue;s.add(u);let{part:d,ownerName:l}=g(a,n,i,o);e.push({id:a.part_id,name:d?.name||p("shared_part_unknown",o),unit:d?.unit,stock:d?.stock??null,storage_location:d?.storage_location,entry_id:a.entry_id,owner_name:l})}return e}function w(){let r=new Uint8Array(4);return(globalThis.crypto??{getRandomValues:n=>n.map(()=>Math.floor(Math.random()*256))}).getRandomValues(r),Array.from(r,n=>n.toString(16).padStart(2,"0")).join("")}function c(r){let n=r?.reading_values;if(!Array.isArray(n))return[];let i=[],o=new Set;for(let t of n){if(!t||typeof t!="object")continue;let e=t;typeof e.id!="string"||!e.id||o.has(e.id)||typeof e.value!="number"||!Number.isFinite(e.value)||(o.add(e.id),i.push({id:e.id,name:typeof e.name=="string"?e.name:e.id,unit:typeof e.unit=="string"?e.unit:null,value:e.value}))}return i}function y(r){return r.filter(n=>n.type==="completed"&&(n.reading_value!=null||c(n).length>0)).sort((n,i)=>n.timestamp.localeCompare(i.timestamp))}function S(r){return y(r??[]).map(n=>({timestamp:n.timestamp,values:c(n)})).filter(n=>n.values.length>0)}function P(r,n,i){let o;for(let t of r){if(i!==void 0){let s=new Date(t.timestamp).getTime();if(!isNaN(s)&&s>=i)break}let e=t.values.find(s=>s.id===n);e&&(o=e)}return o}function b(r,n,i){let o=c(n).find(e=>e.id===i);if(!o)return null;let t=null;for(let e of y(r)){if(e.timestamp>=n.timestamp)break;let s=c(e).find(a=>a.id===i);s&&(t=s.value)}return t==null?null:o.value-t}function E(r){let n=new Set,i=new Set;for(let o of r){let t=(o.name||"").trim().toLowerCase();t&&(n.has(t)?i.add(o.id):n.add(t))}return i}function v(r){let n=[],i=new Set,o=new Set;for(let t of r){let e=(t.name||"").trim();if(!(!e||i.has(t.id)||o.has(e.toLowerCase()))&&(i.add(t.id),o.add(e.toLowerCase()),n.push({id:t.id,name:e,unit:(t.unit||"").trim()||null}),n.length>=20))break}return n}var x=["notes","cost","duration","photo","user"],h={notes:"notes_label",cost:"cost",duration:"duration",photo:"photo_label",user:"user_label"};export{f as a,_ as b,R as c,w as d,c as e,S as f,P as g,b as h,E as i,v as j,x as k,h as l};
@@ -0,0 +1,2 @@
/*! maintenance_supporter frontend 2.87.0 */
import{i as a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-R7OIT4C5.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-XXGPRYJO.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-WZP72YIY.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-6FKJJO4T.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-BFRW5MGC.js";export{a as MaintenanceCompleteDialog};
@@ -0,0 +1,2 @@
/*! maintenance_supporter frontend 2.87.0 */
import{F as a,G as b,H as c,I as d,J as e,K as f,L as g,M as h,N as i,O as j,P as k}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-X5NUHJD3.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-OMI4RPEK.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-GRODOZHK.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-AZKZNFFK.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-A2LPO2HZ.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-AN3A6RAI.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-R7OIT4C5.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-XXGPRYJO.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-WZP72YIY.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-FS7VLXOK.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-NOXOKE42.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-KRAXVQN3.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-6FKJJO4T.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-BFRW5MGC.js";export{b as __resetSettingsCacheForTests,a as getRowActionStyle,h as openCompleteDialog,c as openCreateObjectDialog,e as openCreateTaskDialog,d as openEditObjectDialog,f as openEditTaskDialog,g as openHistoryEditDialog,k as openObjectQuickActions,i as openQrDialog,j as openTaskQuickActions};
@@ -0,0 +1,2 @@
/*! maintenance_supporter frontend 2.87.0 */
import{a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-GRODOZHK.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-AN3A6RAI.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-WZP72YIY.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-6FKJJO4T.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-BFRW5MGC.js";export{a as MaintenanceObjectDialog};
@@ -0,0 +1,2 @@
/*! maintenance_supporter frontend 2.87.0 */
import{a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-FS7VLXOK.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-NOXOKE42.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-BFRW5MGC.js";export{a as MaintenanceQrDialog};
File diff suppressed because one or more lines are too long
@@ -0,0 +1,146 @@
/*! maintenance_supporter frontend 2.87.0 */
import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-6FKJJO4T.js";import{a as l,b as m,c as i,f as h,h as v,l as u,m as d,q as p,s as f,u as x}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-BFRW5MGC.js";var a=class extends v{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._setups=[];this._selected=new Set;this._baselines=new Map;this._targets=new Map;this._objects=[];this._localeReady=!1;this._toggle=t=>{let e=new Set(this._selected);e.has(t)?e.delete(t):e.add(t),this._selected=e};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/adopt",selections:[...this._selected].map(e=>{let r={device_id:e},c=this._targets.get(e);c&&(r.entry_id=c);let s=this._setups.find(n=>n.device_id===e);for(let n of s?.tasks??[]){let o=this._baselines.get(`${e} ${n.task_name}`),_=o?parseFloat(o):NaN;!isNaN(_)&&_>=0&&((r.baselines??={})[n.task_name]=_)}return r})});this.dispatchEvent(new CustomEvent("integration-setups-adopted",{bubbles:!0,composed:!0,detail:t})),this._open=!1}catch(t){this._error=g(t,this._lang)}finally{this._adopting=!1}}}}get _lang(){return f(this.hass)}updated(t){t.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,x(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._setups=[],this._selected=new Set;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/discover"});this._setups=t.setups||[],this._selected=new Set(this._setups.map(e=>e.device_id)),this._baselines=new Map,this._targets=new Map;try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/objects"});this._objects=(e.objects||[]).map(r=>({entry_id:r.entry_id,name:r.object?.name||r.entry_id})).sort((r,c)=>r.name.localeCompare(c.name))}catch{this._objects=[]}}catch(t){this._error=g(t,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return i``;let t=this._lang;return i`
<div class="overlay" @click=${this._close}>
<div class="card" @click=${e=>e.stopPropagation()}>
<div class="title">${p("setups_title",t)}</div>
<div class="hint">${p("setups_hint",t)}</div>
${this._error?i`<div class="error">${this._error}</div>`:h}
${this._loading?i`<div class="loading">…</div>`:this._setups.length===0?i`<div class="empty">${p("setups_none",t)}</div>`:i`
<div class="list">
${this._setups.map(e=>{let r=this._selected.has(e.device_id),c=[e.integration_name,e.area_name].filter(Boolean).join(" \xB7 ");return i`
<label class="row">
<input
type="checkbox"
.checked=${r}
@change=${()=>this._toggle(e.device_id)}
/>
<div class="row-main">
<div class="row-top">
<span class="row-name">${e.device_name}</span>
</div>
<div class="row-sub">${c}</div>
<div class="row-target" @click=${s=>s.preventDefault()}>
→
${r&&this._objects.length>0?i`
<select
class="target-select"
@change=${s=>{let n=new Map(this._targets),o=s.target.value;o?n.set(e.device_id,o):n.delete(e.device_id),this._targets=n}}
>
<option value="" ?selected=${!this._targets.get(e.device_id)}>
${e.suggested_entry_id?e.suggested_object_name:p("setups_target_new",t).replace("{name}",e.suggested_object_name)}
</option>
${this._objects.filter(s=>s.entry_id!==e.suggested_entry_id).map(s=>i`<option
value=${s.entry_id}
?selected=${this._targets.get(e.device_id)===s.entry_id}
>
${s.name}
</option>`)}
</select>
`:i`${e.suggested_object_name}${e.suggested_entry_id?h:i` <span class="new-tag">${p("adopt_problem_new_object",t)}</span>`}`}
</div>
<div class="row-tasks">
${e.tasks.map(s=>i`<span class="chip" title=${s.entity_ids.join(", ")}>
<ha-icon icon="mdi:link-variant"></ha-icon>${s.task_name_localized||s.task_name}
</span>`)}
</div>
${r?e.tasks.filter(s=>s.direction==="usage_delta").map(s=>{let n=`${e.device_id} ${s.task_name}`;return i`
<div class="baseline-field" @click=${o=>o.preventDefault()}>
<span class="baseline-label"
>${s.task_name_localized||s.task_name} —
${p("setups_baseline_hint",t)}</span
>
<input
type="number"
step="any"
min="0"
.value=${this._baselines.get(n)??""}
@click=${o=>o.preventDefault()}
@input=${o=>{let _=new Map(this._baselines);_.set(n,o.target.value),this._baselines=_}}
/>
</div>
`}):h}
</div>
</label>
`})}
</div>
`}
<div class="actions">
<ha-button appearance="plain" @click=${this._close}>
${p("cancel",t)}
</ha-button>
<ha-button
@click=${this._adopt}
.disabled=${this._selected.size===0||this._adopting}
>
${p("setups_adopt",t)}
</ha-button>
</div>
</div>
</div>
`}};a.styles=m`
.overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.card {
background: var(--card-background-color, #fff);
color: var(--primary-text-color);
border-radius: 12px;
padding: 20px;
display: flex;
flex-direction: column;
gap: 12px;
min-width: min(360px, calc(100vw - 24px));
max-width: 560px;
width: 90vw;
max-height: 80vh;
overflow: hidden;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}
.title { font-size: 18px; font-weight: 500; }
.hint { color: var(--secondary-text-color); font-size: 13px; }
.error { color: var(--error-color, #f44336); font-size: 13px; }
.loading, .empty { color: var(--secondary-text-color); font-size: 14px; padding: 12px 0; }
.list { display: flex; flex-direction: column; gap: 6px; overflow-y: auto; max-height: 50vh; }
.row {
display: flex; align-items: flex-start; gap: 10px; padding: 8px;
border: 1px solid var(--divider-color); border-radius: 6px; cursor: pointer;
}
.row input { margin-top: 2px; cursor: pointer; }
.row-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.row-name { font-weight: 500; font-size: 13px; }
.row-sub, .row-target { color: var(--secondary-text-color); font-size: 12px; }
.new-tag { font-style: italic; }
.row-tasks { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 2px; }
.chip {
display: inline-flex; align-items: center; gap: 4px;
font-size: 11px; padding: 2px 8px; border-radius: 10px;
background: var(--secondary-background-color, rgba(0, 0, 0, 0.06));
color: var(--primary-text-color); white-space: nowrap;
}
.chip ha-icon { --mdc-icon-size: 12px; color: var(--primary-color); }
.target-select {
font-size: 12px; padding: 2px 4px; max-width: 100%;
border: 1px solid var(--divider-color); border-radius: 4px;
background: var(--card-background-color, #fff);
color: var(--primary-text-color);
}
.baseline-field {
display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
margin-top: 4px; font-size: 12px; color: var(--secondary-text-color);
}
.baseline-field input {
width: 110px; padding: 3px 6px; font-size: 12px;
border: 1px solid var(--divider-color); border-radius: 4px;
background: var(--card-background-color, #fff);
color: var(--primary-text-color);
}
.actions { display: flex; justify-content: flex-end; gap: 8px; padding-top: 8px; }
`,l([u({attribute:!1})],a.prototype,"hass",2),l([d()],a.prototype,"_open",2),l([d()],a.prototype,"_loading",2),l([d()],a.prototype,"_adopting",2),l([d()],a.prototype,"_error",2),l([d()],a.prototype,"_setups",2),l([d()],a.prototype,"_selected",2),l([d()],a.prototype,"_baselines",2),l([d()],a.prototype,"_targets",2),l([d()],a.prototype,"_objects",2);customElements.get("maintenance-suggested-setups-dialog")||customElements.define("maintenance-suggested-setups-dialog",a);export{a as MaintenanceSuggestedSetupsDialog};
@@ -0,0 +1,2 @@
/*! maintenance_supporter frontend 2.87.0 */
import{a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-AZKZNFFK.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-A2LPO2HZ.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-AN3A6RAI.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-XXGPRYJO.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-WZP72YIY.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-KRAXVQN3.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-6FKJJO4T.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-BFRW5MGC.js";export{a as MaintenanceTaskDialog};
@@ -0,0 +1,125 @@
/*! maintenance_supporter frontend 2.87.0 */
import{a as x,b as $}from"./chunk-TY5VMGUH.js";import{B as p,a as h,b as l,d as b,e as y,f as m,g as o,h as g,i as a,j as v,k as _,n as f,q as d}from"./chunk-A7GYNFDF.js";import{a as n}from"./chunk-APM7GQQR.js";var E=80,e=class extends y{constructor(){super(...arguments);this._config={type:""};this._status=null;this._busy=!1;this._error="";this._localMonthly="";this._localYearly="";this._dirty=!1;this._loaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return _(this.hass)}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),v(this,t),t.has("hass")&&this.hass&&!this._loaded&&(this._loaded=!0,this._load())}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/budget_status"});this._status=t,f(t),this._localMonthly=t.monthly_budget?String(t.monthly_budget):"",this._localYearly=t.yearly_budget?String(t.yearly_budget):"",this._dirty=!1}catch(t){this._error=p(t,this._lang)}}async _save(){if(this._isAdmin){this._busy=!0,this._error="";try{let t=this._localMonthly.trim()===""?0:parseFloat(this._localMonthly),r=this._localYearly.trim()===""?0:parseFloat(this._localYearly),i={};!isNaN(t)&&t>=0&&(i.budget_monthly=t),!isNaN(r)&&r>=0&&(i.budget_yearly=r),await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/update",settings:i}),await this._load()}catch(t){this._error=p(t,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_budget"),window.dispatchEvent(new CustomEvent("location-changed"))}render(){let t=this._lang,r=this._status;if(!r)return l`<ha-card><div class="loading">${a("loading",t)}</div></ha-card>`;let i=g(r),k=r.alert_threshold_pct??E,w=[{label:a("budget_monthly",t),spent:r.monthly_spent||0,budget:r.monthly_budget||0},{label:a("budget_yearly",t),spent:r.yearly_spent||0,budget:r.yearly_budget||0}];return l`
<ha-card>
<div class="card-content">
<div class="header">
<div class="title">
<span class="emoji">💰</span>
<span>${this._config.title||a("settings_budget",t)}</span>
</div>
<span class="currency">${i}</span>
</div>
${this._error?l`<div class="error">${this._error}</div>`:b}
${w.map(s=>{if(!(s.budget>0))return l`
<div class="track spent-only">
<div class="track-label-row">
<label>${s.label}</label>
<span class="track-numbers ok">${d(s.spent,i,t)}</span>
</div>
</div>
`;let c=Math.min(100,Math.max(0,s.spent/s.budget*100)),u=c>=100?"danger":c>=k?"warning":"ok";return l`
<div class="track">
<div class="track-label-row">
<label>${s.label}</label>
<span class="track-numbers ${u}">
${d(s.spent,void 0,t)} / ${d(s.budget,i,t)}
</span>
</div>
<div class="bar"><div class="bar-fill ${u}" style="width:${c}%"></div></div>
</div>
`})}
${this._isAdmin?l`
<div class="inputs-row">
<div class="input-field">
<label>${a("budget_monthly_set",t)}</label>
<div class="input-wrap">
<input type="number" min="0" step="1"
.value=${this._localMonthly}
?disabled=${this._busy}
@input=${s=>{this._localMonthly=s.target.value,this._dirty=!0}} />
<span class="input-suffix">${i}</span>
</div>
</div>
<div class="input-field">
<label>${a("budget_yearly_set",t)}</label>
<div class="input-wrap">
<input type="number" min="0" step="1"
.value=${this._localYearly}
?disabled=${this._busy}
@input=${s=>{this._localYearly=s.target.value,this._dirty=!0}} />
<span class="input-suffix">${i}</span>
</div>
</div>
</div>
<div class="actions">
<button class="btn ${this._dirty?"primary":"muted"}"
@click=${this._save}
?disabled=${this._busy||!this._dirty}>
<ha-icon icon="${this._dirty?"mdi:content-save":"mdi:check"}"></ha-icon>
${this._dirty?a("save",t):a("saved",t)}
</button>
<button class="btn link" @click=${this._onDeepLink}>
${a("budget_advanced",t)}
</button>
</div>
`:l`
<button class="btn link" @click=${this._onDeepLink}>
${a("budget_open_panel",t)}
</button>
`}
</div>
</ha-card>
`}};e.styles=[$,h`
.currency {
font-size: 14px; font-weight: 600;
color: var(--secondary-text-color);
background: var(--secondary-background-color);
padding: 2px 10px; border-radius: 999px;
}
.track { display: flex; flex-direction: column; gap: 4px; }
.track-label-row {
display: flex; align-items: center; justify-content: space-between;
}
.track-label-row label {
font-size: 12px; color: var(--secondary-text-color);
text-transform: uppercase; letter-spacing: 0.5px;
}
.track-numbers { font-size: 13px; font-weight: 600; }
.track-numbers.ok { color: var(--primary-text-color); }
.track-numbers.warning { color: #ff9800; }
.track-numbers.danger { color: var(--error-color, #f44336); }
.bar {
height: 6px; background: var(--secondary-background-color);
border-radius: 3px; overflow: hidden;
}
.bar-fill { height: 100%; transition: width 0.3s; border-radius: 3px; }
.bar-fill.ok { background: var(--primary-color); }
.bar-fill.warning { background: #ff9800; }
.bar-fill.danger { background: var(--error-color, #f44336); }
.inputs-row {
display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
padding-top: 4px; border-top: 1px solid var(--divider-color);
}
.input-field { display: flex; flex-direction: column; gap: 4px; }
.input-field label {
font-size: 11px; color: var(--secondary-text-color);
text-transform: uppercase; letter-spacing: 0.3px;
}
.input-wrap { position: relative; display: flex; align-items: center; }
.input-wrap input {
flex: 1; padding: 6px 32px 6px 8px; font-size: 13px;
background: var(--secondary-background-color, #2c2c2c);
color: var(--primary-text-color);
border: 1px solid var(--divider-color); border-radius: 6px;
font-family: inherit;
}
.input-suffix {
position: absolute; right: 8px;
color: var(--secondary-text-color); font-size: 13px;
pointer-events: none;
}
.actions { display: flex; gap: 8px; align-items: center; }
`],n([m({attribute:!1})],e.prototype,"hass",2),n([o()],e.prototype,"_config",2),n([o()],e.prototype,"_status",2),n([o()],e.prototype,"_busy",2),n([o()],e.prototype,"_error",2),n([o()],e.prototype,"_localMonthly",2),n([o()],e.prototype,"_localYearly",2),n([o()],e.prototype,"_dirty",2);customElements.get("maintenance-budget-section-card")||customElements.define("maintenance-budget-section-card",e);x({type:"maintenance-budget-section-card",name:"Maintenance Supporter \u2014 Budget",description:"Inline monthly + yearly budget editor",preview:!1});export{e as MaintenanceBudgetSectionCard};
File diff suppressed because one or more lines are too long
@@ -0,0 +1,2 @@
/*! maintenance_supporter frontend 2.87.0 */
var s=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var t=(a,r,c,o)=>{for(var e=o>1?void 0:o?l(r,c):r,i=a.length-1,d;i>=0;i--)(d=a[i])&&(e=(o?d(r,c,e):d(e))||e);return o&&e&&s(r,c,e),e};var m={ok:"var(--success-color, #4caf50)",due_soon:"var(--warning-color, #ff9800)",overdue:"var(--error-color, #f44336)",triggered:"var(--deep-orange-color, #ff5722)",archived:"var(--disabled-color, #9e9e9e)",paused:"var(--info-color, #2196f3)"},v={ok:"mdi:check-circle",due_soon:"mdi:alert-circle",overdue:"mdi:alert-octagon",triggered:"mdi:bell-alert",archived:"mdi:archive-outline",paused:"mdi:pause-circle-outline",completed:"mdi:check-circle",skipped:"mdi:skip-next",missed:"mdi:calendar-remove",reset:"mdi:refresh"};export{t as a,m as b,v as c};
@@ -0,0 +1,2 @@
/*! maintenance_supporter frontend 2.87.0 */
function l(r){if(!r)return[];let n=[],i=r.photo_doc_id;typeof i=="string"&&n.push(i);let o=r.photo_doc_ids;Array.isArray(o)&&n.push(...o);let t=[];for(let e of n){if(typeof e!="string")continue;let s=e.trim();if(!(!s||t.includes(s))&&(t.push(s),t.length>=10))break}return t}function f(){let r=new Uint8Array(4);return(globalThis.crypto??{getRandomValues:n=>n.map(()=>Math.floor(Math.random()*256))}).getRandomValues(r),Array.from(r,n=>n.toString(16).padStart(2,"0")).join("")}function u(r){let n=r?.reading_values;if(!Array.isArray(n))return[];let i=[],o=new Set;for(let t of n){if(!t||typeof t!="object")continue;let e=t;typeof e.id!="string"||!e.id||o.has(e.id)||typeof e.value!="number"||!Number.isFinite(e.value)||(o.add(e.id),i.push({id:e.id,name:typeof e.name=="string"?e.name:e.id,unit:typeof e.unit=="string"?e.unit:null,value:e.value}))}return i}function c(r){return r.filter(n=>n.type==="completed"&&(n.reading_value!=null||u(n).length>0)).sort((n,i)=>n.timestamp.localeCompare(i.timestamp))}function p(r){return c(r??[]).map(n=>({timestamp:n.timestamp,values:u(n)})).filter(n=>n.values.length>0)}function m(r,n,i){let o;for(let t of r){if(i!==void 0){let s=new Date(t.timestamp).getTime();if(!isNaN(s)&&s>=i)break}let e=t.values.find(s=>s.id===n);e&&(o=e)}return o}function _(r,n,i){let o=u(n).find(e=>e.id===i);if(!o)return null;let t=null;for(let e of c(r)){if(e.timestamp>=n.timestamp)break;let s=u(e).find(a=>a.id===i);s&&(t=s.value)}return t==null?null:o.value-t}function R(r){let n=new Set,i=new Set;for(let o of r){let t=(o.name||"").trim().toLowerCase();t&&(n.has(t)?i.add(o.id):n.add(t))}return i}function h(r){let n=[],i=new Set,o=new Set;for(let t of r){let e=(t.name||"").trim();if(!(!e||i.has(t.id)||o.has(e.toLowerCase()))&&(i.add(t.id),o.add(e.toLowerCase()),n.push({id:t.id,name:e,unit:(t.unit||"").trim()||null}),n.length>=20))break}return n}function g(r,n,i,o){let t=i,e=d=>typeof d=="string"?d:null,s=d=>typeof d=="number"?d:null,a=e(t.timestamp)??"";return{entry_id:r,task_id:n,original_timestamp:a,type:e(t.type)||"completed",timestamp:a,notes:e(t.notes),cost:s(t.cost),duration:s(t.duration),completed_by:e(t.completed_by),used_parts:Array.isArray(t.used_parts)?t.used_parts:null,photo_doc_ids:l(t),reading_value:s(t.reading_value),reading_values:u(t),readings:o?.readings??[],task_type:o?.type??null,reading_unit:o?.reading_unit??null}}async function E(r,n,i,o){let e=(await r.connection.sendMessagePromise({type:"maintenance_supporter/object",entry_id:n})).tasks?.find(a=>a.id===i),s=e?.history?.find(a=>a.timestamp===o);return!e||!s?null:g(n,i,s,e)}export{l as a,f as b,u as c,p as d,m as e,_ as f,R as g,h,g as i,E as j};
@@ -0,0 +1,88 @@
/*! maintenance_supporter frontend 2.87.0 */
import{a as y,b as s,d as l,e as g,f as o,g as f,i as d,r as m}from"./chunk-A7GYNFDF.js";import{a}from"./chunk-APM7GQQR.js";function $(n){let t=m("2001-02-03",n).match(/\d+/g)||[],e=v=>t.findIndex(_=>Number(_)===v),h=e(2001),c=e(2),u=e(3);return h===0?"YMD":c>=0&&u>=0&&c<u?"MDY":"DMY"}function p(n,i,t){if(n<1e3||n>9999||i<1||i>12||t<1||t>31)return null;let e=new Date(n,i-1,t);return e.getFullYear()!==n||e.getMonth()!==i-1||e.getDate()!==t?null:`${n}-${String(i).padStart(2,"0")}-${String(t).padStart(2,"0")}`}function b(n,i){let t=n.trim(),e;if(e=t.match(/^(\d{4})-(\d{1,2})-(\d{1,2})$/))return p(+e[1],+e[2],+e[3]);if(e=t.match(/^(\d{4})$/))return p(+e[1],1,1);if(e=t.match(/^(\d{1,2})[./](\d{4})$/))return p(+e[2],+e[1],1);if(e=t.match(/^(\d{1,2})\.(\d{1,2})\.(\d{4})$/))return p(+e[3],+e[2],+e[1]);if(e=t.match(/^(\d{1,2})[/-](\d{1,2})[/-](\d{4})$/)){let h=+e[1],c=+e[2],u=+e[3];return $(i)==="MDY"?p(u,h,c):p(u,c,h)}return null}function x(n,i){if(i)switch(n){case"date":return i.split("T")[0];case"time":return i.length===5?`${i}:00`:i;case"datetime":{let[t,e="00:00:00"]=i.split("T");return`${t} ${e.length===5?`${e}:00`:e}`}}}function k(n,i){if(typeof i!="string"||!i)return"";switch(n){case"date":return i.slice(0,10);case"time":return i.slice(0,5);case"datetime":{let[t,e="00:00:00"]=i.split(" ");return`${t}T${e.length===5?`${e}:00`:e}`}}}var r=class extends g{constructor(){super(...arguments);this.kind="date";this.label="";this.value="";this.clearable=!1;this.disabled=!1;this.required=!1;this.lang="en";this._typing=!1;this._typed="";this._typedInvalid=!1}_startTyping(){this._typed=this.value,this._typedInvalid=!1,this._typing=!0,this.updateComplete.then(()=>this.shadowRoot?.querySelector("input.typed")?.focus())}_commitTyped(){if(!this._typed.trim()){this._typing=!1;return}let t=b(this._typed,this.lang);if(!t){this._typedInvalid=!0;return}this._typing=!1,this._typedInvalid=!1,this._emit(t)}_onTypedKey(t){t.key==="Enter"?(t.preventDefault(),this._commitTyped()):t.key==="Escape"&&(t.preventDefault(),this._typing=!1,this._typedInvalid=!1)}_selector(){switch(this.kind){case"date":return{date:{}};case"time":return{time:{no_second:!0}};case"datetime":return{datetime:{}}}}_onSelectorChange(t){t.stopPropagation(),this._emit(k(this.kind,t.detail?.value))}_clear(){this._emit("")}_emit(t){t!==this.value&&(this.value=t,this.dispatchEvent(new CustomEvent("value-changed",{bubbles:!0,composed:!0,detail:{value:t}})))}render(){return s`
<div class="field">
${this.label?s`<span class="label">${this.label}${this.required?s`<span class="req">*</span>`:l}</span>`:l}
<div class="row">
${this._typing?s`<input class="typed" type="text" inputmode="numeric" autocomplete="off"
.value=${this._typed}
placeholder=${m("1978-03-15",this.lang)}
aria-invalid=${this._typedInvalid?"true":"false"}
@input=${t=>{this._typed=t.target.value,this._typedInvalid=!1}}
@keydown=${this._onTypedKey}
@blur=${this._commitTyped} />`:s`<ha-selector
.hass=${this.hass}
.selector=${this._selector()}
.value=${x(this.kind,this.value)}
.required=${this.required}
.disabled=${this.disabled}
@value-changed=${this._onSelectorChange}
></ha-selector>`}
${this.kind==="date"&&!this.disabled&&!this._typing?s`<button type="button" class="type-toggle" title=${d("date_type_toggle",this.lang)} aria-label=${d("date_type_toggle",this.lang)} @click=${this._startTyping}>
<ha-icon icon="mdi:keyboard-outline"></ha-icon>
</button>`:l}
${this.clearable&&this.value&&!this.disabled&&!this._typing?s`<button type="button" class="clear" title=${d("clear",this.lang)} aria-label=${d("clear",this.lang)} @click=${this._clear}>
<ha-icon icon="mdi:close"></ha-icon>
</button>`:l}
</div>
${this._typedInvalid?s`<span class="helper invalid">${d("date_type_invalid",this.lang)}</span>`:this.helper?s`<span class="helper">${this.helper}</span>`:l}
</div>
`}};r.styles=y`
:host { display: block; }
.field {
display: flex;
flex-direction: column;
gap: 4px;
}
.label {
font-size: 12px;
color: var(--secondary-text-color, #888);
font-weight: 500;
}
.req { color: var(--error-color, #f44336); margin-left: 2px; }
.row {
display: flex;
align-items: center;
gap: 4px;
}
ha-selector {
flex: 1;
min-width: 0;
}
.clear, .type-toggle {
flex: none;
display: inline-flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
padding: 0;
border: none;
border-radius: 50%;
background: transparent;
color: var(--secondary-text-color);
cursor: pointer;
--mdc-icon-size: 20px;
}
.clear:hover, .type-toggle:hover { background: rgba(var(--rgb-primary-text-color, 0, 0, 0), 0.08); }
.clear:focus-visible, .type-toggle:focus-visible { outline: 2px solid var(--primary-color); }
.helper {
font-size: 11px;
color: var(--secondary-text-color);
font-style: italic;
}
.helper.invalid { color: var(--error-color, #f44336); font-style: normal; }
input.typed {
flex: 1;
min-width: 0;
height: 40px;
box-sizing: border-box;
padding: 0 12px;
border: 1px solid var(--divider-color, #ccc);
border-radius: 4px;
background: var(--card-background-color, #fff);
color: var(--primary-text-color);
font: inherit;
}
input.typed[aria-invalid="true"] { border-color: var(--error-color, #f44336); }
input.typed:focus { outline: 2px solid var(--primary-color); outline-offset: -1px; }
`,a([o({attribute:!1})],r.prototype,"hass",2),a([o()],r.prototype,"kind",2),a([o()],r.prototype,"label",2),a([o()],r.prototype,"value",2),a([o()],r.prototype,"helper",2),a([o({type:Boolean})],r.prototype,"clearable",2),a([o({type:Boolean})],r.prototype,"disabled",2),a([o({type:Boolean})],r.prototype,"required",2),a([o()],r.prototype,"lang",2),a([f()],r.prototype,"_typing",2),a([f()],r.prototype,"_typed",2),a([f()],r.prototype,"_typedInvalid",2);customElements.get("ms-date-field")||customElements.define("ms-date-field",r);
@@ -0,0 +1,60 @@
/*! maintenance_supporter frontend 2.87.0 */
import{a as t}from"./chunk-A7GYNFDF.js";function e(o){let r=window;r.customCards=r.customCards||[],r.customCards.some(a=>a.type===o.type)||r.customCards.push(o)}var d=t`
ha-card { overflow: hidden; }
.card-content {
padding: 16px;
display: flex; flex-direction: column;
gap: 12px;
}
.header {
display: flex; align-items: center; justify-content: space-between;
gap: 12px;
}
.title {
display: flex; align-items: center; gap: 8px;
font-size: 16px; font-weight: 500;
}
.emoji { font-size: 20px; }
/* Button family — primary action / muted-saved-state / link / icon-with-text */
.btn {
padding: 6px 12px; font-size: 13px;
border-radius: 6px; cursor: pointer;
border: 1px solid var(--divider-color);
background: var(--secondary-background-color, transparent);
color: var(--primary-text-color);
font-weight: 500;
display: inline-flex; align-items: center; gap: 4px;
}
.btn:hover { background: var(--state-icon-color, rgba(255,255,255,0.06)); }
.btn[disabled] { opacity: 0.5; cursor: not-allowed; }
.btn.primary {
background: var(--primary-color);
color: var(--text-primary-color, white);
border-color: var(--primary-color);
}
.btn.primary[disabled] { opacity: 0.6; }
.btn.muted {
background: transparent;
color: var(--secondary-text-color);
border-style: dashed;
}
.btn.muted[disabled] { opacity: 1; cursor: default; }
.btn.muted ha-icon, .btn.primary ha-icon { --mdc-icon-size: 14px; }
.btn.link {
background: transparent; border: none; padding: 6px 4px;
color: var(--primary-color); margin-left: auto;
}
.btn.link:hover { background: transparent; text-decoration: underline; }
/* Error + loading states */
.error {
padding: 8px; border-radius: 6px;
background: rgba(211, 47, 47, 0.1);
color: var(--error-color, #d32f2f); font-size: 13px;
}
.loading {
padding: 24px; text-align: center;
color: var(--secondary-text-color);
}
`;export{e as a,d as b};
File diff suppressed because one or more lines are too long
@@ -0,0 +1,137 @@
/*! maintenance_supporter frontend 2.87.0 */
import{a as v,b}from"./chunk-TY5VMGUH.js";import{B as p,a as u,b as s,d as c,e as h,f as g,g as o,i,k as _,m}from"./chunk-A7GYNFDF.js";import{a}from"./chunk-APM7GQQR.js";var e=class extends h{constructor(){super(...arguments);this._config={type:""};this._groups={};this._loaded=!1;this._busy=!1;this._error="";this._newName="";this._editingId=null;this._editingName="";this._hasInitiallyLoaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return _(this.hass)}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._hasInitiallyLoaded&&(this._hasInitiallyLoaded=!0,this._load(),m(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/groups"});this._groups=t.groups||{},this._loaded=!0}catch(t){this._error=p(t,this._lang)}}async _addGroup(){if(!this._isAdmin)return;let t=this._newName.trim();if(t){this._busy=!0,this._error="";try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/create",name:t}),this._newName="",await this._load()}catch(r){this._error=p(r,this._lang)}finally{this._busy=!1}}}_startEdit(t){this._editingId=t,this._editingName=this._groups[t]?.name||""}async _saveEdit(){if(!this._isAdmin||!this._editingId)return;let t=this._editingName.trim();if(t){this._busy=!0,this._error="";try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/update",group_id:this._editingId,name:t}),this._editingId=null,this._editingName="",await this._load()}catch(r){this._error=p(r,this._lang)}finally{this._busy=!1}}}async _deleteGroup(t,r){if(!this._isAdmin)return;let n=i("group_delete_confirm",this._lang).replace("{name}",r);if(window.confirm(n)){this._busy=!0;try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/delete",group_id:t}),await this._load()}catch(d){this._error=p(d,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_groups"),window.dispatchEvent(new CustomEvent("location-changed"))}_onKeyDown(t,r){t.key==="Enter"?(t.preventDefault(),r()):t.key==="Escape"&&(t.preventDefault(),this._editingId=null,this._editingName="")}render(){let t=this._lang;if(!this._loaded)return s`<ha-card><div class="loading">${i("loading",t)}</div></ha-card>`;let r=Object.keys(this._groups);return s`
<ha-card>
<div class="card-content">
<div class="header">
<div class="title">
<span class="emoji">🏷️</span>
<span>${this._config.title||i("groups",t)}</span>
<span class="count">${r.length}</span>
</div>
</div>
${this._error?s`<div class="error">${this._error}</div>`:c}
${r.length===0?s`<div class="empty">${i("groups_empty",t)}</div>`:s`
<div class="group-list">
${r.map(n=>{let d=this._groups[n],y=d.task_refs?.length??0,f=this._editingId===n;return s`
<div class="group-row">
${f?s`
<input class="edit-input" type="text"
.value=${this._editingName}
?disabled=${this._busy}
@input=${l=>{this._editingName=l.target.value}}
@keydown=${l=>this._onKeyDown(l,this._saveEdit.bind(this))} />
<button class="btn small primary"
@click=${this._saveEdit}
?disabled=${this._busy||!this._editingName.trim()}>
${i("save",t)}
</button>
<button class="btn small"
@click=${()=>{this._editingId=null}}>
${i("cancel",t)}
</button>
`:s`
<span class="group-name">${d.name||"Unnamed"}</span>
<span class="task-count">${y}</span>
${this._isAdmin?s`
<button class="icon-btn"
title="${i("edit",t)}"
@click=${()=>this._startEdit(n)}
?disabled=${this._busy}>
<ha-icon icon="mdi:pencil"></ha-icon>
</button>
<button class="icon-btn danger"
title="${i("delete",t)}"
@click=${()=>this._deleteGroup(n,d.name||"Unnamed")}
?disabled=${this._busy}>
<ha-icon icon="mdi:delete"></ha-icon>
</button>
`:c}
`}
</div>
`})}
</div>
`}
${this._isAdmin?s`
<div class="add-row">
<input type="text"
placeholder="${i("group_new_placeholder",t)}"
.value=${this._newName}
?disabled=${this._busy}
@input=${n=>{this._newName=n.target.value}}
@keydown=${n=>this._onKeyDown(n,this._addGroup.bind(this))} />
<button class="btn primary"
@click=${this._addGroup}
?disabled=${this._busy||!this._newName.trim()}>
<ha-icon icon="mdi:plus"></ha-icon>
${i("add",t)}
</button>
</div>
<button class="btn link" @click=${this._onDeepLink}>
${i("groups_manage_tasks",t)}
</button>
`:s`
<button class="btn link" @click=${this._onDeepLink}>
${i("groups_open_panel",t)}
</button>
`}
</div>
</ha-card>
`}};e.styles=[b,u`
.count {
font-size: 12px; color: var(--secondary-text-color);
background: var(--secondary-background-color);
padding: 2px 8px; border-radius: 999px;
}
.empty {
padding: 16px; text-align: center;
color: var(--secondary-text-color); font-style: italic;
}
.group-list { display: flex; flex-direction: column; gap: 4px; }
.group-row {
display: flex; align-items: center; gap: 8px;
padding: 6px 8px; border-radius: 6px;
background: var(--secondary-background-color, rgba(255,255,255,0.03));
}
.group-name { flex: 1; font-size: 14px; }
.task-count {
font-size: 11px; color: var(--secondary-text-color);
background: var(--card-background-color, rgba(0,0,0,0.2));
padding: 1px 8px; border-radius: 999px;
font-weight: 500;
}
.edit-input {
flex: 1; padding: 4px 8px; font-size: 14px;
background: var(--card-background-color, #1c1c1c);
color: var(--primary-text-color);
border: 1px solid var(--primary-color); border-radius: 4px;
font-family: inherit;
}
.icon-btn {
background: transparent; border: none; cursor: pointer;
color: var(--secondary-text-color); padding: 4px;
border-radius: 4px;
}
.icon-btn:hover {
background: var(--state-icon-color, rgba(255,255,255,0.06));
color: var(--primary-text-color);
}
.icon-btn.danger:hover { color: var(--error-color); }
.icon-btn ha-icon { --mdc-icon-size: 18px; }
.add-row {
display: flex; gap: 6px;
padding-top: 8px; border-top: 1px solid var(--divider-color);
}
.add-row input {
flex: 1; padding: 6px 8px; font-size: 13px;
background: var(--secondary-background-color, #2c2c2c);
color: var(--primary-text-color);
border: 1px solid var(--divider-color); border-radius: 6px;
font-family: inherit;
}
/* Card-specific overrides on the shared .btn */
.btn.small { padding: 4px 8px; font-size: 12px; }
.btn ha-icon { --mdc-icon-size: 16px; }
`],a([g({attribute:!1})],e.prototype,"hass",2),a([o()],e.prototype,"_config",2),a([o()],e.prototype,"_groups",2),a([o()],e.prototype,"_loaded",2),a([o()],e.prototype,"_busy",2),a([o()],e.prototype,"_error",2),a([o()],e.prototype,"_newName",2),a([o()],e.prototype,"_editingId",2),a([o()],e.prototype,"_editingName",2);customElements.get("maintenance-groups-section-card")||customElements.define("maintenance-groups-section-card",e);v({type:"maintenance-groups-section-card",name:"Maintenance Supporter \u2014 Groups",description:"Inline group CRUD",preview:!1});export{e as MaintenanceGroupsSectionCard};

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