iobroker.time-tracker 0.7.2 → 0.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -126,10 +126,10 @@ it before the change: the switch of the **own** account explains why an account
126
126
  `DELETE /users/:id` refuse it on the server as well), and the role dialog names the last administrator and keeps
127
127
  saving locked while the role would be gone.
128
128
 
129
- The **edit window** (`edit_window_days`, default 7 days) bounds what an account may do with a day of its own without
130
- a decision of the administration. Since times belong to the administration, it now matters for the **offline queue**:
131
- a queued punch that is older arrives as the conflict `too_old` and counts once the office accepts it. Managers and
132
- admins are not bound by it.
129
+ The **edit window** (`edit_window_days`, default 7 days) decides how far back the **offline queue** may hand in a punch
130
+ on its own: a queued punch that is older arrives as the conflict `too_old` and counts once the administration accepts
131
+ it. Nothing else hangs on the setting — an employee does not change his own times at all, and the administration is not
132
+ bound by any window.
133
133
 
134
134
  ### Times, corrections and notes
135
135
 
@@ -202,6 +202,10 @@ Punches stay in the database; the adapter publishes aggregates and controls:
202
202
  | `time-tracker.0.company.present` | string | their names, separated by a comma |
203
203
  | `time-tracker.0.company.openConflicts` / `company.lastPunch` | number | punches waiting for a decision, last punch |
204
204
  | `time-tracker.0.events.lastAt` / `lastType` / `lastUser` / `lastDirection` / `lastSource` | — | newest event of the instance |
205
+ | `time-tracker.0.calendar.feedFile` | string | the written `.ics` file (for `ical`) |
206
+ | `time-tracker.0.calendar.feedUrl` | string | subscription link of the company calendar |
207
+ | `time-tracker.0.calendar.absences` | string | the absences of the window as JSON |
208
+ | `time-tracker.0.calendar.updatedAt` | number | when the calendar was written |
205
209
 
206
210
  ### Commands (states)
207
211
 
@@ -217,6 +221,7 @@ happened.
217
221
  | `commands.closeMonth` | `YYYY-MM` | closes the month (the log line reports balance and overtime) |
218
222
  | `commands.recalc` | `YYYY-MM` or `YYYY` | recalculates the aggregates of that period |
219
223
  | `commands.backup` | `true` | writes a database backup |
224
+ | `commands.rotateCalendarToken` | `true` | creates or renews the calendar link of the company |
220
225
 
221
226
  ```js
222
227
  setState("time-tracker.0.commands.punchUserId", 3); // target employee (0 = the only one)
@@ -244,6 +249,36 @@ Every command ends with a refreshed state tree (`users.*`, `company.*`, `events.
244
249
  A wrong period, an unknown or deactivated employee is answered with a warning in the adapter log — never with a
245
250
  broken instance.
246
251
 
252
+ ### Calendar for ioBroker (feed and states)
253
+
254
+ The absences of the whole company reach ioBroker in two ways — both without a session and without a token:
255
+
256
+ | What | Where | Who uses it |
257
+ | -------- | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------- |
258
+ | **File** | `<iobroker-data>/files/time-tracker.<n>/calendar.ics`, rewritten on every change and every 5 minutes | the `ical` adapter as a **local file**, or a browser through the file server of a `web` instance |
259
+ | **URL** | `calendar.feedUrl` (`http://<host>:<port>/api/calendar.ics?token=…`) | a calendar app, or a script that hands the link to `ical.0.iCalReadTrigger` |
260
+ | **Data** | `calendar.absences` — the same days as JSON (`login`, `name`, `from`, `to`, `code`, `type`, `portion`, `approval`, `status`, `note`) | scripts, Blockly, VIS |
261
+ | **When** | `calendar.updatedAt` | to see how current the three above are |
262
+
263
+ The file lives in the `files` folder of the instance data, because the instance folder next to it can only be read by
264
+ the adapter itself. With a `web` instance on the usual port the same file is downloadable as
265
+ `http://<host>:8081/files/time-tracker.0/calendar.ics`; the `ical` adapter points at the path from `calendar.feedFile`.
266
+
267
+ The window is a year back and to the end of next year. The link of the **company** only exists after somebody asked
268
+ for it: write `true` to `commands.rotateCalendarToken`. The first call creates the token, every further one replaces
269
+ it — an old link stops working at once. That link opens the absences of **all** employees, so treat it like a password.
270
+ The personal link of an employee stays what it was (`POST /calendar/token`, the app has a button for it) and shows
271
+ only that employee.
272
+
273
+ ```js
274
+ setState("time-tracker.0.commands.rotateCalendarToken", true); // create or renew the link of the company
275
+ log(getState("time-tracker.0.calendar.feedUrl").val); // paste it into a calendar app
276
+ setState("ical.0.iCalReadTrigger", "read " + getState("time-tracker.0.calendar.feedUrl").val);
277
+ ```
278
+
279
+ `calendar.absences` is JSON, so any script can read it — the field list stands in the table above. T21 in
280
+ [`docs/testplan.md`](docs/testplan.md) carries a small snippet that logs the running absences.
281
+
247
282
  ### Actions (trigger rules)
248
283
 
249
284
  The ioBroker way of connecting hardware is a state: a fingerprint reader, a button, a door contact or a dashboard
@@ -377,6 +412,30 @@ local SQLite file, access is role-based, and every correction is written to an a
377
412
 
378
413
  ### **WORK IN PROGRESS**
379
414
 
415
+ ### 0.7.4 (2026-09-24)
416
+
417
+ - (Alex) fix: the subscription link of the company carries the API prefix now (`…/api/calendar.ics?token=…`). Without
418
+ it a browser got the web app and its login instead of the calendar
419
+ - (Alex) change: the written calendar file sits in `<iobroker-data>/files/time-tracker.<n>/calendar.ics` instead of the
420
+ instance folder next to it — that one is readable for the adapter alone, while `files/` is handed out by a `web`
421
+ instance as a download (`http://<host>:8081/files/time-tracker.0/calendar.ics`); the `ical` adapter keeps reading it
422
+ as a local file
423
+ - (Alex) docs: the test plan carries a small snippet for the *Scripts* tab that reads `calendar.absences` and logs who
424
+ is away today (for T21, not part of the adapter)
425
+
426
+ ### 0.7.3 (2026-09-24)
427
+
428
+ - (Alex) new: the calendar goes to ioBroker. The adapter writes `calendar.ics` into its instance folder — the `ical`
429
+ adapter reads that as a **local file**, without URL, token or network — and publishes the subscription link of the
430
+ **company** in `calendar.feedUrl` plus the same days as JSON in `calendar.absences` (`calendar.updatedAt` says how
431
+ fresh they are). That link opens the absences of **all** employees, so nothing happens by itself:
432
+ `commands.rotateCalendarToken` creates the token and replaces it on every further call, which kills an old link at
433
+ once. The personal link of an employee is unchanged
434
+ - (Alex) cleanup: the guard `requireInsideEditWindow` is gone (with the problem `edit_window_closed`). It had been
435
+ unreachable since times belong to the administration: it only ever checked punches of the own account, and changing
436
+ one of those already needs `time.edit_other`. The setting `edit_window_days` stays and now has exactly one job — it
437
+ tells the **offline queue** how far back it may hand in a punch on its own (`too_old`); README and D6 say that
438
+
380
439
  ### 0.7.2 (2026-09-24)
381
440
 
382
441
  - (Alex) security: the administration cannot lock itself out any more. Deactivating or taking the admin role away from
@@ -414,22 +473,6 @@ local SQLite file, access is role-based, and every correction is written to an a
414
473
  the seeded types come with colours (vacation green, sickness red, accident orange, military slate, internal blue,
415
474
  training violet, external brown). An open request keeps its colour but is drawn faded
416
475
 
417
- ### 0.6.0 (2026-09-24)
418
-
419
- - (Alex) change: the year overview of the absence tab became a **calendar**. The month now stands as a grid (Monday
420
- first) with the name of every absent employee on the day — approved days green, requested ones grey, numbers of a
421
- public holiday in bold. A **year dropdown** (three years back and ahead) and arrows for the month make the past and
422
- the future reachable, so the administration can look ahead and back instead of only seeing the current year
423
-
424
- ### 0.5.0 (2026-09-23)
425
-
426
- - (Alex) new: the own absences can be subscribed in any calendar app. `POST /calendar/token` hands out a personal link
427
- (`GET /calendar.ics?token=…`, public and rate limited) whose token can be rotated — that makes the old link invalid.
428
- The feed is proper iCalendar: `DTEND` is exclusive (no event loses its last day), half days carry their portion in
429
- the summary, a request that waits for its decision is `TENTATIVE`, and the approval state travels in `STATUS`.
430
- On top the administration finds a **year overview** in the absence tab: approved days per employee and month, fed by
431
- its own request for the calendar year
432
-
433
476
  Older entries are kept in [`CHANGELOG_OLD.md`](CHANGELOG_OLD.md).
434
477
 
435
478
  ## Provenance
@@ -23,6 +23,7 @@ __export(commands_exports, {
23
23
  punchEvent: () => punchEvent
24
24
  });
25
25
  module.exports = __toCommonJS(commands_exports);
26
+ var import_node_crypto = require("node:crypto");
26
27
  var import_errors = require("../errors");
27
28
  var import_punch = require("../domain/punch");
28
29
  var import_time = require("../util/time");
@@ -184,6 +185,17 @@ function handleCommand(deps, id, value) {
184
185
  recalculated: []
185
186
  };
186
187
  }
188
+ if (id === import_states.COMMAND_IDS.rotateCalendarToken) {
189
+ if (value !== true) {
190
+ return { ok: false, message: "ignored (buttons act on true)", recalculated: [] };
191
+ }
192
+ deps.settings.set("calendar_token", (0, import_node_crypto.randomBytes)(32).toString("base64url"), 0, timestamp);
193
+ return {
194
+ ok: true,
195
+ message: "calendar link of the company created or renewed (calendar.feedUrl)",
196
+ recalculated: []
197
+ };
198
+ }
187
199
  throw new import_errors.ValidationError(`unknown command state ${id}`);
188
200
  }
189
201
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/adapter/commands.ts"],
4
- "sourcesContent": ["/**\n * Command states of the adapter.\n *\n * The adapter reacts to the states below, so a script, a dashboard or another adapter can punch, close a month\n * or trigger a recalculation without the REST API. Commands are triggered from inside ioBroker, not from a\n * browser, so no session is involved; the audit trail records them with `actorId: 0` (system).\n */\n\nimport type { Db } from \"../db/database\";\nimport type { EntriesRepository } from \"../db/repositories/entries\";\nimport type { SettingsRepository } from \"../db/repositories/settings\";\nimport type { UsersRepository } from \"../db/repositories/users\";\nimport type { AggregationService } from \"../services/aggregation\";\nimport type { ClosingService } from \"../services/closing\";\nimport type { BackupService } from \"../services/backup\";\nimport type { ApiEvent } from \"../web/events\";\nimport { ValidationError } from \"../errors\";\nimport { buildDayPunches, nextDirection, roundToStep, type PunchEntry } from \"../domain/punch\";\nimport { localDate as resolveLocalDate } from \"../util/time\";\nimport { COMMAND_IDS } from \"./states\";\n\n/** Data sources of the command handler. */\nexport interface CommandDeps {\n\t/** Open database handle */\n\tdb: Db;\n\t/** Punch storage */\n\tentries: EntriesRepository;\n\t/** User storage */\n\tusers: UsersRepository;\n\t/** Instance settings (quick rounding, target employee) */\n\tsettings: SettingsRepository;\n\t/** Aggregation service */\n\taggregation: Pick<AggregationService, \"recalculateDay\" | \"recalculateMonth\" | \"recalculateYear\">;\n\t/** Closing service (month close) */\n\tclosing: Pick<ClosingService, \"closeMonth\">;\n\t/** Backup service (button `commands.backup`), optional */\n\tbackup?: Pick<BackupService, \"create\">;\n\t/** Instant source, defaults to the system clock */\n\tnow?: () => number;\n}\n\n/** Result of a command. */\nexport interface CommandResult {\n\t/** True when the command was executed */\n\tok: boolean;\n\t/** Human readable summary for the log */\n\tmessage: string;\n\t/** Local dates that were recalculated */\n\trecalculated: string[];\n\t/** Employee a written punch belongs to \u2014 unset for every other command */\n\tuserId?: number;\n\t/** Direction of a written punch \u2014 unset for every other command */\n\tdirection?: \"in\" | \"out\";\n}\n\n/** A period taken from a command value. */\ninterface Period {\n\t/** Four digit year */\n\tyear: number;\n\t/** Month (1 to 12) or `null` for a whole year */\n\tmonth: number | null;\n}\n\n/**\n * Parses a period string.\n *\n * @param value - `YYYY-MM` or `YYYY`\n * @returns the parsed period\n */\nfunction parsePeriod(value: string): Period {\n\tconst monthMatch = /^(\\d{4})-(\\d{1,2})$/.exec(value.trim());\n\tif (monthMatch) {\n\t\tconst month = Number(monthMatch[2]);\n\t\tif (month < 1 || month > 12) {\n\t\t\tthrow new ValidationError(`month must be between 1 and 12 (got ${value})`);\n\t\t}\n\t\treturn { year: Number(monthMatch[1]), month };\n\t}\n\n\tconst yearMatch = /^(\\d{4})$/.exec(value.trim());\n\tif (yearMatch) {\n\t\treturn { year: Number(yearMatch[1]), month: null };\n\t}\n\tthrow new ValidationError(`expected YYYY-MM or YYYY (got \"${value}\")`);\n}\n\n/**\n * Resolves the employee a command applies to: the only one, or the configured one.\n *\n * @param deps - data sources\n * @returns the employee\n */\nfunction targetUser(deps: CommandDeps): { id: number; displayName: string; timezone: string } {\n\tconst configured = Number(deps.settings.get(\"command_punch_user_id\") ?? Number.NaN);\n\tconst explicit = Number.isInteger(configured) ? deps.users.findById(configured) : null;\n\tif (explicit) {\n\t\treturn explicit;\n\t}\n\n\tconst candidates = deps.users.list();\n\tif (candidates.length === 1) {\n\t\treturn candidates[0];\n\t}\n\tif (candidates.length === 0) {\n\t\tthrow new ValidationError(\"no employee exists yet\");\n\t}\n\tthrow new ValidationError(\"several employees exist - set command_punch_user_id or write users.<id> commands\");\n}\n\n/** Data a punch needs: where to write, how to round and how to recalculate. */\nexport type PunchDeps = Pick<CommandDeps, \"entries\" | \"users\" | \"settings\" | \"aggregation\" | \"now\">;\n\n/**\n * Punches in or out for one employee.\n *\n * This is the single punch path of the adapter: the `commands.punch` button, a trigger rule and a `sendTo`\n * message all end up here, so direction, rounding, note and recalculation behave the same everywhere.\n *\n * @param deps - data sources\n * @param input - employee, rounding and note\n * @param input.userId - employee the punch belongs to\n * @param input.quick - true to round the instant with the configured quick rounding\n * @param input.note - note stored with the punch\n * @param input.now - instant of the punch, defaults to the system clock\n * @returns result of the punch\n */\nexport function punchEmployee(\n\tdeps: PunchDeps,\n\tinput: { userId: number; quick?: boolean; note?: string; now?: number },\n): CommandResult {\n\tconst target = deps.users.findById(input.userId);\n\tif (!target) {\n\t\tthrow new ValidationError(`employee ${input.userId} does not exist`);\n\t}\n\tif (!target.isActive) {\n\t\tthrow new ValidationError(`${target.displayName} is deactivated, no punch was written`);\n\t}\n\n\tconst now = deps.now ?? (() => Math.floor(Date.now() / 1000));\n\tconst timestamp = input.now ?? now();\n\tconst quickRound = input.quick === true ? deps.settings.getNumber(\"quick_round_minutes\", 0) : 0;\n\tconst tsUtc = quickRound > 0 ? roundToStep(timestamp, quickRound, target.timezone) : timestamp;\n\tconst today = resolveLocalDate(tsUtc, target.timezone);\n\n\tconst existing: PunchEntry[] = deps.entries\n\t\t.listByDate(target.id, today)\n\t\t.map(entry => ({ id: entry.id, tsUtc: entry.tsUtc, syncState: entry.syncState }));\n\tconst direction = nextDirection(buildDayPunches(existing));\n\n\tconst stored = deps.entries.insert({\n\t\tuserId: target.id,\n\t\ttsUtc,\n\t\ttimeZone: target.timezone,\n\t\tsource: \"api\",\n\t\tdirection,\n\t\tnote: input.note ?? null,\n\t\tnow: timestamp,\n\t});\n\tconst day = deps.aggregation.recalculateDay(target.id, stored.entry.localDate, { now: timestamp });\n\n\treturn {\n\t\tok: true,\n\t\tmessage: `${target.displayName} punched ${direction} (${day.workedMin} min today, open: ${day.hasOpenEntry})`,\n\t\trecalculated: [stored.entry.localDate],\n\t\tuserId: target.id,\n\t\tdirection,\n\t};\n}\n\n/**\n * Builds the event a written punch publishes.\n *\n * `punchEmployee` stays pure \u2014 the caller feeds the result into the event bus, exactly like the REST API does it.\n * That is what makes a punch from a command state, a script (`sendTo`) or a trigger rule show up in `events.*`\n * (`lastType`, `lastUser`, \u2026) and in the web app. `null` means: no punch was written.\n *\n * @param result - result of the punch\n * @param source - where the punch came from (`commands.punch`, `sendTo.punch`, `trigger.<id>`, \u2026)\n * @param atUtc - instant of the punch, UTC epoch seconds\n * @returns the event for the bus, or `null` when nothing was written\n */\nexport function punchEvent(result: CommandResult, source: string, atUtc: number): ApiEvent | null {\n\tif (!result.ok || !result.direction || result.userId === undefined) {\n\t\treturn null;\n\t}\n\treturn {\n\t\ttype: \"punch\",\n\t\tatUtc,\n\t\tuserId: result.userId,\n\t\tdata: { direction: result.direction, source },\n\t};\n}\n\n/**\n * Handles a command state.\n *\n * @param deps - data sources\n * @param id - state id that was written (without the instance prefix)\n * @param value - value that was written\n * @returns result of the command\n */\nexport function handleCommand(deps: CommandDeps, id: string, value: ioBroker.StateValue): CommandResult {\n\tconst now = deps.now ?? (() => Math.floor(Date.now() / 1000));\n\tconst timestamp = now();\n\n\tif (id === COMMAND_IDS.punchUserId) {\n\t\t// The state chooses the employee the punch commands apply to (`0` = take the only employee again).\n\t\tconst userId = Number(value ?? Number.NaN);\n\t\tif (!Number.isInteger(userId) || userId < 0) {\n\t\t\tthrow new ValidationError(`expected the id of an employee or 0 (got \"${String(value ?? \"\")}\")`);\n\t\t}\n\t\tif (userId === 0) {\n\t\t\tdeps.settings.set(\"command_punch_user_id\", 0, 0, timestamp);\n\t\t\treturn { ok: true, message: \"punch commands use the only employee again\", recalculated: [] };\n\t\t}\n\t\tconst chosen = deps.users.findById(userId);\n\t\tif (!chosen) {\n\t\t\tthrow new ValidationError(`employee ${userId} does not exist`);\n\t\t}\n\t\tdeps.settings.set(\"command_punch_user_id\", userId, 0, timestamp);\n\t\treturn {\n\t\t\tok: true,\n\t\t\tmessage: `punch commands now apply to ${chosen.displayName}`,\n\t\t\trecalculated: [],\n\t\t};\n\t}\n\n\tif (id === COMMAND_IDS.closeMonth || id === COMMAND_IDS.recalc) {\n\t\tconst period = parsePeriod(String(value ?? \"\"));\n\t\tconst target = targetUser(deps);\n\n\t\tif (id === COMMAND_IDS.recalc) {\n\t\t\tif (period.month === null) {\n\t\t\t\tdeps.aggregation.recalculateYear(target.id, period.year, { now: timestamp });\n\t\t\t\treturn { ok: true, message: `year ${period.year} recalculated`, recalculated: [] };\n\t\t\t}\n\t\t\tdeps.aggregation.recalculateMonth(target.id, period.year, period.month, { now: timestamp });\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\tmessage: `month ${period.year}-${String(period.month).padStart(2, \"0\")} recalculated`,\n\t\t\t\trecalculated: [],\n\t\t\t};\n\t\t}\n\n\t\tif (period.month === null) {\n\t\t\tthrow new ValidationError(\"closing a month needs YYYY-MM\");\n\t\t}\n\t\tconst closed = deps.closing.closeMonth({\n\t\t\tuserId: target.id,\n\t\t\tyear: period.year,\n\t\t\tmonth: period.month,\n\t\t\tactorId: 0,\n\t\t\tnow: timestamp,\n\t\t});\n\t\treturn {\n\t\t\tok: true,\n\t\t\tmessage: `month ${period.year}-${String(period.month).padStart(2, \"0\")} closed for ${target.displayName} (balance ${closed.month.balanceMin} min, overtime ${closed.month.overtimeMin} min)`,\n\t\t\trecalculated: [],\n\t\t};\n\t}\n\n\tif (id === COMMAND_IDS.punch || id === COMMAND_IDS.quickPunch) {\n\t\tif (value !== true) {\n\t\t\t// buttons only act on `true`\n\t\t\treturn { ok: false, message: \"ignored (buttons act on true)\", recalculated: [] };\n\t\t}\n\n\t\tconst target = targetUser(deps);\n\t\treturn punchEmployee(deps, {\n\t\t\tuserId: target.id,\n\t\t\tquick: id === COMMAND_IDS.quickPunch,\n\t\t\tnote: \"command.punch\",\n\t\t\tnow: timestamp,\n\t\t});\n\t}\n\n\tif (id === COMMAND_IDS.backup) {\n\t\tif (value !== true) {\n\t\t\t// buttons only act on `true`\n\t\t\treturn { ok: false, message: \"ignored (buttons act on true)\", recalculated: [] };\n\t\t}\n\t\tif (!deps.backup) {\n\t\t\tthrow new ValidationError(\"this instance has no backup service\");\n\t\t}\n\n\t\tconst created = deps.backup.create({ actorId: 0, reason: \"command state\" });\n\t\treturn {\n\t\t\tok: true,\n\t\t\tmessage: `backup ${created.backup.name} written (${created.backup.sizeBytes} bytes, ${created.backup.entries} punches), ${created.removed.length} old file(s) removed`,\n\t\t\trecalculated: [],\n\t\t};\n\t}\n\n\tthrow new ValidationError(`unknown command state ${id}`);\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Command states of the adapter.\n *\n * The adapter reacts to the states below, so a script, a dashboard or another adapter can punch, close a month\n * or trigger a recalculation without the REST API. Commands are triggered from inside ioBroker, not from a\n * browser, so no session is involved; the audit trail records them with `actorId: 0` (system).\n */\n\nimport { randomBytes } from \"node:crypto\";\nimport type { Db } from \"../db/database\";\nimport type { EntriesRepository } from \"../db/repositories/entries\";\nimport type { SettingsRepository } from \"../db/repositories/settings\";\nimport type { UsersRepository } from \"../db/repositories/users\";\nimport type { AggregationService } from \"../services/aggregation\";\nimport type { ClosingService } from \"../services/closing\";\nimport type { BackupService } from \"../services/backup\";\nimport type { ApiEvent } from \"../web/events\";\nimport { ValidationError } from \"../errors\";\nimport { buildDayPunches, nextDirection, roundToStep, type PunchEntry } from \"../domain/punch\";\nimport { localDate as resolveLocalDate } from \"../util/time\";\nimport { COMMAND_IDS } from \"./states\";\n\n/** Data sources of the command handler. */\nexport interface CommandDeps {\n\t/** Open database handle */\n\tdb: Db;\n\t/** Punch storage */\n\tentries: EntriesRepository;\n\t/** User storage */\n\tusers: UsersRepository;\n\t/** Instance settings (quick rounding, target employee) */\n\tsettings: SettingsRepository;\n\t/** Aggregation service */\n\taggregation: Pick<AggregationService, \"recalculateDay\" | \"recalculateMonth\" | \"recalculateYear\">;\n\t/** Closing service (month close) */\n\tclosing: Pick<ClosingService, \"closeMonth\">;\n\t/** Backup service (button `commands.backup`), optional */\n\tbackup?: Pick<BackupService, \"create\">;\n\t/** Instant source, defaults to the system clock */\n\tnow?: () => number;\n}\n\n/** Result of a command. */\nexport interface CommandResult {\n\t/** True when the command was executed */\n\tok: boolean;\n\t/** Human readable summary for the log */\n\tmessage: string;\n\t/** Local dates that were recalculated */\n\trecalculated: string[];\n\t/** Employee a written punch belongs to \u2014 unset for every other command */\n\tuserId?: number;\n\t/** Direction of a written punch \u2014 unset for every other command */\n\tdirection?: \"in\" | \"out\";\n}\n\n/** A period taken from a command value. */\ninterface Period {\n\t/** Four digit year */\n\tyear: number;\n\t/** Month (1 to 12) or `null` for a whole year */\n\tmonth: number | null;\n}\n\n/**\n * Parses a period string.\n *\n * @param value - `YYYY-MM` or `YYYY`\n * @returns the parsed period\n */\nfunction parsePeriod(value: string): Period {\n\tconst monthMatch = /^(\\d{4})-(\\d{1,2})$/.exec(value.trim());\n\tif (monthMatch) {\n\t\tconst month = Number(monthMatch[2]);\n\t\tif (month < 1 || month > 12) {\n\t\t\tthrow new ValidationError(`month must be between 1 and 12 (got ${value})`);\n\t\t}\n\t\treturn { year: Number(monthMatch[1]), month };\n\t}\n\n\tconst yearMatch = /^(\\d{4})$/.exec(value.trim());\n\tif (yearMatch) {\n\t\treturn { year: Number(yearMatch[1]), month: null };\n\t}\n\tthrow new ValidationError(`expected YYYY-MM or YYYY (got \"${value}\")`);\n}\n\n/**\n * Resolves the employee a command applies to: the only one, or the configured one.\n *\n * @param deps - data sources\n * @returns the employee\n */\nfunction targetUser(deps: CommandDeps): { id: number; displayName: string; timezone: string } {\n\tconst configured = Number(deps.settings.get(\"command_punch_user_id\") ?? Number.NaN);\n\tconst explicit = Number.isInteger(configured) ? deps.users.findById(configured) : null;\n\tif (explicit) {\n\t\treturn explicit;\n\t}\n\n\tconst candidates = deps.users.list();\n\tif (candidates.length === 1) {\n\t\treturn candidates[0];\n\t}\n\tif (candidates.length === 0) {\n\t\tthrow new ValidationError(\"no employee exists yet\");\n\t}\n\tthrow new ValidationError(\"several employees exist - set command_punch_user_id or write users.<id> commands\");\n}\n\n/** Data a punch needs: where to write, how to round and how to recalculate. */\nexport type PunchDeps = Pick<CommandDeps, \"entries\" | \"users\" | \"settings\" | \"aggregation\" | \"now\">;\n\n/**\n * Punches in or out for one employee.\n *\n * This is the single punch path of the adapter: the `commands.punch` button, a trigger rule and a `sendTo`\n * message all end up here, so direction, rounding, note and recalculation behave the same everywhere.\n *\n * @param deps - data sources\n * @param input - employee, rounding and note\n * @param input.userId - employee the punch belongs to\n * @param input.quick - true to round the instant with the configured quick rounding\n * @param input.note - note stored with the punch\n * @param input.now - instant of the punch, defaults to the system clock\n * @returns result of the punch\n */\nexport function punchEmployee(\n\tdeps: PunchDeps,\n\tinput: { userId: number; quick?: boolean; note?: string; now?: number },\n): CommandResult {\n\tconst target = deps.users.findById(input.userId);\n\tif (!target) {\n\t\tthrow new ValidationError(`employee ${input.userId} does not exist`);\n\t}\n\tif (!target.isActive) {\n\t\tthrow new ValidationError(`${target.displayName} is deactivated, no punch was written`);\n\t}\n\n\tconst now = deps.now ?? (() => Math.floor(Date.now() / 1000));\n\tconst timestamp = input.now ?? now();\n\tconst quickRound = input.quick === true ? deps.settings.getNumber(\"quick_round_minutes\", 0) : 0;\n\tconst tsUtc = quickRound > 0 ? roundToStep(timestamp, quickRound, target.timezone) : timestamp;\n\tconst today = resolveLocalDate(tsUtc, target.timezone);\n\n\tconst existing: PunchEntry[] = deps.entries\n\t\t.listByDate(target.id, today)\n\t\t.map(entry => ({ id: entry.id, tsUtc: entry.tsUtc, syncState: entry.syncState }));\n\tconst direction = nextDirection(buildDayPunches(existing));\n\n\tconst stored = deps.entries.insert({\n\t\tuserId: target.id,\n\t\ttsUtc,\n\t\ttimeZone: target.timezone,\n\t\tsource: \"api\",\n\t\tdirection,\n\t\tnote: input.note ?? null,\n\t\tnow: timestamp,\n\t});\n\tconst day = deps.aggregation.recalculateDay(target.id, stored.entry.localDate, { now: timestamp });\n\n\treturn {\n\t\tok: true,\n\t\tmessage: `${target.displayName} punched ${direction} (${day.workedMin} min today, open: ${day.hasOpenEntry})`,\n\t\trecalculated: [stored.entry.localDate],\n\t\tuserId: target.id,\n\t\tdirection,\n\t};\n}\n\n/**\n * Builds the event a written punch publishes.\n *\n * `punchEmployee` stays pure \u2014 the caller feeds the result into the event bus, exactly like the REST API does it.\n * That is what makes a punch from a command state, a script (`sendTo`) or a trigger rule show up in `events.*`\n * (`lastType`, `lastUser`, \u2026) and in the web app. `null` means: no punch was written.\n *\n * @param result - result of the punch\n * @param source - where the punch came from (`commands.punch`, `sendTo.punch`, `trigger.<id>`, \u2026)\n * @param atUtc - instant of the punch, UTC epoch seconds\n * @returns the event for the bus, or `null` when nothing was written\n */\nexport function punchEvent(result: CommandResult, source: string, atUtc: number): ApiEvent | null {\n\tif (!result.ok || !result.direction || result.userId === undefined) {\n\t\treturn null;\n\t}\n\treturn {\n\t\ttype: \"punch\",\n\t\tatUtc,\n\t\tuserId: result.userId,\n\t\tdata: { direction: result.direction, source },\n\t};\n}\n\n/**\n * Handles a command state.\n *\n * @param deps - data sources\n * @param id - state id that was written (without the instance prefix)\n * @param value - value that was written\n * @returns result of the command\n */\nexport function handleCommand(deps: CommandDeps, id: string, value: ioBroker.StateValue): CommandResult {\n\tconst now = deps.now ?? (() => Math.floor(Date.now() / 1000));\n\tconst timestamp = now();\n\n\tif (id === COMMAND_IDS.punchUserId) {\n\t\t// The state chooses the employee the punch commands apply to (`0` = take the only employee again).\n\t\tconst userId = Number(value ?? Number.NaN);\n\t\tif (!Number.isInteger(userId) || userId < 0) {\n\t\t\tthrow new ValidationError(`expected the id of an employee or 0 (got \"${String(value ?? \"\")}\")`);\n\t\t}\n\t\tif (userId === 0) {\n\t\t\tdeps.settings.set(\"command_punch_user_id\", 0, 0, timestamp);\n\t\t\treturn { ok: true, message: \"punch commands use the only employee again\", recalculated: [] };\n\t\t}\n\t\tconst chosen = deps.users.findById(userId);\n\t\tif (!chosen) {\n\t\t\tthrow new ValidationError(`employee ${userId} does not exist`);\n\t\t}\n\t\tdeps.settings.set(\"command_punch_user_id\", userId, 0, timestamp);\n\t\treturn {\n\t\t\tok: true,\n\t\t\tmessage: `punch commands now apply to ${chosen.displayName}`,\n\t\t\trecalculated: [],\n\t\t};\n\t}\n\n\tif (id === COMMAND_IDS.closeMonth || id === COMMAND_IDS.recalc) {\n\t\tconst period = parsePeriod(String(value ?? \"\"));\n\t\tconst target = targetUser(deps);\n\n\t\tif (id === COMMAND_IDS.recalc) {\n\t\t\tif (period.month === null) {\n\t\t\t\tdeps.aggregation.recalculateYear(target.id, period.year, { now: timestamp });\n\t\t\t\treturn { ok: true, message: `year ${period.year} recalculated`, recalculated: [] };\n\t\t\t}\n\t\t\tdeps.aggregation.recalculateMonth(target.id, period.year, period.month, { now: timestamp });\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\tmessage: `month ${period.year}-${String(period.month).padStart(2, \"0\")} recalculated`,\n\t\t\t\trecalculated: [],\n\t\t\t};\n\t\t}\n\n\t\tif (period.month === null) {\n\t\t\tthrow new ValidationError(\"closing a month needs YYYY-MM\");\n\t\t}\n\t\tconst closed = deps.closing.closeMonth({\n\t\t\tuserId: target.id,\n\t\t\tyear: period.year,\n\t\t\tmonth: period.month,\n\t\t\tactorId: 0,\n\t\t\tnow: timestamp,\n\t\t});\n\t\treturn {\n\t\t\tok: true,\n\t\t\tmessage: `month ${period.year}-${String(period.month).padStart(2, \"0\")} closed for ${target.displayName} (balance ${closed.month.balanceMin} min, overtime ${closed.month.overtimeMin} min)`,\n\t\t\trecalculated: [],\n\t\t};\n\t}\n\n\tif (id === COMMAND_IDS.punch || id === COMMAND_IDS.quickPunch) {\n\t\tif (value !== true) {\n\t\t\t// buttons only act on `true`\n\t\t\treturn { ok: false, message: \"ignored (buttons act on true)\", recalculated: [] };\n\t\t}\n\n\t\tconst target = targetUser(deps);\n\t\treturn punchEmployee(deps, {\n\t\t\tuserId: target.id,\n\t\t\tquick: id === COMMAND_IDS.quickPunch,\n\t\t\tnote: \"command.punch\",\n\t\t\tnow: timestamp,\n\t\t});\n\t}\n\n\tif (id === COMMAND_IDS.backup) {\n\t\tif (value !== true) {\n\t\t\t// buttons only act on `true`\n\t\t\treturn { ok: false, message: \"ignored (buttons act on true)\", recalculated: [] };\n\t\t}\n\t\tif (!deps.backup) {\n\t\t\tthrow new ValidationError(\"this instance has no backup service\");\n\t\t}\n\n\t\tconst created = deps.backup.create({ actorId: 0, reason: \"command state\" });\n\t\treturn {\n\t\t\tok: true,\n\t\t\tmessage: `backup ${created.backup.name} written (${created.backup.sizeBytes} bytes, ${created.backup.entries} punches), ${created.removed.length} old file(s) removed`,\n\t\t\trecalculated: [],\n\t\t};\n\t}\n\n\tif (id === COMMAND_IDS.rotateCalendarToken) {\n\t\tif (value !== true) {\n\t\t\t// buttons only act on `true`\n\t\t\treturn { ok: false, message: \"ignored (buttons act on true)\", recalculated: [] };\n\t\t}\n\t\t// replacing the token makes the old link useless at once \u2014 that is what makes a leaked link harmless\n\t\tdeps.settings.set(\"calendar_token\", randomBytes(32).toString(\"base64url\"), 0, timestamp);\n\t\treturn {\n\t\t\tok: true,\n\t\t\tmessage: \"calendar link of the company created or renewed (calendar.feedUrl)\",\n\t\t\trecalculated: [],\n\t\t};\n\t}\n\n\tthrow new ValidationError(`unknown command state ${id}`);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["resolveLocalDate"]
7
7
  }
@@ -511,6 +511,90 @@ const STATE_NAMES = {
511
511
  pl: "\u0179r\xF3d\u0142o ostatniego zdarzenia",
512
512
  uk: "\u0414\u0436\u0435\u0440\u0435\u043B\u043E \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u043F\u043E\u0434\u0456\u0457",
513
513
  "zh-cn": "\u6700\u540E\u4E8B\u4EF6\u7684\u6765\u6E90"
514
+ },
515
+ /** Channel with the calendar of the instance */
516
+ calendarChannel: {
517
+ en: "Calendar",
518
+ de: "Kalender",
519
+ ru: "\u041A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\u044C",
520
+ pt: "Calend\xE1rio",
521
+ nl: "Kalender",
522
+ fr: "Calendrier",
523
+ it: "Calendario",
524
+ es: "Calendario",
525
+ pl: "Kalendarz",
526
+ uk: "\u041A\u0430\u043B\u0435\u043D\u0434\u0430\u0440",
527
+ "zh-cn": "\u65E5\u5386"
528
+ },
529
+ /** Subscription link of the company calendar */
530
+ calendarFeedUrl: {
531
+ en: "Subscription link of the company",
532
+ de: "Abo-Link der Firma",
533
+ ru: "\u0421\u0441\u044B\u043B\u043A\u0430 \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0438 \u0444\u0438\u0440\u043C\u044B",
534
+ pt: "Liga\xE7\xE3o de subscri\xE7\xE3o da empresa",
535
+ nl: "Abonnementslink van het bedrijf",
536
+ fr: "Lien d'abonnement de l'entreprise",
537
+ it: "Link di sottoscrizione dell'azienda",
538
+ es: "Enlace de suscripci\xF3n de la empresa",
539
+ pl: "Link subskrypcji firmy",
540
+ uk: "\u041F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F \u043F\u0456\u0434\u043F\u0438\u0441\u043A\u0438 \u043A\u043E\u043C\u043F\u0430\u043D\u0456\u0457",
541
+ "zh-cn": "\u516C\u53F8\u7684\u8BA2\u9605\u94FE\u63A5"
542
+ },
543
+ /** The written calendar file */
544
+ calendarFeedFile: {
545
+ en: "Calendar file (.ics)",
546
+ de: "Kalenderdatei (.ics)",
547
+ ru: "\u0424\u0430\u0439\u043B \u043A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\u044F (.ics)",
548
+ pt: "Ficheiro de calend\xE1rio (.ics)",
549
+ nl: "Kalenderbestand (.ics)",
550
+ fr: "Fichier de calendrier (.ics)",
551
+ it: "File di calendario (.ics)",
552
+ es: "Archivo de calendario (.ics)",
553
+ pl: "Plik kalendarza (.ics)",
554
+ uk: "\u0424\u0430\u0439\u043B \u043A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\u044F (.ics)",
555
+ "zh-cn": "\u65E5\u5386\u6587\u4EF6\uFF08.ics\uFF09"
556
+ },
557
+ /** Instant the calendar was written */
558
+ calendarUpdatedAt: {
559
+ en: "Calendar written at",
560
+ de: "Kalender geschrieben um",
561
+ ru: "\u0412\u0440\u0435\u043C\u044F \u0437\u0430\u043F\u0438\u0441\u0438 \u043A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\u044F",
562
+ pt: "Hora de escrita do calend\xE1rio",
563
+ nl: "Tijdstip kalender geschreven",
564
+ fr: "Heure d'\xE9criture du calendrier",
565
+ it: "Ora di scrittura del calendario",
566
+ es: "Hora de escritura del calendario",
567
+ pl: "Czas zapisu kalendarza",
568
+ uk: "\u0427\u0430\u0441 \u0437\u0430\u043F\u0438\u0441\u0443 \u043A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\u044F",
569
+ "zh-cn": "\u65E5\u5386\u5199\u5165\u65F6\u95F4"
570
+ },
571
+ /** The absences as JSON */
572
+ calendarAbsences: {
573
+ en: "Absences (JSON)",
574
+ de: "Abwesenheiten (JSON)",
575
+ ru: "\u041E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044F (JSON)",
576
+ pt: "Aus\xEAncias (JSON)",
577
+ nl: "Afwezigheden (JSON)",
578
+ fr: "Absences (JSON)",
579
+ it: "Assenze (JSON)",
580
+ es: "Ausencias (JSON)",
581
+ pl: "Nieobecno\u015Bci (JSON)",
582
+ uk: "\u0412\u0456\u0434\u0441\u0443\u0442\u043D\u043E\u0441\u0442\u0456 (JSON)",
583
+ "zh-cn": "\u7F3A\u52E4\uFF08JSON\uFF09"
584
+ },
585
+ /** Command that creates or renews the calendar link of the company */
586
+ rotateCalendarToken: {
587
+ en: "Create or renew the calendar link of the company",
588
+ de: "Kalender-Link der Firma anlegen oder erneuern",
589
+ ru: "\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0438\u043B\u0438 \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u0441\u0441\u044B\u043B\u043A\u0443 \u043A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\u044F \u0444\u0438\u0440\u043C\u044B",
590
+ pt: "Criar ou renovar a liga\xE7\xE3o do calend\xE1rio da empresa",
591
+ nl: "Kalenderlink van het bedrijf aanmaken of vernieuwen",
592
+ fr: "Cr\xE9er ou renouveler le lien du calendrier de l'entreprise",
593
+ it: "Creare o rinnovare il link del calendario dell'azienda",
594
+ es: "Crear o renovar el enlace del calendario de la empresa",
595
+ pl: "Utw\xF3rz lub od\u015Bwie\u017C link kalendarza firmy",
596
+ uk: "\u0421\u0442\u0432\u043E\u0440\u0438\u0442\u0438 \u0430\u0431\u043E \u043E\u043D\u043E\u0432\u0438\u0442\u0438 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F \u043A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\u044F \u043A\u043E\u043C\u043F\u0430\u043D\u0456\u0457",
597
+ "zh-cn": "\u521B\u5EFA\u6216\u66F4\u65B0\u516C\u53F8\u7684\u65E5\u5386\u94FE\u63A5"
514
598
  }
515
599
  };
516
600
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/adapter/stateNames.ts"],
4
- "sourcesContent": ["/**\n * Names of the adapter's objects, in the eleven languages ioBroker recommends (checker `E6001`).\n *\n * `states.ts` creates the tree; this module is the single place that carries the texts, so every name has the same\n * set of languages. `states.test.ts` walks the whole tree and fails when a name misses one of the eleven keys \u2014\n * that is how the recommendation stays satisfied without anyone remembering it.\n */\n\n/** One object name: the eleven languages the ioBroker checker recommends. */\nexport interface StateName {\n\t/** English */\n\ten: string;\n\t/** German */\n\tde: string;\n\t/** Russian */\n\tru: string;\n\t/** Portuguese */\n\tpt: string;\n\t/** Dutch */\n\tnl: string;\n\t/** French */\n\tfr: string;\n\t/** Italian */\n\tit: string;\n\t/** Spanish */\n\tes: string;\n\t/** Polish */\n\tpl: string;\n\t/** Ukrainian */\n\tuk: string;\n\t/** Chinese (simplified) */\n\t\"zh-cn\": string;\n}\n\n/** Object names of the adapter, grouped like the state tree. */\nexport const STATE_NAMES = {\n\t/** Channel holding the employees */\n\tusersChannel: {\n\t\ten: \"Employees\",\n\t\tde: \"Mitarbeiter\",\n\t\tru: \"\u0421\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A\u0438\",\n\t\tpt: \"Funcion\u00E1rios\",\n\t\tnl: \"Medewerkers\",\n\t\tfr: \"Employ\u00E9s\",\n\t\tit: \"Dipendenti\",\n\t\tes: \"Empleados\",\n\t\tpl: \"Pracownicy\",\n\t\tuk: \"\u0421\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A\u0438\",\n\t\t\"zh-cn\": \"\u5458\u5DE5\",\n\t},\n\t/** Channel of one employee */\n\temployeeChannel: {\n\t\ten: \"Employee\",\n\t\tde: \"Mitarbeiter\",\n\t\tru: \"\u0421\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A\",\n\t\tpt: \"Funcion\u00E1rio\",\n\t\tnl: \"Medewerker\",\n\t\tfr: \"Employ\u00E9\",\n\t\tit: \"Dipendente\",\n\t\tes: \"Empleado\",\n\t\tpl: \"Pracownik\",\n\t\tuk: \"\u0421\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A\",\n\t\t\"zh-cn\": \"\u5458\u5DE5\",\n\t},\n\t/** Channel of the writable commands */\n\tcommandsChannel: {\n\t\ten: \"Commands\",\n\t\tde: \"Befehle\",\n\t\tru: \"\u041A\u043E\u043C\u0430\u043D\u0434\u044B\",\n\t\tpt: \"Comandos\",\n\t\tnl: \"Opdrachten\",\n\t\tfr: \"Commandes\",\n\t\tit: \"Comandi\",\n\t\tes: \"Comandos\",\n\t\tpl: \"Polecenia\",\n\t\tuk: \"\u041A\u043E\u043C\u0430\u043D\u0434\u0438\",\n\t\t\"zh-cn\": \"\u547D\u4EE4\",\n\t},\n\t/** Channel with the figures of the instance */\n\tinfoChannel: {\n\t\ten: \"Information\",\n\t\tde: \"Information\",\n\t\tru: \"\u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F\",\n\t\tpt: \"Informa\u00E7\u00E3o\",\n\t\tnl: \"Informatie\",\n\t\tfr: \"Informations\",\n\t\tit: \"Informazioni\",\n\t\tes: \"Informaci\u00F3n\",\n\t\tpl: \"Informacje\",\n\t\tuk: \"\u0406\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0456\u044F\",\n\t\t\"zh-cn\": \"\u4FE1\u606F\",\n\t},\n\t/** Channel with the figures of the whole company */\n\tcompanyChannel: {\n\t\ten: \"Company\",\n\t\tde: \"Firma\",\n\t\tru: \"\u041A\u043E\u043C\u043F\u0430\u043D\u0438\u044F\",\n\t\tpt: \"Empresa\",\n\t\tnl: \"Bedrijf\",\n\t\tfr: \"Entreprise\",\n\t\tit: \"Azienda\",\n\t\tes: \"Empresa\",\n\t\tpl: \"Firma\",\n\t\tuk: \"\u041A\u043E\u043C\u043F\u0430\u043D\u0456\u044F\",\n\t\t\"zh-cn\": \"\u516C\u53F8\",\n\t},\n\t/** Channel with the newest event of the instance */\n\teventsChannel: {\n\t\ten: \"Events\",\n\t\tde: \"Ereignisse\",\n\t\tru: \"\u0421\u043E\u0431\u044B\u0442\u0438\u044F\",\n\t\tpt: \"Eventos\",\n\t\tnl: \"Gebeurtenissen\",\n\t\tfr: \"\u00C9v\u00E9nements\",\n\t\tit: \"Eventi\",\n\t\tes: \"Eventos\",\n\t\tpl: \"Zdarzenia\",\n\t\tuk: \"\u041F\u043E\u0434\u0456\u0457\",\n\t\t\"zh-cn\": \"\u4E8B\u4EF6\",\n\t},\n\t/** Shown name of the employee */\n\tdisplayName: {\n\t\ten: \"Name\",\n\t\tde: \"Name\",\n\t\tru: \"\u0418\u043C\u044F\",\n\t\tpt: \"Nome\",\n\t\tnl: \"Naam\",\n\t\tfr: \"Nom\",\n\t\tit: \"Nome\",\n\t\tes: \"Nombre\",\n\t\tpl: \"Nazwa\",\n\t\tuk: \"\u0406\u043C'\u044F\",\n\t\t\"zh-cn\": \"\u59D3\u540D\",\n\t},\n\t/** Writable presence of the employee (working time runs) */\n\tuserPresent: {\n\t\ten: \"Present (working time is running)\",\n\t\tde: \"Anwesenheit (Arbeitszeit l\u00E4uft)\",\n\t\tru: \"\u041F\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 (\u0440\u0430\u0431\u043E\u0447\u0435\u0435 \u0432\u0440\u0435\u043C\u044F \u0438\u0434\u0451\u0442)\",\n\t\tpt: \"Presente (o tempo de trabalho corre)\",\n\t\tnl: \"Aanwezig (werktijd loopt)\",\n\t\tfr: \"Pr\u00E9sent (temps de travail en cours)\",\n\t\tit: \"Presente (tempo di lavoro in corso)\",\n\t\tes: \"Presente (tiempo de trabajo en curso)\",\n\t\tpl: \"Obecno\u015B\u0107 (czas pracy trwa)\",\n\t\tuk: \"\u041F\u0440\u0438\u0441\u0443\u0442\u043D\u0456\u0441\u0442\u044C (\u0440\u043E\u0431\u043E\u0447\u0438\u0439 \u0447\u0430\u0441 \u0456\u0434\u0435)\",\n\t\t\"zh-cn\": \"\u5728\u5C97\uFF08\u5DE5\u4F5C\u65F6\u95F4\u8BA1\u65F6\u4E2D\uFF09\",\n\t},\n\t/** True while the last punch of the day has no counterpart */\n\thasOpenEntry: {\n\t\ten: \"Punched in\",\n\t\tde: \"Eingestempelt\",\n\t\tru: \"\u041F\u0440\u0438\u0445\u043E\u0434 \u043E\u0442\u043C\u0435\u0447\u0435\u043D\",\n\t\tpt: \"Entrada registada\",\n\t\tnl: \"Ingeklokt\",\n\t\tfr: \"Pointage d'arriv\u00E9e\",\n\t\tit: \"Entrata registrata\",\n\t\tes: \"Entrada registrada\",\n\t\tpl: \"Zarejestrowane wej\u015Bcie\",\n\t\tuk: \"\u0412\u0456\u0434\u043C\u0456\u0447\u0435\u043D\u043E \u043F\u0440\u0438\u0445\u0456\u0434\",\n\t\t\"zh-cn\": \"\u5DF2\u7B7E\u5230\",\n\t},\n\t/** Instant of the last punch */\n\tlastPunch: {\n\t\ten: \"Last punch\",\n\t\tde: \"Letzte Buchung\",\n\t\tru: \"\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u043E\u0442\u043C\u0435\u0442\u043A\u0430\",\n\t\tpt: \"\u00DAltimo registo\",\n\t\tnl: \"Laatste stempeling\",\n\t\tfr: \"Dernier pointage\",\n\t\tit: \"Ultima timbratura\",\n\t\tes: \"\u00DAltimo registro\",\n\t\tpl: \"Ostatni wpis\",\n\t\tuk: \"\u041E\u0441\u0442\u0430\u043D\u043D\u044F \u0432\u0456\u0434\u043C\u0456\u0442\u043A\u0430\",\n\t\t\"zh-cn\": \"\u6700\u540E\u6253\u5361\",\n\t},\n\t/** Net working time of today */\n\ttodayWorkedMinutes: {\n\t\ten: \"Worked today\",\n\t\tde: \"Heute gearbeitet\",\n\t\tru: \"\u041E\u0442\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u043E \u0441\u0435\u0433\u043E\u0434\u043D\u044F\",\n\t\tpt: \"Trabalhado hoje\",\n\t\tnl: \"Vandaag gewerkt\",\n\t\tfr: \"Travaill\u00E9 aujourd'hui\",\n\t\tit: \"Lavorato oggi\",\n\t\tes: \"Trabajado hoy\",\n\t\tpl: \"Przepracowane dzi\u015B\",\n\t\tuk: \"\u0412\u0456\u0434\u043F\u0440\u0430\u0446\u044C\u043E\u0432\u0430\u043D\u043E \u0441\u044C\u043E\u0433\u043E\u0434\u043D\u0456\",\n\t\t\"zh-cn\": \"\u4ECA\u65E5\u5DF2\u5DE5\u4F5C\",\n\t},\n\t/** Balance of today */\n\ttodayBalanceMinutes: {\n\t\ten: \"Balance today\",\n\t\tde: \"Saldo heute\",\n\t\tru: \"\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0441\u0435\u0433\u043E\u0434\u043D\u044F\",\n\t\tpt: \"Saldo de hoje\",\n\t\tnl: \"Saldo vandaag\",\n\t\tfr: \"Solde du jour\",\n\t\tit: \"Saldo di oggi\",\n\t\tes: \"Saldo de hoy\",\n\t\tpl: \"Saldo dzisiaj\",\n\t\tuk: \"\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0441\u044C\u043E\u0433\u043E\u0434\u043D\u0456\",\n\t\t\"zh-cn\": \"\u4ECA\u65E5\u4F59\u989D\",\n\t},\n\t/** Net working time of the current month */\n\tmonthWorkedMinutes: {\n\t\ten: \"Worked this month\",\n\t\tde: \"Diesen Monat gearbeitet\",\n\t\tru: \"\u041E\u0442\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u043E \u0437\u0430 \u043C\u0435\u0441\u044F\u0446\",\n\t\tpt: \"Trabalhado este m\u00EAs\",\n\t\tnl: \"Deze maand gewerkt\",\n\t\tfr: \"Travaill\u00E9 ce mois\",\n\t\tit: \"Lavorato questo mese\",\n\t\tes: \"Trabajado este mes\",\n\t\tpl: \"Przepracowane w tym miesi\u0105cu\",\n\t\tuk: \"\u0412\u0456\u0434\u043F\u0440\u0430\u0446\u044C\u043E\u0432\u0430\u043D\u043E \u0446\u044C\u043E\u0433\u043E \u043C\u0456\u0441\u044F\u0446\u044F\",\n\t\t\"zh-cn\": \"\u672C\u6708\u5DF2\u5DE5\u4F5C\",\n\t},\n\t/** Balance of the current month */\n\tmonthBalanceMinutes: {\n\t\ten: \"Balance this month\",\n\t\tde: \"Saldo diesen Monat\",\n\t\tru: \"\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u043C\u0435\u0441\u044F\u0446\",\n\t\tpt: \"Saldo deste m\u00EAs\",\n\t\tnl: \"Saldo deze maand\",\n\t\tfr: \"Solde du mois\",\n\t\tit: \"Saldo di questo mese\",\n\t\tes: \"Saldo de este mes\",\n\t\tpl: \"Saldo w tym miesi\u0105cu\",\n\t\tuk: \"\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0446\u0435\u0439 \u043C\u0456\u0441\u044F\u0446\u044C\",\n\t\t\"zh-cn\": \"\u672C\u6708\u4F59\u989D\",\n\t},\n\t/** Balance of the current year */\n\tyearBalanceMinutes: {\n\t\ten: \"Balance this year\",\n\t\tde: \"Saldo dieses Jahr\",\n\t\tru: \"\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0433\u043E\u0434\",\n\t\tpt: \"Saldo deste ano\",\n\t\tnl: \"Saldo dit jaar\",\n\t\tfr: \"Solde de l'ann\u00E9e\",\n\t\tit: \"Saldo di quest'anno\",\n\t\tes: \"Saldo de este a\u00F1o\",\n\t\tpl: \"Saldo w tym roku\",\n\t\tuk: \"\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0446\u0435\u0439 \u0440\u0456\u043A\",\n\t\t\"zh-cn\": \"\u672C\u5E74\u4F59\u989D\",\n\t},\n\t/** Punches waiting for a decision */\n\topenConflicts: {\n\t\ten: \"Open conflicts\",\n\t\tde: \"Offene Konflikte\",\n\t\tru: \"\u041E\u0442\u043A\u0440\u044B\u0442\u044B\u0435 \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u044B\",\n\t\tpt: \"Conflitos em aberto\",\n\t\tnl: \"Openstaande conflicten\",\n\t\tfr: \"Conflits en attente\",\n\t\tit: \"Conflitti aperti\",\n\t\tes: \"Conflictos abiertos\",\n\t\tpl: \"Otwarte konflikty\",\n\t\tuk: \"\u0412\u0456\u0434\u043A\u0440\u0438\u0442\u0456 \u043A\u043E\u043D\u0444\u043B\u0456\u043A\u0442\u0438\",\n\t\t\"zh-cn\": \"\u672A\u89E3\u51B3\u7684\u51B2\u7A81\",\n\t},\n\t/** Employee the punch commands apply to */\n\tpunchUserId: {\n\t\ten: \"Employee id for punch commands\",\n\t\tde: \"Mitarbeiter-Id f\u00FCr Stempelbefehle\",\n\t\tru: \"\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0441\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A\u0430 \u0434\u043B\u044F \u043A\u043E\u043C\u0430\u043D\u0434\",\n\t\tpt: \"ID do funcion\u00E1rio para comandos\",\n\t\tnl: \"Medewerker-id voor opdrachten\",\n\t\tfr: \"Identifiant de l'employ\u00E9 pour les commandes\",\n\t\tit: \"ID del dipendente per i comandi\",\n\t\tes: \"ID del empleado para comandos\",\n\t\tpl: \"Identyfikator pracownika dla polece\u0144\",\n\t\tuk: \"\u0406\u0434\u0435\u043D\u0442\u0438\u0444\u0456\u043A\u0430\u0442\u043E\u0440 \u0441\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A\u0430 \u0434\u043B\u044F \u043A\u043E\u043C\u0430\u043D\u0434\",\n\t\t\"zh-cn\": \"\u6253\u5361\u547D\u4EE4\u7684\u5458\u5DE5 ID\",\n\t},\n\t/** Button: punch in or out */\n\tpunch: {\n\t\ten: \"Punch in or out\",\n\t\tde: \"Ein- oder ausstempeln\",\n\t\tru: \"\u041E\u0442\u043C\u0435\u0442\u0438\u0442\u044C\u0441\u044F (\u043F\u0440\u0438\u0445\u043E\u0434 \u0438\u043B\u0438 \u0443\u0445\u043E\u0434)\",\n\t\tpt: \"Marcar entrada ou sa\u00EDda\",\n\t\tnl: \"In- of uitklokken\",\n\t\tfr: \"Pointer l'arriv\u00E9e ou le d\u00E9part\",\n\t\tit: \"Timbrare entrata o uscita\",\n\t\tes: \"Fichar entrada o salida\",\n\t\tpl: \"Zarejestruj wej\u015Bcie lub wyj\u015Bcie\",\n\t\tuk: \"\u0412\u0456\u0434\u043C\u0456\u0442\u0438\u0442\u0438 \u043F\u0440\u0438\u0445\u0456\u0434 \u0430\u0431\u043E \u0432\u0438\u0445\u0456\u0434\",\n\t\t\"zh-cn\": \"\u4E0A\u73ED\u6216\u4E0B\u73ED\u6253\u5361\",\n\t},\n\t/** Button: punch and round the time */\n\tquickPunch: {\n\t\ten: \"Punch with quick rounding\",\n\t\tde: \"Stempeln mit Schnellrundung\",\n\t\tru: \"\u041E\u0442\u043C\u0435\u0442\u0438\u0442\u044C\u0441\u044F \u0441 \u0431\u044B\u0441\u0442\u0440\u044B\u043C \u043E\u043A\u0440\u0443\u0433\u043B\u0435\u043D\u0438\u0435\u043C\",\n\t\tpt: \"Marcar com arredondamento r\u00E1pido\",\n\t\tnl: \"Klokken met snelle afronding\",\n\t\tfr: \"Pointer avec arrondi rapide\",\n\t\tit: \"Timbrare con arrotondamento rapido\",\n\t\tes: \"Fichar con redondeo r\u00E1pido\",\n\t\tpl: \"Zarejestruj z szybkim zaokr\u0105gleniem\",\n\t\tuk: \"\u0412\u0456\u0434\u043C\u0456\u0442\u0438\u0442\u0438 \u0437\u0456 \u0448\u0432\u0438\u0434\u043A\u0438\u043C \u043E\u043A\u0440\u0443\u0433\u043B\u0435\u043D\u043D\u044F\u043C\",\n\t\t\"zh-cn\": \"\u5FEB\u901F\u53D6\u6574\u6253\u5361\",\n\t},\n\t/** Month to close */\n\tcloseMonth: {\n\t\ten: \"Close month (YYYY-MM)\",\n\t\tde: \"Monat abschlie\u00DFen (JJJJ-MM)\",\n\t\tru: \"\u0417\u0430\u043A\u0440\u044B\u0442\u044C \u043C\u0435\u0441\u044F\u0446 (\u0413\u0413\u0413\u0413-\u041C\u041C)\",\n\t\tpt: \"Fechar m\u00EAs (AAAA-MM)\",\n\t\tnl: \"Maand afsluiten (JJJJ-MM)\",\n\t\tfr: \"Cl\u00F4turer le mois (AAAA-MM)\",\n\t\tit: \"Chiudere il mese (AAAA-MM)\",\n\t\tes: \"Cerrar mes (AAAA-MM)\",\n\t\tpl: \"Zamknij miesi\u0105c (RRRR-MM)\",\n\t\tuk: \"\u0417\u0430\u043A\u0440\u0438\u0442\u0438 \u043C\u0456\u0441\u044F\u0446\u044C (\u0420\u0420\u0420\u0420-\u041C\u041C)\",\n\t\t\"zh-cn\": \"\u5173\u95ED\u6708\u4EFD\uFF08YYYY-MM\uFF09\",\n\t},\n\t/** Period to recalculate */\n\trecalc: {\n\t\ten: \"Recalculate period (YYYY-MM or YYYY)\",\n\t\tde: \"Zeitraum neu berechnen (JJJJ-MM oder JJJJ)\",\n\t\tru: \"\u041F\u0435\u0440\u0435\u0441\u0447\u0438\u0442\u0430\u0442\u044C \u043F\u0435\u0440\u0438\u043E\u0434 (\u0413\u0413\u0413\u0413-\u041C\u041C \u0438\u043B\u0438 \u0413\u0413\u0413\u0413)\",\n\t\tpt: \"Recalcular per\u00EDodo (AAAA-MM ou AAAA)\",\n\t\tnl: \"Periode opnieuw berekenen (JJJJ-MM of JJJJ)\",\n\t\tfr: \"Recalculer la p\u00E9riode (AAAA-MM ou AAAA)\",\n\t\tit: \"Ricalcolare il periodo (AAAA-MM o AAAA)\",\n\t\tes: \"Recalcular periodo (AAAA-MM o AAAA)\",\n\t\tpl: \"Przelicz okres (RRRR-MM lub RRRR)\",\n\t\tuk: \"\u041F\u0435\u0440\u0435\u0440\u0430\u0445\u0443\u0432\u0430\u0442\u0438 \u043F\u0435\u0440\u0456\u043E\u0434 (\u0420\u0420\u0420\u0420-\u041C\u041C \u0430\u0431\u043E \u0420\u0420\u0420\u0420)\",\n\t\t\"zh-cn\": \"\u91CD\u65B0\u8BA1\u7B97\u671F\u95F4\uFF08YYYY-MM \u6216 YYYY\uFF09\",\n\t},\n\t/** Button: write a database backup */\n\tbackupCommand: {\n\t\ten: \"Write a database backup\",\n\t\tde: \"Datenbank-Sicherung schreiben\",\n\t\tru: \"\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u0443\u044E \u043A\u043E\u043F\u0438\u044E \u0431\u0430\u0437\u044B\",\n\t\tpt: \"Criar c\u00F3pia de seguran\u00E7a da base de dados\",\n\t\tnl: \"Databasback-up maken\",\n\t\tfr: \"Cr\u00E9er une sauvegarde de la base\",\n\t\tit: \"Creare un backup del database\",\n\t\tes: \"Crear copia de seguridad de la base\",\n\t\tpl: \"Utw\u00F3rz kopi\u0119 zapasow\u0105 bazy\",\n\t\tuk: \"\u0421\u0442\u0432\u043E\u0440\u0438\u0442\u0438 \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u0443 \u043A\u043E\u043F\u0456\u044E \u0431\u0430\u0437\u0438\",\n\t\t\"zh-cn\": \"\u5199\u5165\u6570\u636E\u5E93\u5907\u4EFD\",\n\t},\n\t/** Version of the adapter */\n\tversion: {\n\t\ten: \"Adapter version\",\n\t\tde: \"Adapter-Version\",\n\t\tru: \"\u0412\u0435\u0440\u0441\u0438\u044F \u0430\u0434\u0430\u043F\u0442\u0435\u0440\u0430\",\n\t\tpt: \"Vers\u00E3o do adaptador\",\n\t\tnl: \"Adapterversie\",\n\t\tfr: \"Version de l'adaptateur\",\n\t\tit: \"Versione dell'adattatore\",\n\t\tes: \"Versi\u00F3n del adaptador\",\n\t\tpl: \"Wersja adaptera\",\n\t\tuk: \"\u0412\u0435\u0440\u0441\u0456\u044F \u0430\u0434\u0430\u043F\u0442\u0435\u0440\u0430\",\n\t\t\"zh-cn\": \"\u9002\u914D\u5668\u7248\u672C\",\n\t},\n\t/** Version of the database schema */\n\tschemaVersion: {\n\t\ten: \"Database schema version\",\n\t\tde: \"Datenbank-Schemaversion\",\n\t\tru: \"\u0412\u0435\u0440\u0441\u0438\u044F \u0441\u0445\u0435\u043C\u044B \u0431\u0430\u0437\u044B \u0434\u0430\u043D\u043D\u044B\u0445\",\n\t\tpt: \"Vers\u00E3o do esquema da base de dados\",\n\t\tnl: \"Schemaversie van de database\",\n\t\tfr: \"Version du sch\u00E9ma de la base\",\n\t\tit: \"Versione dello schema del database\",\n\t\tes: \"Versi\u00F3n del esquema de la base\",\n\t\tpl: \"Wersja schematu bazy\",\n\t\tuk: \"\u0412\u0435\u0440\u0441\u0456\u044F \u0441\u0445\u0435\u043C\u0438 \u0431\u0430\u0437\u0438 \u0434\u0430\u043D\u0438\u0445\",\n\t\t\"zh-cn\": \"\u6570\u636E\u5E93\u67B6\u6784\u7248\u672C\",\n\t},\n\t/** Size of the database file */\n\tdbSizeBytes: {\n\t\ten: \"Database size\",\n\t\tde: \"Datenbank-Gr\u00F6\u00DFe\",\n\t\tru: \"\u0420\u0430\u0437\u043C\u0435\u0440 \u0431\u0430\u0437\u044B \u0434\u0430\u043D\u043D\u044B\u0445\",\n\t\tpt: \"Tamanho da base de dados\",\n\t\tnl: \"Grootte van de database\",\n\t\tfr: \"Taille de la base\",\n\t\tit: \"Dimensione del database\",\n\t\tes: \"Tama\u00F1o de la base\",\n\t\tpl: \"Rozmiar bazy\",\n\t\tuk: \"\u0420\u043E\u0437\u043C\u0456\u0440 \u0431\u0430\u0437\u0438 \u0434\u0430\u043D\u0438\u0445\",\n\t\t\"zh-cn\": \"\u6570\u636E\u5E93\u5927\u5C0F\",\n\t},\n\t/** Last error of the instance */\n\tlastError: {\n\t\ten: \"Last error\",\n\t\tde: \"Letzter Fehler\",\n\t\tru: \"\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u043E\u0448\u0438\u0431\u043A\u0430\",\n\t\tpt: \"\u00DAltimo erro\",\n\t\tnl: \"Laatste fout\",\n\t\tfr: \"Derni\u00E8re erreur\",\n\t\tit: \"Ultimo errore\",\n\t\tes: \"\u00DAltimo error\",\n\t\tpl: \"Ostatni b\u0142\u0105d\",\n\t\tuk: \"\u041E\u0441\u0442\u0430\u043D\u043D\u044F \u043F\u043E\u043C\u0438\u043B\u043A\u0430\",\n\t\t\"zh-cn\": \"\u6700\u540E\u7684\u9519\u8BEF\",\n\t},\n\t/** Instant of the last backup */\n\tlastBackup: {\n\t\ten: \"Last backup\",\n\t\tde: \"Letzte Sicherung\",\n\t\tru: \"\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u0430\u044F \u043A\u043E\u043F\u0438\u044F\",\n\t\tpt: \"\u00DAltima c\u00F3pia de seguran\u00E7a\",\n\t\tnl: \"Laatste back-up\",\n\t\tfr: \"Derni\u00E8re sauvegarde\",\n\t\tit: \"Ultimo backup\",\n\t\tes: \"\u00DAltima copia de seguridad\",\n\t\tpl: \"Ostatnia kopia zapasowa\",\n\t\tuk: \"\u041E\u0441\u0442\u0430\u043D\u043D\u044F \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u0430 \u043A\u043E\u043F\u0456\u044F\",\n\t\t\"zh-cn\": \"\u6700\u540E\u7684\u5907\u4EFD\",\n\t},\n\t/** Number of employees that are present */\n\tcompanyPresentCount: {\n\t\ten: \"Present employees\",\n\t\tde: \"Anwesende Mitarbeiter\",\n\t\tru: \"\u041F\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0435 \u0441\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A\u0438\",\n\t\tpt: \"Funcion\u00E1rios presentes\",\n\t\tnl: \"Aanwezige medewerkers\",\n\t\tfr: \"Employ\u00E9s pr\u00E9sents\",\n\t\tit: \"Dipendenti presenti\",\n\t\tes: \"Empleados presentes\",\n\t\tpl: \"Obecni pracownicy\",\n\t\tuk: \"\u041F\u0440\u0438\u0441\u0443\u0442\u043D\u0456 \u0441\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A\u0438\",\n\t\t\"zh-cn\": \"\u5728\u5C97\u5458\u5DE5\",\n\t},\n\t/** Names of the employees that are present */\n\tcompanyPresent: {\n\t\ten: \"Who is present\",\n\t\tde: \"Wer ist anwesend\",\n\t\tru: \"\u041A\u0442\u043E \u043F\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442\",\n\t\tpt: \"Quem est\u00E1 presente\",\n\t\tnl: \"Wie is aanwezig\",\n\t\tfr: \"Qui est pr\u00E9sent\",\n\t\tit: \"Chi \u00E8 presente\",\n\t\tes: \"Qui\u00E9n est\u00E1 presente\",\n\t\tpl: \"Kto jest obecny\",\n\t\tuk: \"\u0425\u0442\u043E \u043F\u0440\u0438\u0441\u0443\u0442\u043D\u0456\u0439\",\n\t\t\"zh-cn\": \"\u8C01\u5728\u5C97\",\n\t},\n\t/** Instant of the newest punch of the company */\n\tcompanyLastPunch: {\n\t\ten: \"Last punch\",\n\t\tde: \"Letzte Buchung\",\n\t\tru: \"\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u043E\u0442\u043C\u0435\u0442\u043A\u0430\",\n\t\tpt: \"\u00DAltimo registo\",\n\t\tnl: \"Laatste stempeling\",\n\t\tfr: \"Dernier pointage\",\n\t\tit: \"Ultima timbratura\",\n\t\tes: \"\u00DAltimo registro\",\n\t\tpl: \"Ostatni wpis\",\n\t\tuk: \"\u041E\u0441\u0442\u0430\u043D\u043D\u044F \u0432\u0456\u0434\u043C\u0456\u0442\u043A\u0430\",\n\t\t\"zh-cn\": \"\u6700\u540E\u6253\u5361\",\n\t},\n\t/** Instant of the newest event */\n\tlastAt: {\n\t\ten: \"Last event at\",\n\t\tde: \"Letztes Ereignis um\",\n\t\tru: \"\u0412\u0440\u0435\u043C\u044F \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E \u0441\u043E\u0431\u044B\u0442\u0438\u044F\",\n\t\tpt: \"Hora do \u00FAltimo evento\",\n\t\tnl: \"Tijdstip laatste gebeurtenis\",\n\t\tfr: \"Heure du dernier \u00E9v\u00E9nement\",\n\t\tit: \"Ora dell'ultimo evento\",\n\t\tes: \"Hora del \u00FAltimo evento\",\n\t\tpl: \"Czas ostatniego zdarzenia\",\n\t\tuk: \"\u0427\u0430\u0441 \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u043F\u043E\u0434\u0456\u0457\",\n\t\t\"zh-cn\": \"\u6700\u540E\u4E8B\u4EF6\u65F6\u95F4\",\n\t},\n\t/** Kind of the newest event */\n\tlastType: {\n\t\ten: \"Kind of the last event\",\n\t\tde: \"Art des letzten Ereignisses\",\n\t\tru: \"\u0422\u0438\u043F \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E \u0441\u043E\u0431\u044B\u0442\u0438\u044F\",\n\t\tpt: \"Tipo do \u00FAltimo evento\",\n\t\tnl: \"Soort laatste gebeurtenis\",\n\t\tfr: \"Type du dernier \u00E9v\u00E9nement\",\n\t\tit: \"Tipo dell'ultimo evento\",\n\t\tes: \"Tipo del \u00FAltimo evento\",\n\t\tpl: \"Rodzaj ostatniego zdarzenia\",\n\t\tuk: \"\u0422\u0438\u043F \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u043F\u043E\u0434\u0456\u0457\",\n\t\t\"zh-cn\": \"\u6700\u540E\u4E8B\u4EF6\u7C7B\u578B\",\n\t},\n\t/** Employee of the newest event */\n\tlastUser: {\n\t\ten: \"Employee of the last event\",\n\t\tde: \"Mitarbeiter des letzten Ereignisses\",\n\t\tru: \"\u0421\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E \u0441\u043E\u0431\u044B\u0442\u0438\u044F\",\n\t\tpt: \"Funcion\u00E1rio do \u00FAltimo evento\",\n\t\tnl: \"Medewerker van de laatste gebeurtenis\",\n\t\tfr: \"Employ\u00E9 du dernier \u00E9v\u00E9nement\",\n\t\tit: \"Dipendente dell'ultimo evento\",\n\t\tes: \"Empleado del \u00FAltimo evento\",\n\t\tpl: \"Pracownik ostatniego zdarzenia\",\n\t\tuk: \"\u0421\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u043F\u043E\u0434\u0456\u0457\",\n\t\t\"zh-cn\": \"\u6700\u540E\u4E8B\u4EF6\u7684\u5458\u5DE5\",\n\t},\n\t/** Direction of the newest punch */\n\tlastDirection: {\n\t\ten: \"Direction of the last punch\",\n\t\tde: \"Richtung der letzten Buchung\",\n\t\tru: \"\u041D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0439 \u043E\u0442\u043C\u0435\u0442\u043A\u0438\",\n\t\tpt: \"Dire\u00E7\u00E3o do \u00FAltimo registo\",\n\t\tnl: \"Richting van de laatste stempeling\",\n\t\tfr: \"Sens du dernier pointage\",\n\t\tit: \"Direzione dell'ultima timbratura\",\n\t\tes: \"Direcci\u00F3n del \u00FAltimo registro\",\n\t\tpl: \"Kierunek ostatniego wpisu\",\n\t\tuk: \"\u041D\u0430\u043F\u0440\u044F\u043C\u043E\u043A \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u0432\u0456\u0434\u043C\u0456\u0442\u043A\u0438\",\n\t\t\"zh-cn\": \"\u6700\u540E\u6253\u5361\u7684\u65B9\u5411\",\n\t},\n\t/** Source of the newest event */\n\tlastSource: {\n\t\ten: \"Source of the last event\",\n\t\tde: \"Quelle des letzten Ereignisses\",\n\t\tru: \"\u0418\u0441\u0442\u043E\u0447\u043D\u0438\u043A \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E \u0441\u043E\u0431\u044B\u0442\u0438\u044F\",\n\t\tpt: \"Origem do \u00FAltimo evento\",\n\t\tnl: \"Bron van de laatste gebeurtenis\",\n\t\tfr: \"Source du dernier \u00E9v\u00E9nement\",\n\t\tit: \"Origine dell'ultimo evento\",\n\t\tes: \"Origen del \u00FAltimo evento\",\n\t\tpl: \"\u0179r\u00F3d\u0142o ostatniego zdarzenia\",\n\t\tuk: \"\u0414\u0436\u0435\u0440\u0435\u043B\u043E \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u043F\u043E\u0434\u0456\u0457\",\n\t\t\"zh-cn\": \"\u6700\u540E\u4E8B\u4EF6\u7684\u6765\u6E90\",\n\t},\n} satisfies Record<string, StateName>;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Names of the adapter's objects, in the eleven languages ioBroker recommends (checker `E6001`).\n *\n * `states.ts` creates the tree; this module is the single place that carries the texts, so every name has the same\n * set of languages. `states.test.ts` walks the whole tree and fails when a name misses one of the eleven keys \u2014\n * that is how the recommendation stays satisfied without anyone remembering it.\n */\n\n/** One object name: the eleven languages the ioBroker checker recommends. */\nexport interface StateName {\n\t/** English */\n\ten: string;\n\t/** German */\n\tde: string;\n\t/** Russian */\n\tru: string;\n\t/** Portuguese */\n\tpt: string;\n\t/** Dutch */\n\tnl: string;\n\t/** French */\n\tfr: string;\n\t/** Italian */\n\tit: string;\n\t/** Spanish */\n\tes: string;\n\t/** Polish */\n\tpl: string;\n\t/** Ukrainian */\n\tuk: string;\n\t/** Chinese (simplified) */\n\t\"zh-cn\": string;\n}\n\n/** Object names of the adapter, grouped like the state tree. */\nexport const STATE_NAMES = {\n\t/** Channel holding the employees */\n\tusersChannel: {\n\t\ten: \"Employees\",\n\t\tde: \"Mitarbeiter\",\n\t\tru: \"\u0421\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A\u0438\",\n\t\tpt: \"Funcion\u00E1rios\",\n\t\tnl: \"Medewerkers\",\n\t\tfr: \"Employ\u00E9s\",\n\t\tit: \"Dipendenti\",\n\t\tes: \"Empleados\",\n\t\tpl: \"Pracownicy\",\n\t\tuk: \"\u0421\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A\u0438\",\n\t\t\"zh-cn\": \"\u5458\u5DE5\",\n\t},\n\t/** Channel of one employee */\n\temployeeChannel: {\n\t\ten: \"Employee\",\n\t\tde: \"Mitarbeiter\",\n\t\tru: \"\u0421\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A\",\n\t\tpt: \"Funcion\u00E1rio\",\n\t\tnl: \"Medewerker\",\n\t\tfr: \"Employ\u00E9\",\n\t\tit: \"Dipendente\",\n\t\tes: \"Empleado\",\n\t\tpl: \"Pracownik\",\n\t\tuk: \"\u0421\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A\",\n\t\t\"zh-cn\": \"\u5458\u5DE5\",\n\t},\n\t/** Channel of the writable commands */\n\tcommandsChannel: {\n\t\ten: \"Commands\",\n\t\tde: \"Befehle\",\n\t\tru: \"\u041A\u043E\u043C\u0430\u043D\u0434\u044B\",\n\t\tpt: \"Comandos\",\n\t\tnl: \"Opdrachten\",\n\t\tfr: \"Commandes\",\n\t\tit: \"Comandi\",\n\t\tes: \"Comandos\",\n\t\tpl: \"Polecenia\",\n\t\tuk: \"\u041A\u043E\u043C\u0430\u043D\u0434\u0438\",\n\t\t\"zh-cn\": \"\u547D\u4EE4\",\n\t},\n\t/** Channel with the figures of the instance */\n\tinfoChannel: {\n\t\ten: \"Information\",\n\t\tde: \"Information\",\n\t\tru: \"\u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F\",\n\t\tpt: \"Informa\u00E7\u00E3o\",\n\t\tnl: \"Informatie\",\n\t\tfr: \"Informations\",\n\t\tit: \"Informazioni\",\n\t\tes: \"Informaci\u00F3n\",\n\t\tpl: \"Informacje\",\n\t\tuk: \"\u0406\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0456\u044F\",\n\t\t\"zh-cn\": \"\u4FE1\u606F\",\n\t},\n\t/** Channel with the figures of the whole company */\n\tcompanyChannel: {\n\t\ten: \"Company\",\n\t\tde: \"Firma\",\n\t\tru: \"\u041A\u043E\u043C\u043F\u0430\u043D\u0438\u044F\",\n\t\tpt: \"Empresa\",\n\t\tnl: \"Bedrijf\",\n\t\tfr: \"Entreprise\",\n\t\tit: \"Azienda\",\n\t\tes: \"Empresa\",\n\t\tpl: \"Firma\",\n\t\tuk: \"\u041A\u043E\u043C\u043F\u0430\u043D\u0456\u044F\",\n\t\t\"zh-cn\": \"\u516C\u53F8\",\n\t},\n\t/** Channel with the newest event of the instance */\n\teventsChannel: {\n\t\ten: \"Events\",\n\t\tde: \"Ereignisse\",\n\t\tru: \"\u0421\u043E\u0431\u044B\u0442\u0438\u044F\",\n\t\tpt: \"Eventos\",\n\t\tnl: \"Gebeurtenissen\",\n\t\tfr: \"\u00C9v\u00E9nements\",\n\t\tit: \"Eventi\",\n\t\tes: \"Eventos\",\n\t\tpl: \"Zdarzenia\",\n\t\tuk: \"\u041F\u043E\u0434\u0456\u0457\",\n\t\t\"zh-cn\": \"\u4E8B\u4EF6\",\n\t},\n\t/** Shown name of the employee */\n\tdisplayName: {\n\t\ten: \"Name\",\n\t\tde: \"Name\",\n\t\tru: \"\u0418\u043C\u044F\",\n\t\tpt: \"Nome\",\n\t\tnl: \"Naam\",\n\t\tfr: \"Nom\",\n\t\tit: \"Nome\",\n\t\tes: \"Nombre\",\n\t\tpl: \"Nazwa\",\n\t\tuk: \"\u0406\u043C'\u044F\",\n\t\t\"zh-cn\": \"\u59D3\u540D\",\n\t},\n\t/** Writable presence of the employee (working time runs) */\n\tuserPresent: {\n\t\ten: \"Present (working time is running)\",\n\t\tde: \"Anwesenheit (Arbeitszeit l\u00E4uft)\",\n\t\tru: \"\u041F\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 (\u0440\u0430\u0431\u043E\u0447\u0435\u0435 \u0432\u0440\u0435\u043C\u044F \u0438\u0434\u0451\u0442)\",\n\t\tpt: \"Presente (o tempo de trabalho corre)\",\n\t\tnl: \"Aanwezig (werktijd loopt)\",\n\t\tfr: \"Pr\u00E9sent (temps de travail en cours)\",\n\t\tit: \"Presente (tempo di lavoro in corso)\",\n\t\tes: \"Presente (tiempo de trabajo en curso)\",\n\t\tpl: \"Obecno\u015B\u0107 (czas pracy trwa)\",\n\t\tuk: \"\u041F\u0440\u0438\u0441\u0443\u0442\u043D\u0456\u0441\u0442\u044C (\u0440\u043E\u0431\u043E\u0447\u0438\u0439 \u0447\u0430\u0441 \u0456\u0434\u0435)\",\n\t\t\"zh-cn\": \"\u5728\u5C97\uFF08\u5DE5\u4F5C\u65F6\u95F4\u8BA1\u65F6\u4E2D\uFF09\",\n\t},\n\t/** True while the last punch of the day has no counterpart */\n\thasOpenEntry: {\n\t\ten: \"Punched in\",\n\t\tde: \"Eingestempelt\",\n\t\tru: \"\u041F\u0440\u0438\u0445\u043E\u0434 \u043E\u0442\u043C\u0435\u0447\u0435\u043D\",\n\t\tpt: \"Entrada registada\",\n\t\tnl: \"Ingeklokt\",\n\t\tfr: \"Pointage d'arriv\u00E9e\",\n\t\tit: \"Entrata registrata\",\n\t\tes: \"Entrada registrada\",\n\t\tpl: \"Zarejestrowane wej\u015Bcie\",\n\t\tuk: \"\u0412\u0456\u0434\u043C\u0456\u0447\u0435\u043D\u043E \u043F\u0440\u0438\u0445\u0456\u0434\",\n\t\t\"zh-cn\": \"\u5DF2\u7B7E\u5230\",\n\t},\n\t/** Instant of the last punch */\n\tlastPunch: {\n\t\ten: \"Last punch\",\n\t\tde: \"Letzte Buchung\",\n\t\tru: \"\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u043E\u0442\u043C\u0435\u0442\u043A\u0430\",\n\t\tpt: \"\u00DAltimo registo\",\n\t\tnl: \"Laatste stempeling\",\n\t\tfr: \"Dernier pointage\",\n\t\tit: \"Ultima timbratura\",\n\t\tes: \"\u00DAltimo registro\",\n\t\tpl: \"Ostatni wpis\",\n\t\tuk: \"\u041E\u0441\u0442\u0430\u043D\u043D\u044F \u0432\u0456\u0434\u043C\u0456\u0442\u043A\u0430\",\n\t\t\"zh-cn\": \"\u6700\u540E\u6253\u5361\",\n\t},\n\t/** Net working time of today */\n\ttodayWorkedMinutes: {\n\t\ten: \"Worked today\",\n\t\tde: \"Heute gearbeitet\",\n\t\tru: \"\u041E\u0442\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u043E \u0441\u0435\u0433\u043E\u0434\u043D\u044F\",\n\t\tpt: \"Trabalhado hoje\",\n\t\tnl: \"Vandaag gewerkt\",\n\t\tfr: \"Travaill\u00E9 aujourd'hui\",\n\t\tit: \"Lavorato oggi\",\n\t\tes: \"Trabajado hoy\",\n\t\tpl: \"Przepracowane dzi\u015B\",\n\t\tuk: \"\u0412\u0456\u0434\u043F\u0440\u0430\u0446\u044C\u043E\u0432\u0430\u043D\u043E \u0441\u044C\u043E\u0433\u043E\u0434\u043D\u0456\",\n\t\t\"zh-cn\": \"\u4ECA\u65E5\u5DF2\u5DE5\u4F5C\",\n\t},\n\t/** Balance of today */\n\ttodayBalanceMinutes: {\n\t\ten: \"Balance today\",\n\t\tde: \"Saldo heute\",\n\t\tru: \"\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0441\u0435\u0433\u043E\u0434\u043D\u044F\",\n\t\tpt: \"Saldo de hoje\",\n\t\tnl: \"Saldo vandaag\",\n\t\tfr: \"Solde du jour\",\n\t\tit: \"Saldo di oggi\",\n\t\tes: \"Saldo de hoy\",\n\t\tpl: \"Saldo dzisiaj\",\n\t\tuk: \"\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0441\u044C\u043E\u0433\u043E\u0434\u043D\u0456\",\n\t\t\"zh-cn\": \"\u4ECA\u65E5\u4F59\u989D\",\n\t},\n\t/** Net working time of the current month */\n\tmonthWorkedMinutes: {\n\t\ten: \"Worked this month\",\n\t\tde: \"Diesen Monat gearbeitet\",\n\t\tru: \"\u041E\u0442\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u043E \u0437\u0430 \u043C\u0435\u0441\u044F\u0446\",\n\t\tpt: \"Trabalhado este m\u00EAs\",\n\t\tnl: \"Deze maand gewerkt\",\n\t\tfr: \"Travaill\u00E9 ce mois\",\n\t\tit: \"Lavorato questo mese\",\n\t\tes: \"Trabajado este mes\",\n\t\tpl: \"Przepracowane w tym miesi\u0105cu\",\n\t\tuk: \"\u0412\u0456\u0434\u043F\u0440\u0430\u0446\u044C\u043E\u0432\u0430\u043D\u043E \u0446\u044C\u043E\u0433\u043E \u043C\u0456\u0441\u044F\u0446\u044F\",\n\t\t\"zh-cn\": \"\u672C\u6708\u5DF2\u5DE5\u4F5C\",\n\t},\n\t/** Balance of the current month */\n\tmonthBalanceMinutes: {\n\t\ten: \"Balance this month\",\n\t\tde: \"Saldo diesen Monat\",\n\t\tru: \"\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u043C\u0435\u0441\u044F\u0446\",\n\t\tpt: \"Saldo deste m\u00EAs\",\n\t\tnl: \"Saldo deze maand\",\n\t\tfr: \"Solde du mois\",\n\t\tit: \"Saldo di questo mese\",\n\t\tes: \"Saldo de este mes\",\n\t\tpl: \"Saldo w tym miesi\u0105cu\",\n\t\tuk: \"\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0446\u0435\u0439 \u043C\u0456\u0441\u044F\u0446\u044C\",\n\t\t\"zh-cn\": \"\u672C\u6708\u4F59\u989D\",\n\t},\n\t/** Balance of the current year */\n\tyearBalanceMinutes: {\n\t\ten: \"Balance this year\",\n\t\tde: \"Saldo dieses Jahr\",\n\t\tru: \"\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0433\u043E\u0434\",\n\t\tpt: \"Saldo deste ano\",\n\t\tnl: \"Saldo dit jaar\",\n\t\tfr: \"Solde de l'ann\u00E9e\",\n\t\tit: \"Saldo di quest'anno\",\n\t\tes: \"Saldo de este a\u00F1o\",\n\t\tpl: \"Saldo w tym roku\",\n\t\tuk: \"\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0446\u0435\u0439 \u0440\u0456\u043A\",\n\t\t\"zh-cn\": \"\u672C\u5E74\u4F59\u989D\",\n\t},\n\t/** Punches waiting for a decision */\n\topenConflicts: {\n\t\ten: \"Open conflicts\",\n\t\tde: \"Offene Konflikte\",\n\t\tru: \"\u041E\u0442\u043A\u0440\u044B\u0442\u044B\u0435 \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u044B\",\n\t\tpt: \"Conflitos em aberto\",\n\t\tnl: \"Openstaande conflicten\",\n\t\tfr: \"Conflits en attente\",\n\t\tit: \"Conflitti aperti\",\n\t\tes: \"Conflictos abiertos\",\n\t\tpl: \"Otwarte konflikty\",\n\t\tuk: \"\u0412\u0456\u0434\u043A\u0440\u0438\u0442\u0456 \u043A\u043E\u043D\u0444\u043B\u0456\u043A\u0442\u0438\",\n\t\t\"zh-cn\": \"\u672A\u89E3\u51B3\u7684\u51B2\u7A81\",\n\t},\n\t/** Employee the punch commands apply to */\n\tpunchUserId: {\n\t\ten: \"Employee id for punch commands\",\n\t\tde: \"Mitarbeiter-Id f\u00FCr Stempelbefehle\",\n\t\tru: \"\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0441\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A\u0430 \u0434\u043B\u044F \u043A\u043E\u043C\u0430\u043D\u0434\",\n\t\tpt: \"ID do funcion\u00E1rio para comandos\",\n\t\tnl: \"Medewerker-id voor opdrachten\",\n\t\tfr: \"Identifiant de l'employ\u00E9 pour les commandes\",\n\t\tit: \"ID del dipendente per i comandi\",\n\t\tes: \"ID del empleado para comandos\",\n\t\tpl: \"Identyfikator pracownika dla polece\u0144\",\n\t\tuk: \"\u0406\u0434\u0435\u043D\u0442\u0438\u0444\u0456\u043A\u0430\u0442\u043E\u0440 \u0441\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A\u0430 \u0434\u043B\u044F \u043A\u043E\u043C\u0430\u043D\u0434\",\n\t\t\"zh-cn\": \"\u6253\u5361\u547D\u4EE4\u7684\u5458\u5DE5 ID\",\n\t},\n\t/** Button: punch in or out */\n\tpunch: {\n\t\ten: \"Punch in or out\",\n\t\tde: \"Ein- oder ausstempeln\",\n\t\tru: \"\u041E\u0442\u043C\u0435\u0442\u0438\u0442\u044C\u0441\u044F (\u043F\u0440\u0438\u0445\u043E\u0434 \u0438\u043B\u0438 \u0443\u0445\u043E\u0434)\",\n\t\tpt: \"Marcar entrada ou sa\u00EDda\",\n\t\tnl: \"In- of uitklokken\",\n\t\tfr: \"Pointer l'arriv\u00E9e ou le d\u00E9part\",\n\t\tit: \"Timbrare entrata o uscita\",\n\t\tes: \"Fichar entrada o salida\",\n\t\tpl: \"Zarejestruj wej\u015Bcie lub wyj\u015Bcie\",\n\t\tuk: \"\u0412\u0456\u0434\u043C\u0456\u0442\u0438\u0442\u0438 \u043F\u0440\u0438\u0445\u0456\u0434 \u0430\u0431\u043E \u0432\u0438\u0445\u0456\u0434\",\n\t\t\"zh-cn\": \"\u4E0A\u73ED\u6216\u4E0B\u73ED\u6253\u5361\",\n\t},\n\t/** Button: punch and round the time */\n\tquickPunch: {\n\t\ten: \"Punch with quick rounding\",\n\t\tde: \"Stempeln mit Schnellrundung\",\n\t\tru: \"\u041E\u0442\u043C\u0435\u0442\u0438\u0442\u044C\u0441\u044F \u0441 \u0431\u044B\u0441\u0442\u0440\u044B\u043C \u043E\u043A\u0440\u0443\u0433\u043B\u0435\u043D\u0438\u0435\u043C\",\n\t\tpt: \"Marcar com arredondamento r\u00E1pido\",\n\t\tnl: \"Klokken met snelle afronding\",\n\t\tfr: \"Pointer avec arrondi rapide\",\n\t\tit: \"Timbrare con arrotondamento rapido\",\n\t\tes: \"Fichar con redondeo r\u00E1pido\",\n\t\tpl: \"Zarejestruj z szybkim zaokr\u0105gleniem\",\n\t\tuk: \"\u0412\u0456\u0434\u043C\u0456\u0442\u0438\u0442\u0438 \u0437\u0456 \u0448\u0432\u0438\u0434\u043A\u0438\u043C \u043E\u043A\u0440\u0443\u0433\u043B\u0435\u043D\u043D\u044F\u043C\",\n\t\t\"zh-cn\": \"\u5FEB\u901F\u53D6\u6574\u6253\u5361\",\n\t},\n\t/** Month to close */\n\tcloseMonth: {\n\t\ten: \"Close month (YYYY-MM)\",\n\t\tde: \"Monat abschlie\u00DFen (JJJJ-MM)\",\n\t\tru: \"\u0417\u0430\u043A\u0440\u044B\u0442\u044C \u043C\u0435\u0441\u044F\u0446 (\u0413\u0413\u0413\u0413-\u041C\u041C)\",\n\t\tpt: \"Fechar m\u00EAs (AAAA-MM)\",\n\t\tnl: \"Maand afsluiten (JJJJ-MM)\",\n\t\tfr: \"Cl\u00F4turer le mois (AAAA-MM)\",\n\t\tit: \"Chiudere il mese (AAAA-MM)\",\n\t\tes: \"Cerrar mes (AAAA-MM)\",\n\t\tpl: \"Zamknij miesi\u0105c (RRRR-MM)\",\n\t\tuk: \"\u0417\u0430\u043A\u0440\u0438\u0442\u0438 \u043C\u0456\u0441\u044F\u0446\u044C (\u0420\u0420\u0420\u0420-\u041C\u041C)\",\n\t\t\"zh-cn\": \"\u5173\u95ED\u6708\u4EFD\uFF08YYYY-MM\uFF09\",\n\t},\n\t/** Period to recalculate */\n\trecalc: {\n\t\ten: \"Recalculate period (YYYY-MM or YYYY)\",\n\t\tde: \"Zeitraum neu berechnen (JJJJ-MM oder JJJJ)\",\n\t\tru: \"\u041F\u0435\u0440\u0435\u0441\u0447\u0438\u0442\u0430\u0442\u044C \u043F\u0435\u0440\u0438\u043E\u0434 (\u0413\u0413\u0413\u0413-\u041C\u041C \u0438\u043B\u0438 \u0413\u0413\u0413\u0413)\",\n\t\tpt: \"Recalcular per\u00EDodo (AAAA-MM ou AAAA)\",\n\t\tnl: \"Periode opnieuw berekenen (JJJJ-MM of JJJJ)\",\n\t\tfr: \"Recalculer la p\u00E9riode (AAAA-MM ou AAAA)\",\n\t\tit: \"Ricalcolare il periodo (AAAA-MM o AAAA)\",\n\t\tes: \"Recalcular periodo (AAAA-MM o AAAA)\",\n\t\tpl: \"Przelicz okres (RRRR-MM lub RRRR)\",\n\t\tuk: \"\u041F\u0435\u0440\u0435\u0440\u0430\u0445\u0443\u0432\u0430\u0442\u0438 \u043F\u0435\u0440\u0456\u043E\u0434 (\u0420\u0420\u0420\u0420-\u041C\u041C \u0430\u0431\u043E \u0420\u0420\u0420\u0420)\",\n\t\t\"zh-cn\": \"\u91CD\u65B0\u8BA1\u7B97\u671F\u95F4\uFF08YYYY-MM \u6216 YYYY\uFF09\",\n\t},\n\t/** Button: write a database backup */\n\tbackupCommand: {\n\t\ten: \"Write a database backup\",\n\t\tde: \"Datenbank-Sicherung schreiben\",\n\t\tru: \"\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u0443\u044E \u043A\u043E\u043F\u0438\u044E \u0431\u0430\u0437\u044B\",\n\t\tpt: \"Criar c\u00F3pia de seguran\u00E7a da base de dados\",\n\t\tnl: \"Databasback-up maken\",\n\t\tfr: \"Cr\u00E9er une sauvegarde de la base\",\n\t\tit: \"Creare un backup del database\",\n\t\tes: \"Crear copia de seguridad de la base\",\n\t\tpl: \"Utw\u00F3rz kopi\u0119 zapasow\u0105 bazy\",\n\t\tuk: \"\u0421\u0442\u0432\u043E\u0440\u0438\u0442\u0438 \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u0443 \u043A\u043E\u043F\u0456\u044E \u0431\u0430\u0437\u0438\",\n\t\t\"zh-cn\": \"\u5199\u5165\u6570\u636E\u5E93\u5907\u4EFD\",\n\t},\n\t/** Version of the adapter */\n\tversion: {\n\t\ten: \"Adapter version\",\n\t\tde: \"Adapter-Version\",\n\t\tru: \"\u0412\u0435\u0440\u0441\u0438\u044F \u0430\u0434\u0430\u043F\u0442\u0435\u0440\u0430\",\n\t\tpt: \"Vers\u00E3o do adaptador\",\n\t\tnl: \"Adapterversie\",\n\t\tfr: \"Version de l'adaptateur\",\n\t\tit: \"Versione dell'adattatore\",\n\t\tes: \"Versi\u00F3n del adaptador\",\n\t\tpl: \"Wersja adaptera\",\n\t\tuk: \"\u0412\u0435\u0440\u0441\u0456\u044F \u0430\u0434\u0430\u043F\u0442\u0435\u0440\u0430\",\n\t\t\"zh-cn\": \"\u9002\u914D\u5668\u7248\u672C\",\n\t},\n\t/** Version of the database schema */\n\tschemaVersion: {\n\t\ten: \"Database schema version\",\n\t\tde: \"Datenbank-Schemaversion\",\n\t\tru: \"\u0412\u0435\u0440\u0441\u0438\u044F \u0441\u0445\u0435\u043C\u044B \u0431\u0430\u0437\u044B \u0434\u0430\u043D\u043D\u044B\u0445\",\n\t\tpt: \"Vers\u00E3o do esquema da base de dados\",\n\t\tnl: \"Schemaversie van de database\",\n\t\tfr: \"Version du sch\u00E9ma de la base\",\n\t\tit: \"Versione dello schema del database\",\n\t\tes: \"Versi\u00F3n del esquema de la base\",\n\t\tpl: \"Wersja schematu bazy\",\n\t\tuk: \"\u0412\u0435\u0440\u0441\u0456\u044F \u0441\u0445\u0435\u043C\u0438 \u0431\u0430\u0437\u0438 \u0434\u0430\u043D\u0438\u0445\",\n\t\t\"zh-cn\": \"\u6570\u636E\u5E93\u67B6\u6784\u7248\u672C\",\n\t},\n\t/** Size of the database file */\n\tdbSizeBytes: {\n\t\ten: \"Database size\",\n\t\tde: \"Datenbank-Gr\u00F6\u00DFe\",\n\t\tru: \"\u0420\u0430\u0437\u043C\u0435\u0440 \u0431\u0430\u0437\u044B \u0434\u0430\u043D\u043D\u044B\u0445\",\n\t\tpt: \"Tamanho da base de dados\",\n\t\tnl: \"Grootte van de database\",\n\t\tfr: \"Taille de la base\",\n\t\tit: \"Dimensione del database\",\n\t\tes: \"Tama\u00F1o de la base\",\n\t\tpl: \"Rozmiar bazy\",\n\t\tuk: \"\u0420\u043E\u0437\u043C\u0456\u0440 \u0431\u0430\u0437\u0438 \u0434\u0430\u043D\u0438\u0445\",\n\t\t\"zh-cn\": \"\u6570\u636E\u5E93\u5927\u5C0F\",\n\t},\n\t/** Last error of the instance */\n\tlastError: {\n\t\ten: \"Last error\",\n\t\tde: \"Letzter Fehler\",\n\t\tru: \"\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u043E\u0448\u0438\u0431\u043A\u0430\",\n\t\tpt: \"\u00DAltimo erro\",\n\t\tnl: \"Laatste fout\",\n\t\tfr: \"Derni\u00E8re erreur\",\n\t\tit: \"Ultimo errore\",\n\t\tes: \"\u00DAltimo error\",\n\t\tpl: \"Ostatni b\u0142\u0105d\",\n\t\tuk: \"\u041E\u0441\u0442\u0430\u043D\u043D\u044F \u043F\u043E\u043C\u0438\u043B\u043A\u0430\",\n\t\t\"zh-cn\": \"\u6700\u540E\u7684\u9519\u8BEF\",\n\t},\n\t/** Instant of the last backup */\n\tlastBackup: {\n\t\ten: \"Last backup\",\n\t\tde: \"Letzte Sicherung\",\n\t\tru: \"\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u0430\u044F \u043A\u043E\u043F\u0438\u044F\",\n\t\tpt: \"\u00DAltima c\u00F3pia de seguran\u00E7a\",\n\t\tnl: \"Laatste back-up\",\n\t\tfr: \"Derni\u00E8re sauvegarde\",\n\t\tit: \"Ultimo backup\",\n\t\tes: \"\u00DAltima copia de seguridad\",\n\t\tpl: \"Ostatnia kopia zapasowa\",\n\t\tuk: \"\u041E\u0441\u0442\u0430\u043D\u043D\u044F \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u0430 \u043A\u043E\u043F\u0456\u044F\",\n\t\t\"zh-cn\": \"\u6700\u540E\u7684\u5907\u4EFD\",\n\t},\n\t/** Number of employees that are present */\n\tcompanyPresentCount: {\n\t\ten: \"Present employees\",\n\t\tde: \"Anwesende Mitarbeiter\",\n\t\tru: \"\u041F\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0435 \u0441\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A\u0438\",\n\t\tpt: \"Funcion\u00E1rios presentes\",\n\t\tnl: \"Aanwezige medewerkers\",\n\t\tfr: \"Employ\u00E9s pr\u00E9sents\",\n\t\tit: \"Dipendenti presenti\",\n\t\tes: \"Empleados presentes\",\n\t\tpl: \"Obecni pracownicy\",\n\t\tuk: \"\u041F\u0440\u0438\u0441\u0443\u0442\u043D\u0456 \u0441\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A\u0438\",\n\t\t\"zh-cn\": \"\u5728\u5C97\u5458\u5DE5\",\n\t},\n\t/** Names of the employees that are present */\n\tcompanyPresent: {\n\t\ten: \"Who is present\",\n\t\tde: \"Wer ist anwesend\",\n\t\tru: \"\u041A\u0442\u043E \u043F\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442\",\n\t\tpt: \"Quem est\u00E1 presente\",\n\t\tnl: \"Wie is aanwezig\",\n\t\tfr: \"Qui est pr\u00E9sent\",\n\t\tit: \"Chi \u00E8 presente\",\n\t\tes: \"Qui\u00E9n est\u00E1 presente\",\n\t\tpl: \"Kto jest obecny\",\n\t\tuk: \"\u0425\u0442\u043E \u043F\u0440\u0438\u0441\u0443\u0442\u043D\u0456\u0439\",\n\t\t\"zh-cn\": \"\u8C01\u5728\u5C97\",\n\t},\n\t/** Instant of the newest punch of the company */\n\tcompanyLastPunch: {\n\t\ten: \"Last punch\",\n\t\tde: \"Letzte Buchung\",\n\t\tru: \"\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u043E\u0442\u043C\u0435\u0442\u043A\u0430\",\n\t\tpt: \"\u00DAltimo registo\",\n\t\tnl: \"Laatste stempeling\",\n\t\tfr: \"Dernier pointage\",\n\t\tit: \"Ultima timbratura\",\n\t\tes: \"\u00DAltimo registro\",\n\t\tpl: \"Ostatni wpis\",\n\t\tuk: \"\u041E\u0441\u0442\u0430\u043D\u043D\u044F \u0432\u0456\u0434\u043C\u0456\u0442\u043A\u0430\",\n\t\t\"zh-cn\": \"\u6700\u540E\u6253\u5361\",\n\t},\n\t/** Instant of the newest event */\n\tlastAt: {\n\t\ten: \"Last event at\",\n\t\tde: \"Letztes Ereignis um\",\n\t\tru: \"\u0412\u0440\u0435\u043C\u044F \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E \u0441\u043E\u0431\u044B\u0442\u0438\u044F\",\n\t\tpt: \"Hora do \u00FAltimo evento\",\n\t\tnl: \"Tijdstip laatste gebeurtenis\",\n\t\tfr: \"Heure du dernier \u00E9v\u00E9nement\",\n\t\tit: \"Ora dell'ultimo evento\",\n\t\tes: \"Hora del \u00FAltimo evento\",\n\t\tpl: \"Czas ostatniego zdarzenia\",\n\t\tuk: \"\u0427\u0430\u0441 \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u043F\u043E\u0434\u0456\u0457\",\n\t\t\"zh-cn\": \"\u6700\u540E\u4E8B\u4EF6\u65F6\u95F4\",\n\t},\n\t/** Kind of the newest event */\n\tlastType: {\n\t\ten: \"Kind of the last event\",\n\t\tde: \"Art des letzten Ereignisses\",\n\t\tru: \"\u0422\u0438\u043F \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E \u0441\u043E\u0431\u044B\u0442\u0438\u044F\",\n\t\tpt: \"Tipo do \u00FAltimo evento\",\n\t\tnl: \"Soort laatste gebeurtenis\",\n\t\tfr: \"Type du dernier \u00E9v\u00E9nement\",\n\t\tit: \"Tipo dell'ultimo evento\",\n\t\tes: \"Tipo del \u00FAltimo evento\",\n\t\tpl: \"Rodzaj ostatniego zdarzenia\",\n\t\tuk: \"\u0422\u0438\u043F \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u043F\u043E\u0434\u0456\u0457\",\n\t\t\"zh-cn\": \"\u6700\u540E\u4E8B\u4EF6\u7C7B\u578B\",\n\t},\n\t/** Employee of the newest event */\n\tlastUser: {\n\t\ten: \"Employee of the last event\",\n\t\tde: \"Mitarbeiter des letzten Ereignisses\",\n\t\tru: \"\u0421\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E \u0441\u043E\u0431\u044B\u0442\u0438\u044F\",\n\t\tpt: \"Funcion\u00E1rio do \u00FAltimo evento\",\n\t\tnl: \"Medewerker van de laatste gebeurtenis\",\n\t\tfr: \"Employ\u00E9 du dernier \u00E9v\u00E9nement\",\n\t\tit: \"Dipendente dell'ultimo evento\",\n\t\tes: \"Empleado del \u00FAltimo evento\",\n\t\tpl: \"Pracownik ostatniego zdarzenia\",\n\t\tuk: \"\u0421\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u043F\u043E\u0434\u0456\u0457\",\n\t\t\"zh-cn\": \"\u6700\u540E\u4E8B\u4EF6\u7684\u5458\u5DE5\",\n\t},\n\t/** Direction of the newest punch */\n\tlastDirection: {\n\t\ten: \"Direction of the last punch\",\n\t\tde: \"Richtung der letzten Buchung\",\n\t\tru: \"\u041D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0439 \u043E\u0442\u043C\u0435\u0442\u043A\u0438\",\n\t\tpt: \"Dire\u00E7\u00E3o do \u00FAltimo registo\",\n\t\tnl: \"Richting van de laatste stempeling\",\n\t\tfr: \"Sens du dernier pointage\",\n\t\tit: \"Direzione dell'ultima timbratura\",\n\t\tes: \"Direcci\u00F3n del \u00FAltimo registro\",\n\t\tpl: \"Kierunek ostatniego wpisu\",\n\t\tuk: \"\u041D\u0430\u043F\u0440\u044F\u043C\u043E\u043A \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u0432\u0456\u0434\u043C\u0456\u0442\u043A\u0438\",\n\t\t\"zh-cn\": \"\u6700\u540E\u6253\u5361\u7684\u65B9\u5411\",\n\t},\n\t/** Source of the newest event */\n\tlastSource: {\n\t\ten: \"Source of the last event\",\n\t\tde: \"Quelle des letzten Ereignisses\",\n\t\tru: \"\u0418\u0441\u0442\u043E\u0447\u043D\u0438\u043A \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E \u0441\u043E\u0431\u044B\u0442\u0438\u044F\",\n\t\tpt: \"Origem do \u00FAltimo evento\",\n\t\tnl: \"Bron van de laatste gebeurtenis\",\n\t\tfr: \"Source du dernier \u00E9v\u00E9nement\",\n\t\tit: \"Origine dell'ultimo evento\",\n\t\tes: \"Origen del \u00FAltimo evento\",\n\t\tpl: \"\u0179r\u00F3d\u0142o ostatniego zdarzenia\",\n\t\tuk: \"\u0414\u0436\u0435\u0440\u0435\u043B\u043E \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u043F\u043E\u0434\u0456\u0457\",\n\t\t\"zh-cn\": \"\u6700\u540E\u4E8B\u4EF6\u7684\u6765\u6E90\",\n\t},\n\t/** Channel with the calendar of the instance */\n\tcalendarChannel: {\n\t\ten: \"Calendar\",\n\t\tde: \"Kalender\",\n\t\tru: \"\u041A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\u044C\",\n\t\tpt: \"Calend\u00E1rio\",\n\t\tnl: \"Kalender\",\n\t\tfr: \"Calendrier\",\n\t\tit: \"Calendario\",\n\t\tes: \"Calendario\",\n\t\tpl: \"Kalendarz\",\n\t\tuk: \"\u041A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\",\n\t\t\"zh-cn\": \"\u65E5\u5386\",\n\t},\n\t/** Subscription link of the company calendar */\n\tcalendarFeedUrl: {\n\t\ten: \"Subscription link of the company\",\n\t\tde: \"Abo-Link der Firma\",\n\t\tru: \"\u0421\u0441\u044B\u043B\u043A\u0430 \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0438 \u0444\u0438\u0440\u043C\u044B\",\n\t\tpt: \"Liga\u00E7\u00E3o de subscri\u00E7\u00E3o da empresa\",\n\t\tnl: \"Abonnementslink van het bedrijf\",\n\t\tfr: \"Lien d'abonnement de l'entreprise\",\n\t\tit: \"Link di sottoscrizione dell'azienda\",\n\t\tes: \"Enlace de suscripci\u00F3n de la empresa\",\n\t\tpl: \"Link subskrypcji firmy\",\n\t\tuk: \"\u041F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F \u043F\u0456\u0434\u043F\u0438\u0441\u043A\u0438 \u043A\u043E\u043C\u043F\u0430\u043D\u0456\u0457\",\n\t\t\"zh-cn\": \"\u516C\u53F8\u7684\u8BA2\u9605\u94FE\u63A5\",\n\t},\n\t/** The written calendar file */\n\tcalendarFeedFile: {\n\t\ten: \"Calendar file (.ics)\",\n\t\tde: \"Kalenderdatei (.ics)\",\n\t\tru: \"\u0424\u0430\u0439\u043B \u043A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\u044F (.ics)\",\n\t\tpt: \"Ficheiro de calend\u00E1rio (.ics)\",\n\t\tnl: \"Kalenderbestand (.ics)\",\n\t\tfr: \"Fichier de calendrier (.ics)\",\n\t\tit: \"File di calendario (.ics)\",\n\t\tes: \"Archivo de calendario (.ics)\",\n\t\tpl: \"Plik kalendarza (.ics)\",\n\t\tuk: \"\u0424\u0430\u0439\u043B \u043A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\u044F (.ics)\",\n\t\t\"zh-cn\": \"\u65E5\u5386\u6587\u4EF6\uFF08.ics\uFF09\",\n\t},\n\t/** Instant the calendar was written */\n\tcalendarUpdatedAt: {\n\t\ten: \"Calendar written at\",\n\t\tde: \"Kalender geschrieben um\",\n\t\tru: \"\u0412\u0440\u0435\u043C\u044F \u0437\u0430\u043F\u0438\u0441\u0438 \u043A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\u044F\",\n\t\tpt: \"Hora de escrita do calend\u00E1rio\",\n\t\tnl: \"Tijdstip kalender geschreven\",\n\t\tfr: \"Heure d'\u00E9criture du calendrier\",\n\t\tit: \"Ora di scrittura del calendario\",\n\t\tes: \"Hora de escritura del calendario\",\n\t\tpl: \"Czas zapisu kalendarza\",\n\t\tuk: \"\u0427\u0430\u0441 \u0437\u0430\u043F\u0438\u0441\u0443 \u043A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\u044F\",\n\t\t\"zh-cn\": \"\u65E5\u5386\u5199\u5165\u65F6\u95F4\",\n\t},\n\t/** The absences as JSON */\n\tcalendarAbsences: {\n\t\ten: \"Absences (JSON)\",\n\t\tde: \"Abwesenheiten (JSON)\",\n\t\tru: \"\u041E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044F (JSON)\",\n\t\tpt: \"Aus\u00EAncias (JSON)\",\n\t\tnl: \"Afwezigheden (JSON)\",\n\t\tfr: \"Absences (JSON)\",\n\t\tit: \"Assenze (JSON)\",\n\t\tes: \"Ausencias (JSON)\",\n\t\tpl: \"Nieobecno\u015Bci (JSON)\",\n\t\tuk: \"\u0412\u0456\u0434\u0441\u0443\u0442\u043D\u043E\u0441\u0442\u0456 (JSON)\",\n\t\t\"zh-cn\": \"\u7F3A\u52E4\uFF08JSON\uFF09\",\n\t},\n\t/** Command that creates or renews the calendar link of the company */\n\trotateCalendarToken: {\n\t\ten: \"Create or renew the calendar link of the company\",\n\t\tde: \"Kalender-Link der Firma anlegen oder erneuern\",\n\t\tru: \"\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0438\u043B\u0438 \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u0441\u0441\u044B\u043B\u043A\u0443 \u043A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\u044F \u0444\u0438\u0440\u043C\u044B\",\n\t\tpt: \"Criar ou renovar a liga\u00E7\u00E3o do calend\u00E1rio da empresa\",\n\t\tnl: \"Kalenderlink van het bedrijf aanmaken of vernieuwen\",\n\t\tfr: \"Cr\u00E9er ou renouveler le lien du calendrier de l'entreprise\",\n\t\tit: \"Creare o rinnovare il link del calendario dell'azienda\",\n\t\tes: \"Crear o renovar el enlace del calendario de la empresa\",\n\t\tpl: \"Utw\u00F3rz lub od\u015Bwie\u017C link kalendarza firmy\",\n\t\tuk: \"\u0421\u0442\u0432\u043E\u0440\u0438\u0442\u0438 \u0430\u0431\u043E \u043E\u043D\u043E\u0432\u0438\u0442\u0438 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F \u043A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\u044F \u043A\u043E\u043C\u043F\u0430\u043D\u0456\u0457\",\n\t\t\"zh-cn\": \"\u521B\u5EFA\u6216\u66F4\u65B0\u516C\u53F8\u7684\u65E5\u5386\u94FE\u63A5\",\n\t},\n} satisfies Record<string, StateName>;\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -18,13 +18,16 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var states_exports = {};
20
20
  __export(states_exports, {
21
+ CALENDAR_IDS: () => CALENDAR_IDS,
21
22
  COMMAND_IDS: () => COMMAND_IDS,
23
+ createCalendarStates: () => createCalendarStates,
22
24
  createCommandStates: () => createCommandStates,
23
25
  createCompanyStates: () => createCompanyStates,
24
26
  createEventStates: () => createEventStates,
25
27
  createInfoStates: () => createInfoStates,
26
28
  createUserChannel: () => createUserChannel,
27
29
  publishAllUserStates: () => publishAllUserStates,
30
+ publishCalendarSnapshot: () => publishCalendarSnapshot,
28
31
  publishCompanySnapshot: () => publishCompanySnapshot,
29
32
  publishEventSnapshot: () => publishEventSnapshot,
30
33
  publishUserSnapshot: () => publishUserSnapshot,
@@ -46,7 +49,9 @@ const COMMAND_IDS = {
46
49
  /** Recalculate a period, value `YYYY-MM` or `YYYY` */
47
50
  recalc: "commands.recalc",
48
51
  /** Write a backup of the database */
49
- backup: "commands.backup"
52
+ backup: "commands.backup",
53
+ /** Create or renew the calendar link of the company */
54
+ rotateCalendarToken: "commands.rotateCalendarToken"
50
55
  };
51
56
  function stateObject(name, type, role, options = {}) {
52
57
  return {
@@ -216,6 +221,14 @@ async function createCommandStates(port) {
216
221
  write: true
217
222
  })
218
223
  );
224
+ await ensureObject(
225
+ port,
226
+ COMMAND_IDS.rotateCalendarToken,
227
+ stateObject(import_stateNames.STATE_NAMES.rotateCalendarToken, "boolean", "button", {
228
+ read: false,
229
+ write: true
230
+ })
231
+ );
219
232
  }
220
233
  async function createInfoStates(port) {
221
234
  await ensureObject(port, "info", channelObject(import_stateNames.STATE_NAMES.infoChannel));
@@ -270,15 +283,45 @@ async function publishEventSnapshot(port, snapshot) {
270
283
  await port.setState("events.lastDirection", snapshot.direction, true);
271
284
  await port.setState("events.lastSource", snapshot.source, true);
272
285
  }
286
+ const CALENDAR_IDS = {
287
+ /** Subscription link of the company calendar */
288
+ feedUrl: "calendar.feedUrl",
289
+ /** Path of the written `.ics` file */
290
+ feedFile: "calendar.feedFile",
291
+ /** Instant the calendar was written */
292
+ updatedAt: "calendar.updatedAt",
293
+ /** The absences as JSON */
294
+ absences: "calendar.absences"
295
+ };
296
+ async function createCalendarStates(port) {
297
+ await ensureObject(port, "calendar", channelObject(import_stateNames.STATE_NAMES.calendarChannel));
298
+ await ensureObject(port, CALENDAR_IDS.feedUrl, stateObject(import_stateNames.STATE_NAMES.calendarFeedUrl, "string", "text"));
299
+ await ensureObject(port, CALENDAR_IDS.feedFile, stateObject(import_stateNames.STATE_NAMES.calendarFeedFile, "string", "text"));
300
+ await ensureObject(
301
+ port,
302
+ CALENDAR_IDS.updatedAt,
303
+ stateObject(import_stateNames.STATE_NAMES.calendarUpdatedAt, "number", "value.time")
304
+ );
305
+ await ensureObject(port, CALENDAR_IDS.absences, stateObject(import_stateNames.STATE_NAMES.calendarAbsences, "string", "text"));
306
+ }
307
+ async function publishCalendarSnapshot(port, snapshot) {
308
+ await port.setState(CALENDAR_IDS.feedUrl, snapshot.feedUrl, true);
309
+ await port.setState(CALENDAR_IDS.feedFile, snapshot.feedFile, true);
310
+ await port.setState(CALENDAR_IDS.updatedAt, snapshot.updatedAt, true);
311
+ await port.setState(CALENDAR_IDS.absences, snapshot.absences, true);
312
+ }
273
313
  // Annotate the CommonJS export names for ESM import in node:
274
314
  0 && (module.exports = {
315
+ CALENDAR_IDS,
275
316
  COMMAND_IDS,
317
+ createCalendarStates,
276
318
  createCommandStates,
277
319
  createCompanyStates,
278
320
  createEventStates,
279
321
  createInfoStates,
280
322
  createUserChannel,
281
323
  publishAllUserStates,
324
+ publishCalendarSnapshot,
282
325
  publishCompanySnapshot,
283
326
  publishEventSnapshot,
284
327
  publishUserSnapshot,