@homebridge-plugins/homebridge-eufy-security 5.0.0-beta.1 → 5.0.0-beta.10

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.
Files changed (35) hide show
  1. package/README.md +4 -6
  2. package/config.schema.json +20 -0
  3. package/dist/configuration.js +26 -2
  4. package/dist/configuration.js.map +1 -1
  5. package/dist/device/member-evidence.js +8 -1
  6. package/dist/device/member-evidence.js.map +1 -1
  7. package/dist/diagnostics.js +428 -60
  8. package/dist/diagnostics.js.map +1 -1
  9. package/dist/homekit/adapters/camera-streaming.js +54 -26
  10. package/dist/homekit/adapters/camera-streaming.js.map +1 -1
  11. package/dist/homekit/adapters/security-system.js +85 -44
  12. package/dist/homekit/adapters/security-system.js.map +1 -1
  13. package/dist/homekit/reconciler.js +5 -2
  14. package/dist/homekit/reconciler.js.map +1 -1
  15. package/dist/media/live-stream.js +98 -54
  16. package/dist/media/live-stream.js.map +1 -1
  17. package/dist/media/recording.js +7 -5
  18. package/dist/media/recording.js.map +1 -1
  19. package/dist/media/snapshot.js +4 -4
  20. package/dist/media/station-live-sessions.js +47 -43
  21. package/dist/media/station-live-sessions.js.map +1 -1
  22. package/dist/platform.js +24 -5
  23. package/dist/platform.js.map +1 -1
  24. package/dist/ui/dashboard.js +5 -1
  25. package/dist/ui/dashboard.js.map +1 -1
  26. package/dist/ui/server.js +26 -4
  27. package/dist/ui/server.js.map +1 -1
  28. package/homebridge-ui/public/app.css +356 -3
  29. package/homebridge-ui/public/i18n/en.json +25 -14
  30. package/homebridge-ui/public/i18n/fr.json +25 -14
  31. package/homebridge-ui/public/index.html +24 -32
  32. package/homebridge-ui/public/js/app.js +187 -65
  33. package/homebridge-ui/public/js/dashboard.js +80 -1
  34. package/homebridge-ui/public/js/profile-wizard.js +40 -28
  35. package/package.json +2 -2
@@ -384,11 +384,230 @@ button.diagnostics-quiet-action {
384
384
  gap: 8px;
385
385
  }
386
386
 
387
- .diagnostics-result a {
388
- display: inline-block;
387
+ /*
388
+ * The two steps of the handoff share one shape, so the sequence reads as a sequence: same height, same
389
+ * gap, same badge, and a colour each. The download is a button because it acts here; the report is an
390
+ * anchor because it navigates to GitHub.
391
+ */
392
+ .diagnostics-result [data-diagnostics-export],
393
+ .diagnostics-result [data-diagnostics-issue] {
394
+ display: flex;
395
+ width: 100%;
396
+ min-height: 44px;
397
+ align-items: center;
398
+ justify-content: center;
399
+ gap: 10px;
389
400
  margin-top: 8px;
401
+ border-radius: var(--radius-control);
402
+ font-weight: 600;
403
+ text-decoration: none;
404
+ }
405
+
406
+ /*
407
+ * The step number is generated content rather than an element, because translation assigns `textContent`
408
+ * on the control and would remove any child it had.
409
+ */
410
+ .diagnostics-result [data-diagnostics-export]::before,
411
+ .diagnostics-result [data-diagnostics-issue]::before {
412
+ display: inline-flex;
413
+ width: 22px;
414
+ height: 22px;
415
+ flex: none;
416
+ align-items: center;
417
+ justify-content: center;
418
+ border-radius: 50%;
419
+ font-size: 12px;
420
+ font-variant-numeric: tabular-nums;
421
+ font-weight: 700;
422
+ }
423
+
424
+ /* Each badge inverts its own control's pair, so the digit keeps its contrast on either background. */
425
+ .diagnostics-result [data-diagnostics-export]::before {
426
+ background: var(--on-accent);
427
+ color: var(--accent);
428
+ content: '1';
429
+ }
430
+
431
+ /*
432
+ * Step two is the same progression as step one and is filled differently rather than coloured
433
+ * differently: a success colour would claim the task is complete, and colour alone must not be what
434
+ * tells two controls apart.
435
+ */
436
+ .diagnostics-result [data-diagnostics-issue] {
437
+ border: 1px solid var(--accent);
438
+ background: transparent;
439
+ color: var(--accent-ink);
440
+ }
441
+
442
+ .diagnostics-result [data-diagnostics-issue]::before {
443
+ background: var(--accent);
444
+ color: var(--on-accent);
445
+ content: '2';
446
+ }
447
+
448
+ /* Without an archive there is nothing to attach, so the step is present and not yet a link. */
449
+ .diagnostics-result a[data-diagnostics-issue][aria-disabled='true'] {
450
+ border-color: var(--line);
451
+ color: var(--ink-disabled);
452
+ cursor: default;
453
+ }
454
+
455
+ .diagnostics-result a[data-diagnostics-issue][aria-disabled='true']::before {
456
+ background: var(--ink-disabled);
457
+ color: var(--panel);
458
+ }
459
+
460
+ /*
461
+ * The opening screen: every area at once, three to a row.
462
+ *
463
+ * Each tile carries a Material Symbols outline glyph (Apache-2.0) as a mask rather than an element, because
464
+ * translation assigns `textContent` on the tile and would remove any child it had. A mask also lets the glyph
465
+ * take the tile's own colour in every state instead of being baked into an image. The data URI is inline, so
466
+ * the panel renders the same on a host with no route to the internet.
467
+ */
468
+ .diagnostics-tiles {
469
+ display: grid;
470
+ grid-template-columns: repeat(3, minmax(0, 1fr));
471
+ gap: 8px;
472
+ margin-top: 12px;
473
+ }
474
+
475
+ .diagnostics-tiles button {
476
+ display: flex;
477
+ min-height: 88px;
478
+ flex-direction: column;
479
+ align-items: center;
480
+ justify-content: center;
481
+ gap: 8px;
482
+ padding: 10px 6px;
483
+ border: 1px solid var(--line-strong);
484
+ background: transparent;
485
+ color: var(--ink);
486
+ font-size: 12px;
487
+ font-weight: 600;
488
+ line-height: 1.25;
489
+ overflow-wrap: break-word;
490
+ text-align: center;
491
+ }
492
+
493
+ .diagnostics-tiles button::before {
494
+ width: 26px;
495
+ height: 26px;
496
+ flex: none;
497
+ background: currentColor;
498
+ content: '';
499
+ mask-position: center;
500
+ mask-repeat: no-repeat;
501
+ mask-size: contain;
502
+ }
503
+
504
+ .diagnostics-tiles button:hover:not(:disabled) {
505
+ border-color: var(--accent);
506
+ background: var(--accent-soft);
390
507
  color: var(--accent-ink);
508
+ }
509
+
510
+ .diagnostics-tiles [data-diagnostics-tile='startup-authentication']::before {
511
+ mask-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%20-960%20960%20960%22%3E%3Cpath%20d=%22M480-120v-80h280v-560H480v-80h280q33%200%2056.5%2023.5T840-760v560q0%2033-23.5%2056.5T760-120H480Zm-80-160-55-58%20102-102H120v-80h327L345-622l55-58%20200%20200-200%20200Z%22/%3E%3C/svg%3E');
512
+ }
513
+
514
+ .diagnostics-tiles [data-diagnostics-tile='device-representation']::before {
515
+ mask-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%20-960%20960%20960%22%3E%3Cpath%20d=%22M400-560ZM160-160q-33%200-56.5-23.5T80-240v-480q0-33%2023.5-56.5T160-800h640q33%200%2056.5%2023.5T880-720H160v480h80v80h-80Zm640-80v-320H640v320h160Zm-180%2080q-25%200-42.5-17.5T560-220v-360q0-25%2017.5-42.5T620-640h200q25%200%2042.5%2017.5T880-580v360q0%2025-17.5%2042.5T820-160H620Zm100-300q13%200%2021.5-9t8.5-21q0-13-8.5-21.5T720-520q-12%200-21%208.5t-9%2021.5q0%2012%209%2021t21%209ZM340-160l-20-70q-19-17-29.5-40T280-320q0-27%2010.5-50t29.5-40l20-70h120l20%2070q19%2017%2029.5%2040t10.5%2050q0%2027-10.5%2050T480-230l-20%2070H340Zm60-100q26%200%2043-17.5t17-42.5q0-25-18-42.5T400-380q-24%200-42%2017t-18%2043q0%2026%2017%2043t43%2017Zm320-140Z%22/%3E%3C/svg%3E');
516
+ }
517
+
518
+ .diagnostics-tiles [data-diagnostics-tile='control-state']::before {
519
+ mask-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%20-960%20960%20960%22%3E%3Cpath%20d=%22M440-120v-240h80v80h320v80H520v80h-80Zm-320-80v-80h240v80H120Zm160-160v-80H120v-80h160v-80h80v240h-80Zm160-80v-80h400v80H440Zm160-160v-240h80v80h160v80H680v80h-80Zm-480-80v-80h400v80H120Z%22/%3E%3C/svg%3E');
520
+ }
521
+
522
+ .diagnostics-tiles [data-diagnostics-tile='live-media']::before {
523
+ mask-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%20-960%20960%20960%22%3E%3Cpath%20d=%22M160-160q-33%200-56.5-23.5T80-240v-480q0-33%2023.5-56.5T160-800h480q33%200%2056.5%2023.5T720-720v180l160-160v440L720-420v180q0%2033-23.5%2056.5T640-160H160Zm0-80h480v-480H160v480Zm0%200v-480%20480Z%22/%3E%3C/svg%3E');
524
+ }
525
+
526
+ .diagnostics-tiles [data-diagnostics-tile='hksv-recording']::before {
527
+ mask-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%20-960%20960%20960%22%3E%3Cpath%20d=%22m160-800%2080%20160h120l-80-160h80l80%20160h120l-80-160h80l80%20160h120l-80-160h120q33%200%2056.5%2023.5T880-720v480q0%2033-23.5%2056.5T800-160H160q-33%200-56.5-23.5T80-240v-480q0-33%2023.5-56.5T160-800Zm0%20240v320h640v-320H160Zm0%200v320-320Z%22/%3E%3C/svg%3E');
528
+ }
529
+
530
+ .diagnostics-tiles [data-diagnostics-tile='dashboard-ui']::before {
531
+ mask-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%20-960%20960%20960%22%3E%3Cpath%20d=%22M520-600v-240h320v240H520ZM120-440v-400h320v400H120Zm400%20320v-400h320v400H520Zm-400%200v-240h320v240H120Zm80-400h160v-240H200v240Zm400%20320h160v-240H600v240Zm0-480h160v-80H600v80ZM200-200h160v-80H200v80Zm160-320Zm240-160Zm0%20240ZM360-280Z%22/%3E%3C/svg%3E');
532
+ }
533
+
534
+ .diagnostics-tiles [data-diagnostics-tile='other']::before {
535
+ mask-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%20-960%20960%20960%22%3E%3Cpath%20d=%22M513.5-254.5Q528-269%20528-290t-14.5-35.5Q499-340%20478-340t-35.5%2014.5Q428-311%20428-290t14.5%2035.5Q457-240%20478-240t35.5-14.5ZM442-394h74q0-33%207.5-52t42.5-52q26-26%2041-49.5t15-56.5q0-56-41-86t-97-30q-57%200-92.5%2030T342-618l66%2026q5-18%2022.5-39t53.5-21q32%200%2048%2017.5t16%2038.5q0%2020-12%2037.5T506-526q-44%2039-54%2059t-10%2073Zm38%20314q-83%200-156-31.5T197-197q-54-54-85.5-127T80-480q0-83%2031.5-156T197-763q54-54%20127-85.5T480-880q83%200%20156%2031.5T763-763q54%2054%2085.5%20127T880-480q0%2083-31.5%20156T763-197q-54%2054-127%2085.5T480-80Zm0-80q134%200%20227-93t93-227q0-134-93-227t-227-93q-134%200-227%2093t-93%20227q0%20134%2093%20227t227%2093Zm0-320Z%22/%3E%3C/svg%3E');
536
+ }
537
+
538
+ /* The same grid as the areas, so picking hardware reads as the same kind of act as picking an area. */
539
+ .diagnostics-device-list {
540
+ display: grid;
541
+ max-height: 264px;
542
+ grid-template-columns: repeat(3, minmax(0, 1fr));
543
+ gap: 8px;
544
+ overflow-y: auto;
545
+ margin: 8px 0 12px;
546
+ }
547
+
548
+ .diagnostics-device-list button {
549
+ display: flex;
550
+ min-height: 104px;
551
+ flex-direction: column;
552
+ align-items: center;
553
+ justify-content: center;
554
+ gap: 6px;
555
+ padding: 8px 6px;
556
+ border: 1px solid var(--line-strong);
557
+ background: transparent;
558
+ color: var(--ink);
559
+ font-size: 11px;
391
560
  font-weight: 600;
561
+ line-height: 1.2;
562
+ overflow-wrap: break-word;
563
+ text-align: center;
564
+ }
565
+
566
+ .diagnostics-device-list img {
567
+ width: 24px;
568
+ height: 24px;
569
+ flex: none;
570
+ }
571
+
572
+ /*
573
+ * The device's own artwork, contained rather than cropped and at half the tile.
574
+ *
575
+ * `contain` is how the devices view draws the same image, because it is a cutout of the hardware and not a
576
+ * scene: cropping it to fill cuts the device out of its own picture. Half the tile keeps the name it belongs
577
+ * to from competing with it. That view's darkening filter is not carried over — it exists to seat the image
578
+ * under white text on a coloured tile, and these tiles read dark text on the panel.
579
+ */
580
+ .diagnostics-device-list img.device-photo {
581
+ width: 100%;
582
+ max-width: 100%;
583
+ height: auto;
584
+ max-height: 50%;
585
+ object-fit: contain;
586
+ }
587
+
588
+ .diagnostics-device-list button:hover {
589
+ border-color: var(--accent);
590
+ background: var(--accent-soft);
591
+ }
592
+
593
+ /* Pressed is the selection, so it is the border and the fill that say so rather than the colour alone. */
594
+ .diagnostics-device-list button[aria-pressed='true'] {
595
+ border-color: var(--accent);
596
+ border-width: 2px;
597
+ background: var(--accent-soft);
598
+ color: var(--accent-ink);
599
+ }
600
+
601
+ .diagnostics-step-hint {
602
+ margin: 4px 0 0;
603
+ color: var(--muted);
604
+ font-size: 12px;
605
+ }
606
+
607
+ .diagnostics-local-note {
608
+ margin: 12px 0 0;
609
+ color: var(--ink-secondary);
610
+ font-size: 12px;
392
611
  }
393
612
 
394
613
  .diagnostics-result button {
@@ -1149,7 +1368,128 @@ button.diagnostics-quiet-action {
1149
1368
  font-weight: 700;
1150
1369
  }
1151
1370
 
1152
- .preference-grid .preference-changed .snapshot-description {
1371
+ .preference-grid .preference-changed /*
1372
+ * The guard-mode map: four HomeKit states against nine station modes, one pairing per row.
1373
+ *
1374
+ * A table because the content is one, which also gives each select its own row label without a second element
1375
+ * beside it. Row rules and no box: the panel's own surface encloses it, and the one control in the row is the
1376
+ * select, which carries the only border here.
1377
+ */
1378
+ .arming-setting {
1379
+ color: var(--muted);
1380
+ font-size: 11px;
1381
+ }
1382
+
1383
+ .arming-setting > summary {
1384
+ display: grid;
1385
+ grid-template-columns: minmax(0, 1fr) 12px;
1386
+ align-items: center;
1387
+ gap: 2px 8px;
1388
+ cursor: pointer;
1389
+ }
1390
+
1391
+ /* `display: grid` on a summary drops the native marker, so the affordance is drawn back in as a caret. */
1392
+ .arming-setting > summary::marker,
1393
+ .arming-setting > summary::-webkit-details-marker {
1394
+ content: '';
1395
+ display: none;
1396
+ }
1397
+
1398
+ .arming-setting > summary::after {
1399
+ content: '';
1400
+ grid-row: 1 / span 2;
1401
+ grid-column: 2;
1402
+ width: 6px;
1403
+ height: 6px;
1404
+ border-right: 1.5px solid var(--muted);
1405
+ border-bottom: 1.5px solid var(--muted);
1406
+ transform: rotate(45deg);
1407
+ transition: transform 140ms var(--ease-out);
1408
+ }
1409
+
1410
+ .arming-setting[open] > summary::after {
1411
+ transform: rotate(-135deg);
1412
+ }
1413
+
1414
+ /* The map as one line, which is the answer most households only ever read. */
1415
+ .arming-summary {
1416
+ overflow: hidden;
1417
+ color: var(--muted);
1418
+ font-size: 10px;
1419
+ text-overflow: ellipsis;
1420
+ white-space: nowrap;
1421
+ }
1422
+
1423
+ .arming-setting[open] > summary {
1424
+ margin-bottom: 8px;
1425
+ }
1426
+
1427
+ .arming-table {
1428
+ width: 100%;
1429
+ border-collapse: collapse;
1430
+ }
1431
+
1432
+ .arming-table thead th {
1433
+ padding: 0 0 6px;
1434
+ border-bottom: 1px solid var(--line-strong);
1435
+ color: var(--muted);
1436
+ font-size: 10px;
1437
+ font-weight: 600;
1438
+ letter-spacing: 0.04em;
1439
+ text-align: left;
1440
+ text-transform: uppercase;
1441
+ }
1442
+
1443
+ .arming-table tbody tr + tr th,
1444
+ .arming-table tbody tr + tr td {
1445
+ border-top: 1px solid var(--line);
1446
+ }
1447
+
1448
+ .arming-table th[scope='row'] {
1449
+ width: 38%;
1450
+ padding: 6px 10px 6px 0;
1451
+ color: var(--ink);
1452
+ font-size: 11px;
1453
+ font-weight: 600;
1454
+ text-align: left;
1455
+ }
1456
+
1457
+ .arming-table th[scope='row'] label {
1458
+ cursor: pointer;
1459
+ }
1460
+
1461
+ .arming-table td {
1462
+ padding: 6px 0;
1463
+ }
1464
+
1465
+ .arming-table select {
1466
+ width: 100%;
1467
+ min-height: 28px;
1468
+ border: 1px solid var(--line-strong);
1469
+ border-radius: var(--radius-control);
1470
+ background: var(--panel);
1471
+ color: var(--ink);
1472
+ padding: 2px 6px;
1473
+ font-size: 11px;
1474
+ }
1475
+
1476
+ /* The changed row carries the weight, so a pending map reads as which pairing moved rather than as a heavier table. */
1477
+ .arming-setting .snapshot-help {
1478
+ margin-top: 6px;
1479
+ }
1480
+
1481
+ .arming-table select.preference-control-changed {
1482
+ border-color: var(--accent);
1483
+ font-weight: 700;
1484
+ }
1485
+
1486
+ @media (pointer: coarse) {
1487
+ .arming-table select {
1488
+ min-height: 44px;
1489
+ }
1490
+ }
1491
+
1492
+ .snapshot-description {
1153
1493
  font-weight: 400;
1154
1494
  }
1155
1495
 
@@ -1734,6 +2074,19 @@ input:focus-visible {
1734
2074
  }
1735
2075
 
1736
2076
  @media (max-width: 420px) {
2077
+ /*
2078
+ * Two across rather than three. Seven areas still fit on one screen at this width, and a third column
2079
+ * leaves each label about ninety pixels, where the longest of them runs to four lines.
2080
+ */
2081
+ .diagnostics-tiles {
2082
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2083
+ }
2084
+
2085
+ .diagnostics-device-list {
2086
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2087
+ }
2088
+
2089
+
1737
2090
  .status-row {
1738
2091
  display: grid;
1739
2092
  }
@@ -28,6 +28,11 @@
28
28
  "advancedWarmUpLabel": "Warm up camera connections",
29
29
  "advancedWarmUpRemove": "Stop warming up the selected events",
30
30
  "advancedWarmUpRemoveAll": "Stop warming up every event",
31
+ "armingModesHelp": "Four HomeKit states, nine station modes. Pick what each state sets; leave one empty to keep it out of HomeKit. Night has no default.",
32
+ "armingSlotAway": "Away",
33
+ "armingSlotHome": "Home",
34
+ "armingSlotNight": "Night",
35
+ "armingSlotOff": "Off",
31
36
  "authBlocked": "Stop the active Homebridge Eufy connection before authenticating, then try again.",
32
37
  "authFailed": "Authentication failed. Check the account details and try again.",
33
38
  "authReady": "Authenticate your guest account",
@@ -77,22 +82,20 @@
77
82
  "diagnosticOnly": "Diagnostic only",
78
83
  "diagnosticsActionLabel": "What to do",
79
84
  "diagnosticsArchiveCoverageGap": "{classes}: evidence older than {retainedFrom} was dropped at the archive limit, so those classes do not reach the start of the reproduction you marked. Reproduce the fault again over a shorter interval.",
80
- "diagnosticsArchiveExcluded": "Always excluded:",
85
+ "diagnosticsArchiveDetail": "Technical detail",
86
+ "diagnosticsArchiveExcluded": "Never included:",
81
87
  "diagnosticsArchiveExpires": "expires {expiresAt}",
82
88
  "diagnosticsArchiveExport": "Download encrypted archive",
83
89
  "diagnosticsArchiveFields": "fields:",
84
90
  "diagnosticsArchiveMode": "mode:",
85
- "diagnosticsArchiveReview": "Review archive manifest",
86
- "diagnosticsArchiveReviewConfirm": "I reviewed this manifest and want to create this encrypted archive.",
87
- "diagnosticsArchiveReviewIntro": "Review the evidence classes and permanent exclusions before creating an encrypted local download. Nothing is uploaded.",
91
+ "diagnosticsArchiveReviewConfirm": "I have read the summary above and want to create this file.",
92
+ "diagnosticsArchiveReviewIntro": "Creating the file is the next step. Below is what it never contains.",
88
93
  "diagnosticsArchiveTruncated": "newest records retained at the archive limit",
89
94
  "diagnosticsAuthorize": "Start diagnostics session",
90
95
  "diagnosticsAuthorized": "Ready to collect. Start when you are ready.",
91
- "diagnosticsBackToQuestions": "Back to questions",
92
96
  "diagnosticsBeforeLabel": "Before you start",
93
97
  "diagnosticsBestMatch": "Best match",
94
98
  "diagnosticsChangeAnswers": "Change answers",
95
- "diagnosticsChooseDirectly": "Choose a profile directly",
96
99
  "diagnosticsCollectingFinishHere": "Debug diagnostics — collection is active. Finish here.",
97
100
  "diagnosticsComplete": "Collection complete.",
98
101
  "diagnosticsContinue": "Continue",
@@ -104,6 +107,11 @@
104
107
  "diagnosticsDashboardSummary": "Tracks a problem in the dashboard, login, or setup screens.",
105
108
  "diagnosticsDevicesAction": "Refresh the devices or reopen the affected tile, then finish when the problem appears.",
106
109
  "diagnosticsDevicesBefore": "Note which accessory is missing, duplicated, or shown as the wrong type.",
110
+ "diagnosticsDevicesChosen": "Continue",
111
+ "diagnosticsDevicesEvery": "Select all",
112
+ "diagnosticsDevicesHeading": "Which devices are affected?",
113
+ "diagnosticsDevicesHint": "Tap the ones involved. Every log is collected either way — naming them tells us where to look, and saves you being asked again.",
114
+ "diagnosticsDevicesNone": "Clear all",
107
115
  "diagnosticsDevicesSummary": "Checks why a HomeKit accessory is missing, duplicated, or shown as the wrong type.",
108
116
  "diagnosticsEndReproduction": "Issue happened: end reproduction",
109
117
  "diagnosticsEvidenceReady": "Collection complete.",
@@ -118,6 +126,8 @@
118
126
  "diagnosticsIntermittentReproducing": "Collection is waiting for the issue to happen.",
119
127
  "diagnosticsIntermittentStartWaiting": "Start waiting",
120
128
  "diagnosticsIntermittentWaitingGuidance": "Collection is waiting. Return here and finish when the issue happens.",
129
+ "diagnosticsIssueNeedsArchive": "Available once you have downloaded the file above.",
130
+ "diagnosticsIssueOpensTab": "Opens GitHub in a new tab. You will need to attach the downloaded file there.",
121
131
  "diagnosticsLiveAction": "Open the live view, request one snapshot, or try talkback once, then finish when the result is visible.",
122
132
  "diagnosticsLiveBefore": "Choose one camera and one action to try. Video and talkback audio are never included.",
123
133
  "diagnosticsLiveSummary": "Checks one live view, snapshot, or talkback problem.",
@@ -137,18 +147,11 @@
137
147
  "diagnosticsProfileControl": "Control or state mismatch",
138
148
  "diagnosticsProfileDashboard": "Dashboard or setup interface",
139
149
  "diagnosticsProfileDevices": "Missing or incorrect device",
140
- "diagnosticsProfileLabel": "Issue profile",
141
150
  "diagnosticsProfileLiveMedia": "Live video, snapshot, or talkback",
142
151
  "diagnosticsProfileOther": "Other issue",
143
152
  "diagnosticsProfileRecording": "HomeKit Secure Video recording",
144
153
  "diagnosticsProfileStartup": "Startup or authentication",
145
- "diagnosticsQuestionControl": "Does a HomeKit control disagree with the actual device state?",
146
- "diagnosticsQuestionDashboard": "Is the problem in the dashboard, login, or setup screens?",
147
- "diagnosticsQuestionDevices": "Is an accessory missing, duplicated, or shown as the wrong type in HomeKit?",
148
- "diagnosticsQuestionLiveMedia": "Is the problem with live video, a snapshot, or talkback?",
149
- "diagnosticsQuestionRecording": "Is a HomeKit Secure Video recording missing or unplayable?",
150
154
  "diagnosticsQuestionReproduceNow": "Can you reproduce the problem now?",
151
- "diagnosticsQuestionStartup": "Is this a startup or sign-in problem?",
152
155
  "diagnosticsReauthorize": "Start a new diagnostics session",
153
156
  "diagnosticsRecordingAction": "Trigger one event that should be recorded, wait for the recording to appear, then finish.",
154
157
  "diagnosticsRecordingBefore": "Confirm HomeKit Secure Video is enabled and note roughly when the event happens. Recordings are never included.",
@@ -160,10 +163,17 @@
160
163
  "diagnosticsStartupAction": "Restart Homebridge or repeat the failed sign-in step, then return here and finish.",
161
164
  "diagnosticsStartupBefore": "Start collecting before a restart. Never share a password, captcha answer, or verification code.",
162
165
  "diagnosticsStartupSummary": "Checks a Homebridge startup, connection, or sign-in problem.",
166
+ "diagnosticsStaysLocal": "The file is encrypted and stays on this machine. Nothing is uploaded.",
163
167
  "diagnosticsSummary": "Choose the problem, then collect what happens while it occurs.",
168
+ "diagnosticsTilesHeading": "What is going wrong?",
164
169
  "diagnosticsTitle": "Guided diagnostics",
165
- "diagnosticsUseProfile": "Use this profile",
166
170
  "diagnosticsYes": "Yes",
171
+ "excludedCredentials": "your eufy login and password",
172
+ "excludedInternalData": "raw internal data that was never reviewed",
173
+ "excludedKeys": "encryption keys",
174
+ "excludedMedia": "any camera image, video or audio",
175
+ "excludedSessions": "saved sessions and push registrations",
176
+ "excludedTokens": "access tokens and cookies",
167
177
  "firstSetupAcknowledgement": "I have created a dedicated guest account and shared my Eufy home and devices with it.",
168
178
  "firstSetupContinue": "Continue",
169
179
  "firstSetupEyebrow": "First-time setup",
@@ -181,6 +191,7 @@
181
191
  "oneAccountSession": "One account session at a time",
182
192
  "pageTitle": "Connect your Eufy account",
183
193
  "passwordLabel": "Password",
194
+ "preferenceArmingModes": "HomeKit guard modes",
184
195
  "preferenceAudio": "HomeKit audio",
185
196
  "preferenceRepresented": "Expose in HomeKit",
186
197
  "preferenceSaveFailed": "The preference could not be saved. Try again.",
@@ -28,6 +28,11 @@
28
28
  "advancedWarmUpLabel": "Préchauffer les connexions des caméras",
29
29
  "advancedWarmUpRemove": "Ne plus préchauffer les événements sélectionnés",
30
30
  "advancedWarmUpRemoveAll": "Ne plus préchauffer aucun événement",
31
+ "armingModesHelp": "Quatre états HomeKit, neuf modes de station. Choisissez ce que chaque état active ; un état vide n'apparaît pas dans HomeKit. Nuit n'a pas de valeur par défaut.",
32
+ "armingSlotAway": "Absent",
33
+ "armingSlotHome": "Maison",
34
+ "armingSlotNight": "Nuit",
35
+ "armingSlotOff": "Désactivé",
31
36
  "authBlocked": "Arrêtez la connexion Homebridge Eufy active avant de vous authentifier, puis réessayez.",
32
37
  "authFailed": "Échec de l'authentification. Vérifiez le compte et réessayez.",
33
38
  "authReady": "Authentifiez votre compte invité",
@@ -77,22 +82,20 @@
77
82
  "diagnosticOnly": "Diagnostic uniquement",
78
83
  "diagnosticsActionLabel": "À faire",
79
84
  "diagnosticsArchiveCoverageGap": "{classes} : les preuves antérieures à {retainedFrom} ont été écartées à la limite de l'archive, donc ces classes ne remontent pas au début de la reproduction que vous avez marquée. Reproduisez la panne sur un intervalle plus court.",
80
- "diagnosticsArchiveExcluded": "Toujours exclus :",
85
+ "diagnosticsArchiveDetail": "Détail technique",
86
+ "diagnosticsArchiveExcluded": "Jamais inclus :",
81
87
  "diagnosticsArchiveExpires": "expire le {expiresAt}",
82
88
  "diagnosticsArchiveExport": "Télécharger l’archive chiffrée",
83
89
  "diagnosticsArchiveFields": "champs :",
84
90
  "diagnosticsArchiveMode": "mode :",
85
- "diagnosticsArchiveReview": "Examiner le manifeste de l’archive",
86
- "diagnosticsArchiveReviewConfirm": "J’ai examiné ce manifeste et je souhaite créer cette archive chiffrée.",
87
- "diagnosticsArchiveReviewIntro": "Examinez les catégories de preuves et les exclusions permanentes avant de créer un téléchargement local chiffré. Rien n’est envoyé.",
91
+ "diagnosticsArchiveReviewConfirm": "J’ai lu le résumé ci-dessus et je veux créer ce fichier.",
92
+ "diagnosticsArchiveReviewIntro": "L’étape suivante crée le fichier. Ci-dessous, ce qu’il ne contient jamais.",
88
93
  "diagnosticsArchiveTruncated": "enregistrements les plus récents conservés à la limite de l’archive",
89
94
  "diagnosticsAuthorize": "Démarrer la session de diagnostic",
90
95
  "diagnosticsAuthorized": "La collecte est prête. Démarrez lorsque vous le souhaitez.",
91
- "diagnosticsBackToQuestions": "Retour aux questions",
92
96
  "diagnosticsBeforeLabel": "Avant de commencer",
93
97
  "diagnosticsBestMatch": "Meilleur profil",
94
98
  "diagnosticsChangeAnswers": "Modifier les réponses",
95
- "diagnosticsChooseDirectly": "Choisir directement un profil",
96
99
  "diagnosticsCollectingFinishHere": "Diagnostics de débogage — la collecte est active. Terminez ici.",
97
100
  "diagnosticsComplete": "Collecte terminée.",
98
101
  "diagnosticsContinue": "Continuer",
@@ -104,6 +107,11 @@
104
107
  "diagnosticsDashboardSummary": "Suit un problème dans les écrans du tableau de bord, de connexion ou de configuration.",
105
108
  "diagnosticsDevicesAction": "Actualisez les appareils ou rouvrez la tuile concernée, puis terminez lorsque le problème apparaît.",
106
109
  "diagnosticsDevicesBefore": "Notez quel accessoire est absent, dupliqué ou affiché avec le mauvais type.",
110
+ "diagnosticsDevicesChosen": "Continuer",
111
+ "diagnosticsDevicesEvery": "Tout sélectionner",
112
+ "diagnosticsDevicesHeading": "Quels appareils sont concernés ?",
113
+ "diagnosticsDevicesHint": "Touchez ceux qui sont concernés. Tous les journaux sont collectés dans les deux cas — les nommer indique où regarder, et évite qu’on vous repose la question.",
114
+ "diagnosticsDevicesNone": "Tout désélectionner",
107
115
  "diagnosticsDevicesSummary": "Vérifie pourquoi un accessoire HomeKit est absent, dupliqué ou affiché avec le mauvais type.",
108
116
  "diagnosticsEndReproduction": "Le problème est survenu : terminer la reproduction",
109
117
  "diagnosticsEvidenceReady": "Collecte terminée.",
@@ -118,6 +126,8 @@
118
126
  "diagnosticsIntermittentReproducing": "La collecte attend que le problème survienne.",
119
127
  "diagnosticsIntermittentStartWaiting": "Commencer l’attente",
120
128
  "diagnosticsIntermittentWaitingGuidance": "La collecte est en attente. Revenez ici et terminez-la lorsque le problème survient.",
129
+ "diagnosticsIssueNeedsArchive": "Disponible une fois le fichier ci-dessus téléchargé.",
130
+ "diagnosticsIssueOpensTab": "Ouvre GitHub dans un nouvel onglet. Il faudra y joindre le fichier téléchargé.",
121
131
  "diagnosticsLiveAction": "Ouvrez la vue en direct, demandez un instantané ou essayez l’interphone une fois, puis terminez lorsque le résultat est visible.",
122
132
  "diagnosticsLiveBefore": "Choisissez une caméra et une action à essayer. La vidéo et l’audio de l’interphone ne sont jamais inclus.",
123
133
  "diagnosticsLiveSummary": "Vérifie un problème de vue en direct, d’instantané ou d’interphone.",
@@ -137,18 +147,11 @@
137
147
  "diagnosticsProfileControl": "Décalage de commande ou d’état",
138
148
  "diagnosticsProfileDashboard": "Tableau de bord ou interface de configuration",
139
149
  "diagnosticsProfileDevices": "Appareil manquant ou incorrect",
140
- "diagnosticsProfileLabel": "Profil du problème",
141
150
  "diagnosticsProfileLiveMedia": "Vidéo en direct, instantané ou interphone",
142
151
  "diagnosticsProfileOther": "Autre problème",
143
152
  "diagnosticsProfileRecording": "Enregistrement vidéo sécurisé HomeKit",
144
153
  "diagnosticsProfileStartup": "Démarrage ou authentification",
145
- "diagnosticsQuestionControl": "Une commande HomeKit diffère-t-elle de l’état réel de l’appareil ?",
146
- "diagnosticsQuestionDashboard": "Le problème se situe-t-il dans les écrans du tableau de bord, de connexion ou de configuration ?",
147
- "diagnosticsQuestionDevices": "Un accessoire est-il absent, dupliqué ou affiché avec le mauvais type dans HomeKit ?",
148
- "diagnosticsQuestionLiveMedia": "Le problème concerne-t-il la vidéo en direct, un instantané ou l’interphone ?",
149
- "diagnosticsQuestionRecording": "Un enregistrement vidéo sécurisé HomeKit est-il absent ou illisible ?",
150
154
  "diagnosticsQuestionReproduceNow": "Pouvez-vous reproduire le problème maintenant ?",
151
- "diagnosticsQuestionStartup": "S’agit-il d’un problème de démarrage ou de connexion ?",
152
155
  "diagnosticsReauthorize": "Démarrer une nouvelle session de diagnostic",
153
156
  "diagnosticsRecordingAction": "Déclenchez un événement qui devrait être enregistré, attendez que l’enregistrement apparaisse, puis terminez.",
154
157
  "diagnosticsRecordingBefore": "Vérifiez que la vidéo sécurisée HomeKit est activée et notez approximativement quand l’événement survient. Les enregistrements ne sont jamais inclus.",
@@ -160,10 +163,17 @@
160
163
  "diagnosticsStartupAction": "Redémarrez Homebridge ou répétez l’étape de connexion en échec, puis revenez ici et terminez.",
161
164
  "diagnosticsStartupBefore": "Commencez la collecte avant un redémarrage. Ne partagez jamais de mot de passe, de réponse captcha ou de code de vérification.",
162
165
  "diagnosticsStartupSummary": "Vérifie un problème de démarrage, de connexion ou d’authentification de Homebridge.",
166
+ "diagnosticsStaysLocal": "Le fichier est chiffré et reste sur cette machine. Rien n’est envoyé.",
163
167
  "diagnosticsSummary": "Choisissez le problème, puis collectez ce qui se passe lorsqu’il survient.",
168
+ "diagnosticsTilesHeading": "Qu’est-ce qui ne va pas ?",
164
169
  "diagnosticsTitle": "Diagnostics guidés",
165
- "diagnosticsUseProfile": "Utiliser ce profil",
166
170
  "diagnosticsYes": "Oui",
171
+ "excludedCredentials": "vos identifiants eufy et votre mot de passe",
172
+ "excludedInternalData": "les données internes brutes non relues",
173
+ "excludedKeys": "les clés de chiffrement",
174
+ "excludedMedia": "toute image, vidéo ou audio de caméra",
175
+ "excludedSessions": "les sessions enregistrées et les inscriptions push",
176
+ "excludedTokens": "les jetons d’accès et les cookies",
167
177
  "firstSetupAcknowledgement": "J'ai créé un compte invité dédié et partagé mon domicile et mes appareils Eufy avec ce compte.",
168
178
  "firstSetupContinue": "Continuer",
169
179
  "firstSetupEyebrow": "Première configuration",
@@ -181,6 +191,7 @@
181
191
  "oneAccountSession": "Une seule session de compte à la fois",
182
192
  "pageTitle": "Connectez votre compte Eufy",
183
193
  "passwordLabel": "Mot de passe",
194
+ "preferenceArmingModes": "Modes de garde HomeKit",
184
195
  "preferenceAudio": "Audio HomeKit",
185
196
  "preferenceRepresented": "Exposer dans HomeKit",
186
197
  "preferenceSaveFailed": "La préférence n’a pas pu être enregistrée. Réessayez.",