iobroker.script-restore 0.1.1 → 0.1.2
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.de.md +3 -0
- package/README.md +3 -5
- package/admin/tab_m.html +572 -45
- package/io-package.json +14 -14
- package/package.json +1 -1
package/README.de.md
CHANGED
|
@@ -78,6 +78,9 @@ Das Archiv wird vollständig im Browser geparst — beim Durchsuchen werden kein
|
|
|
78
78
|
### **WORK IN PROGRESS**
|
|
79
79
|
-->
|
|
80
80
|
### **WORK IN PROGRESS**
|
|
81
|
+
* (ipod86) Vollständige i18n im Admin-Tab: alle Strings in de/en/fr/es/it/nl/pl/pt/ru/uk/zh-cn übersetzt
|
|
82
|
+
|
|
83
|
+
### 0.1.1 (2026-05-24)
|
|
81
84
|
* (ipod86) Überschreiben bestehender Skripte beim Restore erlaubt (Bestätigungs-Dialog mit Pfadanzeige)
|
|
82
85
|
* (ipod86) Leeres Suffix erlaubt, um Skript unter dem Originalnamen wiederherzustellen
|
|
83
86
|
* (ipod86) Hinweis nach erfolgreichem Restore: Skript direkt starten?
|
package/README.md
CHANGED
|
@@ -75,6 +75,9 @@ The archive is parsed entirely in the browser — no files are written to disk d
|
|
|
75
75
|
Placeholder for the next version (at the beginning of the line):
|
|
76
76
|
### **WORK IN PROGRESS**
|
|
77
77
|
-->
|
|
78
|
+
### 0.1.2 (2026-05-24)
|
|
79
|
+
* (ipod86) add full i18n to tab UI: all strings translated into de/en/fr/es/it/nl/pl/pt/ru/uk/zh-cn
|
|
80
|
+
|
|
78
81
|
### 0.1.1 (2026-05-24)
|
|
79
82
|
* (ipod86) allow overwriting existing scripts during restore (confirmation dialog with path display)
|
|
80
83
|
* (ipod86) allow empty suffix to restore script under its original name
|
|
@@ -95,11 +98,6 @@ The archive is parsed entirely in the browser — no files are written to disk d
|
|
|
95
98
|
* (ipod86) add direct restore into ioBroker with suffix input and confirm modal
|
|
96
99
|
* (ipod86) remove obsolete admin/words.js and .prettierignore
|
|
97
100
|
|
|
98
|
-
### 0.0.10 (2026-04-08)
|
|
99
|
-
* (ipod86) fix jsonConfig responsive sizes lg/xl for backupPath (E5509)
|
|
100
|
-
* (ipod86) trim news entries to 7 (W1032)
|
|
101
|
-
* (ipod86) add Dependabot npm cooldown of 7 days (W8915)
|
|
102
|
-
|
|
103
101
|
## License
|
|
104
102
|
MIT License
|
|
105
103
|
|
package/admin/tab_m.html
CHANGED
|
@@ -393,39 +393,39 @@
|
|
|
393
393
|
<div class="progress-inner"><span id="progressPercent">0%</span></div>
|
|
394
394
|
</div>
|
|
395
395
|
<div id="spinnerEl" class="spinner" style="display:none;"></div>
|
|
396
|
-
<div id="loaderText">Lade Backup...</div>
|
|
396
|
+
<div id="loaderText" data-i18n="loaderLoading">Lade Backup...</div>
|
|
397
397
|
</div>
|
|
398
398
|
|
|
399
399
|
<!-- Restore Modal -->
|
|
400
400
|
<div class="restore-modal-overlay" id="restoreModalOverlay" onclick="closeRestoreModal(event)">
|
|
401
401
|
<div class="restore-modal" onclick="event.stopPropagation()">
|
|
402
|
-
<h3>In ioBroker laden</h3>
|
|
402
|
+
<h3 data-i18n="modalTitle">In ioBroker laden</h3>
|
|
403
403
|
<div class="restore-modal-meta">
|
|
404
|
-
<div>Skript
|
|
405
|
-
<div>Pfad
|
|
406
|
-
<div>Typ
|
|
404
|
+
<div><span data-i18n="modalLabelScript">Skript:</span> <strong id="rmScriptName"></strong></div>
|
|
405
|
+
<div><span data-i18n="modalLabelPath">Pfad:</span> <strong id="rmScriptPath"></strong></div>
|
|
406
|
+
<div><span data-i18n="modalLabelType">Typ:</span> <strong id="rmScriptType"></strong></div>
|
|
407
407
|
</div>
|
|
408
|
-
<label for="rmSuffix">Suffix (wird an den Skriptnamen angehängt)</label>
|
|
408
|
+
<label for="rmSuffix" data-i18n="modalLabelSuffix">Suffix (wird an den Skriptnamen angehängt)</label>
|
|
409
409
|
<input type="text" id="rmSuffix" value="_rcvr" oninput="updateRestorePreview();">
|
|
410
410
|
<div class="restore-modal-preview" id="rmPreview"></div>
|
|
411
411
|
<div class="restore-modal-warning" id="rmWarning">
|
|
412
|
-
<p
|
|
412
|
+
<p></p>
|
|
413
413
|
<div class="rmw-actions">
|
|
414
|
-
<button class="btn btn-outline" onclick="dismissWarning()">Anderen Suffix wählen</button>
|
|
415
|
-
<button class="btn btn-danger" onclick="overwriteConfirmed()">Überschreiben</button>
|
|
414
|
+
<button class="btn btn-outline" onclick="dismissWarning()" data-i18n="modalDismiss">Anderen Suffix wählen</button>
|
|
415
|
+
<button class="btn btn-danger" onclick="overwriteConfirmed()" data-i18n="modalOverwrite">Überschreiben</button>
|
|
416
416
|
</div>
|
|
417
417
|
</div>
|
|
418
418
|
<div class="restore-modal-success" id="rmSuccess">
|
|
419
|
-
<p>✓ Erfolgreich wiederhergestellt.<br>Soll das Skript jetzt gestartet werden?</p>
|
|
419
|
+
<p data-i18n-html="modalSuccess">✓ Erfolgreich wiederhergestellt.<br>Soll das Skript jetzt gestartet werden?</p>
|
|
420
420
|
<div class="rmw-actions">
|
|
421
|
-
<button class="btn btn-outline" onclick="closeRestoreModal()">Nein danke</button>
|
|
422
|
-
<button class="btn btn-outline-success" id="rmStartBtn" onclick="startRestoredScript()">Jetzt starten</button>
|
|
421
|
+
<button class="btn btn-outline" onclick="closeRestoreModal()" data-i18n="modalClose">Nein danke</button>
|
|
422
|
+
<button class="btn btn-outline-success" id="rmStartBtn" onclick="startRestoredScript()" data-i18n="modalStart">Jetzt starten</button>
|
|
423
423
|
</div>
|
|
424
424
|
</div>
|
|
425
425
|
<div class="restore-modal-footer">
|
|
426
426
|
<span id="rmMsg" style="flex:1;font-size:0.85rem;align-self:center;"></span>
|
|
427
427
|
<button class="btn btn-outline" onclick="closeRestoreModal()">Schließen</button>
|
|
428
|
-
<button class="btn btn-outline-success" id="rmConfirmBtn" onclick="confirmRestoreScript(false)">Laden</button>
|
|
428
|
+
<button class="btn btn-outline-success" id="rmConfirmBtn" onclick="confirmRestoreScript(false)" data-i18n="modalLoad">Laden</button>
|
|
429
429
|
</div>
|
|
430
430
|
</div>
|
|
431
431
|
</div>
|
|
@@ -433,56 +433,56 @@
|
|
|
433
433
|
<div class="toolbar">
|
|
434
434
|
<div class="toolbar-left">
|
|
435
435
|
<label class="file-input-label">
|
|
436
|
-
|
|
436
|
+
<span data-i18n="uploadLabel">📂 Backup hochladen</span>
|
|
437
437
|
<input type="file" id="fileInput" accept=".tar,.gz,.tar.gz,.json,.jsonl">
|
|
438
438
|
</label>
|
|
439
439
|
<div class="dropdown-wrapper" id="localDropdown">
|
|
440
|
-
<button class="btn btn-outline" onclick="toggleDropdown('local')">
|
|
440
|
+
<button class="btn btn-outline" onclick="toggleDropdown('local')" data-i18n="localDropdown">
|
|
441
441
|
🗂️ Lokale Backups ▾
|
|
442
442
|
</button>
|
|
443
443
|
<div class="dropdown-menu" id="localMenu"></div>
|
|
444
444
|
</div>
|
|
445
445
|
<div class="dropdown-wrapper" id="ftpDropdown" style="display:none;">
|
|
446
|
-
<button class="btn btn-outline" onclick="toggleDropdown('ftp')">
|
|
446
|
+
<button class="btn btn-outline" onclick="toggleDropdown('ftp')" data-i18n="ftpDropdown">
|
|
447
447
|
🌐 FTP Backups ▾
|
|
448
448
|
</button>
|
|
449
449
|
<div class="dropdown-menu" id="ftpMenu"></div>
|
|
450
450
|
</div>
|
|
451
451
|
<div class="dropdown-wrapper" id="smbDropdown" style="display:none;">
|
|
452
|
-
<button class="btn btn-outline" onclick="toggleDropdown('smb')">
|
|
452
|
+
<button class="btn btn-outline" onclick="toggleDropdown('smb')" data-i18n="smbDropdown">
|
|
453
453
|
🗄️ SMB Backups ▾
|
|
454
454
|
</button>
|
|
455
455
|
<div class="dropdown-menu" id="smbMenu"></div>
|
|
456
456
|
</div>
|
|
457
457
|
<div class="dropdown-wrapper" id="sftpDropdown" style="display:none;">
|
|
458
|
-
<button class="btn btn-outline" onclick="toggleDropdown('sftp')">
|
|
458
|
+
<button class="btn btn-outline" onclick="toggleDropdown('sftp')" data-i18n="sftpDropdown">
|
|
459
459
|
🔒 SFTP Backups ▾
|
|
460
460
|
</button>
|
|
461
461
|
<div class="dropdown-menu" id="sftpMenu"></div>
|
|
462
462
|
</div>
|
|
463
463
|
<div class="dropdown-wrapper" id="webdavDropdown" style="display:none;">
|
|
464
|
-
<button class="btn btn-outline" onclick="toggleDropdown('webdav')">
|
|
464
|
+
<button class="btn btn-outline" onclick="toggleDropdown('webdav')" data-i18n="webdavDropdown">
|
|
465
465
|
☁️ WebDAV Backups ▾
|
|
466
466
|
</button>
|
|
467
467
|
<div class="dropdown-menu" id="webdavMenu"></div>
|
|
468
468
|
</div>
|
|
469
469
|
<div id="httpInputWrapper" style="display:none; align-items:center; gap:6px;">
|
|
470
470
|
<input type="text" id="httpUrlInput" placeholder="https://..." style="padding:0.35rem 0.6rem; border:1px solid #ced4da; border-radius:4px; font-size:0.875rem; min-width:260px; font-family:inherit;">
|
|
471
|
-
<button type="button" class="btn btn-outline" onclick="loadHttpUrl()">🌐 URL laden</button>
|
|
471
|
+
<button type="button" class="btn btn-outline" onclick="loadHttpUrl()" data-i18n="httpLoadBtn">🌐 URL laden</button>
|
|
472
472
|
</div>
|
|
473
|
-
<button id="zipBtn" class="btn btn-outline" onclick="downloadZip()" style="display:none;">📦 ZIP</button>
|
|
474
|
-
<span class="status-msg" id="statusMsg">Backup laden oder Quelle wählen</span>
|
|
473
|
+
<button id="zipBtn" class="btn btn-outline" onclick="downloadZip()" style="display:none;" data-i18n="zipBtn">📦 ZIP</button>
|
|
474
|
+
<span class="status-msg" id="statusMsg" data-i18n="statusDefault">Backup laden oder Quelle wählen</span>
|
|
475
475
|
</div>
|
|
476
476
|
</div>
|
|
477
477
|
|
|
478
478
|
<div class="main-container">
|
|
479
479
|
<div class="sidebar" id="sidebar">
|
|
480
480
|
<div class="sidebar-header">
|
|
481
|
-
<input type="text" id="q" placeholder="Suche in Namen, Ordner & Code...">
|
|
482
|
-
<button class="btn-icon" id="expandToggleBtn" onclick="toggleExpandAll()" title="Alle Ordner aufklappen">📂</button>
|
|
481
|
+
<input type="text" id="q" data-i18n-placeholder="searchPlaceholder" placeholder="Suche in Namen, Ordner & Code...">
|
|
482
|
+
<button class="btn-icon" id="expandToggleBtn" onclick="toggleExpandAll()" data-i18n-title="expandAll" title="Alle Ordner aufklappen">📂</button>
|
|
483
483
|
</div>
|
|
484
484
|
<div class="type-filter-bar">
|
|
485
|
-
<button class="btn-type active" onclick="setTypeFilter(this, '')">Alle</button>
|
|
485
|
+
<button class="btn-type active" onclick="setTypeFilter(this, '')" data-i18n="typeAll">Alle</button>
|
|
486
486
|
<button class="btn-type" onclick="setTypeFilter(this, 'JS')"><span class="type-badge badge-JS">JS</span></button>
|
|
487
487
|
<button class="btn-type" onclick="setTypeFilter(this, 'TypeScript')"><span class="type-badge badge-TypeScript">TS</span></button>
|
|
488
488
|
<button class="btn-type" onclick="setTypeFilter(this, 'Blockly')"><span class="type-badge badge-Blockly">Blockly</span></button>
|
|
@@ -498,17 +498,16 @@
|
|
|
498
498
|
<div class="action-bar-inner">
|
|
499
499
|
<div class="btn-group" id="viewSwitcher"></div>
|
|
500
500
|
<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap;">
|
|
501
|
-
<button onclick="openRestoreModal()" class="btn btn-outline-success" id="restoreBtn">In ioBroker laden</button>
|
|
502
|
-
<button onclick="copyCode(this)" class="btn btn-outline-light">Code Kopieren</button>
|
|
503
|
-
<button onclick="downloadActive()" class="btn btn-primary" id="dlBtn">Download</button>
|
|
501
|
+
<button onclick="openRestoreModal()" class="btn btn-outline-success" id="restoreBtn" data-i18n="restoreBtn">In ioBroker laden</button>
|
|
502
|
+
<button onclick="copyCode(this)" class="btn btn-outline-light" data-i18n="copyBtnAction">Code Kopieren</button>
|
|
503
|
+
<button onclick="downloadActive()" class="btn btn-primary" id="dlBtn" data-i18n="downloadBtn">Download</button>
|
|
504
504
|
</div>
|
|
505
505
|
</div>
|
|
506
506
|
</div>
|
|
507
507
|
<div id="codeContainer" class="code-empty">
|
|
508
508
|
<div>
|
|
509
509
|
<strong>ioBroker Script Restore</strong><br><br>
|
|
510
|
-
Lade ein Backup hoch oder wähle eine lokale Datei,<br>
|
|
511
|
-
um Skripte anzuzeigen und wiederherzustellen.
|
|
510
|
+
<span data-i18n-html="welcomeText">Lade ein Backup hoch oder wähle eine lokale Datei,<br>um Skripte anzuzeigen und wiederherzustellen.</span>
|
|
512
511
|
</div>
|
|
513
512
|
</div>
|
|
514
513
|
</div>
|
|
@@ -520,6 +519,534 @@
|
|
|
520
519
|
const instance = urlParams.get('instance') || '0';
|
|
521
520
|
const adapterInst = 'script-restore.' + instance;
|
|
522
521
|
|
|
522
|
+
// === i18n ===
|
|
523
|
+
const TRANSLATIONS = {
|
|
524
|
+
de: {
|
|
525
|
+
loaderLoading: 'Lade Backup...',
|
|
526
|
+
loaderProcessing: 'Verarbeite...',
|
|
527
|
+
modalTitle: 'In ioBroker laden',
|
|
528
|
+
modalLabelScript: 'Skript:',
|
|
529
|
+
modalLabelPath: 'Pfad:',
|
|
530
|
+
modalLabelType: 'Typ:',
|
|
531
|
+
modalLabelSuffix: 'Suffix (wird an den Skriptnamen angehängt)',
|
|
532
|
+
modalWarning: '⚠ Ein Skript unter {path} existiert bereits.<br>Soll es wirklich überschrieben werden?',
|
|
533
|
+
modalDismiss: 'Anderen Suffix wählen',
|
|
534
|
+
modalOverwrite: 'Überschreiben',
|
|
535
|
+
modalSuccess: '✓ Erfolgreich wiederhergestellt.<br>Soll das Skript jetzt gestartet werden?',
|
|
536
|
+
modalClose: 'Nein danke',
|
|
537
|
+
modalStart: 'Jetzt starten',
|
|
538
|
+
modalLoad: 'Laden',
|
|
539
|
+
modalLoading: '⏳ Laden...',
|
|
540
|
+
modalStarting: '⏳ Starte...',
|
|
541
|
+
modalStarted: '✓ Gestartet',
|
|
542
|
+
modalLoaded: '✓ Geladen!',
|
|
543
|
+
modalUnknownError: '✗ Unbekannter Fehler',
|
|
544
|
+
modalErrorPrefix: '✗ Fehler: ',
|
|
545
|
+
copyBtn: 'Code Kopieren',
|
|
546
|
+
copyBtnAction: 'Code Kopieren',
|
|
547
|
+
copied: '✓ Kopiert!',
|
|
548
|
+
uploadLabel: '📂 Backup hochladen',
|
|
549
|
+
localDropdown: '🗂️ Lokale Backups ▾',
|
|
550
|
+
ftpDropdown: '🌐 FTP Backups ▾',
|
|
551
|
+
smbDropdown: '🗄️ SMB Backups ▾',
|
|
552
|
+
sftpDropdown: '🔒 SFTP Backups ▾',
|
|
553
|
+
webdavDropdown: '☁️ WebDAV Backups ▾',
|
|
554
|
+
httpLoadBtn: '🌐 URL laden',
|
|
555
|
+
zipBtn: '📦 ZIP',
|
|
556
|
+
statusDefault: 'Backup laden oder Quelle wählen',
|
|
557
|
+
searchPlaceholder: 'Suche in Namen, Ordner & Code...',
|
|
558
|
+
expandAll: 'Alle aufklappen',
|
|
559
|
+
collapseAll: 'Alle einklappen',
|
|
560
|
+
typeAll: 'Alle',
|
|
561
|
+
restoreBtn: 'In ioBroker laden',
|
|
562
|
+
downloadBtn: 'Download',
|
|
563
|
+
welcomeText: 'Lade ein Backup hoch oder wähle eine lokale Datei,<br>um Skripte anzuzeigen und wiederherzustellen.',
|
|
564
|
+
noSocket: 'Kein Socket. Bitte prüfen ob script-restore.{i} läuft.',
|
|
565
|
+
timeout: 'Timeout: Adapter antwortet nicht. Läuft script-restore.{i}?',
|
|
566
|
+
},
|
|
567
|
+
en: {
|
|
568
|
+
loaderLoading: 'Loading backup...',
|
|
569
|
+
loaderProcessing: 'Processing...',
|
|
570
|
+
modalTitle: 'Load into ioBroker',
|
|
571
|
+
modalLabelScript: 'Script:',
|
|
572
|
+
modalLabelPath: 'Path:',
|
|
573
|
+
modalLabelType: 'Type:',
|
|
574
|
+
modalLabelSuffix: 'Suffix (appended to the script name)',
|
|
575
|
+
modalWarning: '⚠ A script at {path} already exists.<br>Do you really want to overwrite it?',
|
|
576
|
+
modalDismiss: 'Choose different suffix',
|
|
577
|
+
modalOverwrite: 'Overwrite',
|
|
578
|
+
modalSuccess: '✓ Successfully restored.<br>Do you want to start the script now?',
|
|
579
|
+
modalClose: 'No thanks',
|
|
580
|
+
modalStart: 'Start now',
|
|
581
|
+
modalLoad: 'Load',
|
|
582
|
+
modalLoading: '⏳ Loading...',
|
|
583
|
+
modalStarting: '⏳ Starting...',
|
|
584
|
+
modalStarted: '✓ Started',
|
|
585
|
+
modalLoaded: '✓ Loaded!',
|
|
586
|
+
modalUnknownError: '✗ Unknown error',
|
|
587
|
+
modalErrorPrefix: '✗ Error: ',
|
|
588
|
+
copyBtn: 'Copy Code',
|
|
589
|
+
copyBtnAction: 'Copy Code',
|
|
590
|
+
copied: '✓ Copied!',
|
|
591
|
+
uploadLabel: '📂 Upload backup',
|
|
592
|
+
localDropdown: '🗂️ Local Backups ▾',
|
|
593
|
+
ftpDropdown: '🌐 FTP Backups ▾',
|
|
594
|
+
smbDropdown: '🗄️ SMB Backups ▾',
|
|
595
|
+
sftpDropdown: '🔒 SFTP Backups ▾',
|
|
596
|
+
webdavDropdown: '☁️ WebDAV Backups ▾',
|
|
597
|
+
httpLoadBtn: '🌐 Load URL',
|
|
598
|
+
zipBtn: '📦 ZIP',
|
|
599
|
+
statusDefault: 'Load a backup or select a source',
|
|
600
|
+
searchPlaceholder: 'Search in names, folders & code...',
|
|
601
|
+
expandAll: 'Expand all',
|
|
602
|
+
collapseAll: 'Collapse all',
|
|
603
|
+
typeAll: 'All',
|
|
604
|
+
restoreBtn: 'Load into ioBroker',
|
|
605
|
+
downloadBtn: 'Download',
|
|
606
|
+
welcomeText: 'Upload a backup or select a local file,<br>to view and restore scripts.',
|
|
607
|
+
noSocket: 'No socket. Please check if script-restore.{i} is running.',
|
|
608
|
+
timeout: 'Timeout: Adapter not responding. Is script-restore.{i} running?',
|
|
609
|
+
},
|
|
610
|
+
fr: {
|
|
611
|
+
loaderLoading: 'Chargement de la sauvegarde...',
|
|
612
|
+
loaderProcessing: 'Traitement en cours...',
|
|
613
|
+
modalTitle: 'Charger dans ioBroker',
|
|
614
|
+
modalLabelScript: 'Script :',
|
|
615
|
+
modalLabelPath: 'Chemin :',
|
|
616
|
+
modalLabelType: 'Type :',
|
|
617
|
+
modalLabelSuffix: 'Suffixe (ajouté au nom du script)',
|
|
618
|
+
modalWarning: '⚠ Un script à {path} existe déjà.<br>Voulez-vous vraiment l\'écraser ?',
|
|
619
|
+
modalDismiss: 'Choisir un autre suffixe',
|
|
620
|
+
modalOverwrite: 'Écraser',
|
|
621
|
+
modalSuccess: '✓ Restauré avec succès.<br>Voulez-vous démarrer le script maintenant ?',
|
|
622
|
+
modalClose: 'Non merci',
|
|
623
|
+
modalStart: 'Démarrer maintenant',
|
|
624
|
+
modalLoad: 'Charger',
|
|
625
|
+
modalLoading: '⏳ Chargement...',
|
|
626
|
+
modalStarting: '⏳ Démarrage...',
|
|
627
|
+
modalStarted: '✓ Démarré',
|
|
628
|
+
modalLoaded: '✓ Chargé !',
|
|
629
|
+
modalUnknownError: '✗ Erreur inconnue',
|
|
630
|
+
modalErrorPrefix: '✗ Erreur : ',
|
|
631
|
+
copyBtn: 'Copier le code',
|
|
632
|
+
copyBtnAction: 'Copier le code',
|
|
633
|
+
copied: '✓ Copié !',
|
|
634
|
+
uploadLabel: '📂 Téléverser une sauvegarde',
|
|
635
|
+
localDropdown: '🗂️ Sauvegardes locales ▾',
|
|
636
|
+
ftpDropdown: '🌐 Sauvegardes FTP ▾',
|
|
637
|
+
smbDropdown: '🗄️ Sauvegardes SMB ▾',
|
|
638
|
+
sftpDropdown: '🔒 Sauvegardes SFTP ▾',
|
|
639
|
+
webdavDropdown: '☁️ Sauvegardes WebDAV ▾',
|
|
640
|
+
httpLoadBtn: '🌐 Charger URL',
|
|
641
|
+
zipBtn: '📦 ZIP',
|
|
642
|
+
statusDefault: 'Charger une sauvegarde ou choisir une source',
|
|
643
|
+
searchPlaceholder: 'Rechercher dans les noms, dossiers et code...',
|
|
644
|
+
expandAll: 'Tout développer',
|
|
645
|
+
collapseAll: 'Tout réduire',
|
|
646
|
+
typeAll: 'Tous',
|
|
647
|
+
restoreBtn: 'Charger dans ioBroker',
|
|
648
|
+
downloadBtn: 'Télécharger',
|
|
649
|
+
welcomeText: 'Téléversez une sauvegarde ou sélectionnez un fichier local,<br>pour afficher et restaurer des scripts.',
|
|
650
|
+
noSocket: 'Pas de socket. Vérifiez si script-restore.{i} est en cours d\'exécution.',
|
|
651
|
+
timeout: 'Délai d\'attente : l\'adaptateur ne répond pas. script-restore.{i} est-il en cours d\'exécution ?',
|
|
652
|
+
},
|
|
653
|
+
es: {
|
|
654
|
+
loaderLoading: 'Cargando copia de seguridad...',
|
|
655
|
+
loaderProcessing: 'Procesando...',
|
|
656
|
+
modalTitle: 'Cargar en ioBroker',
|
|
657
|
+
modalLabelScript: 'Script:',
|
|
658
|
+
modalLabelPath: 'Ruta:',
|
|
659
|
+
modalLabelType: 'Tipo:',
|
|
660
|
+
modalLabelSuffix: 'Sufijo (se añade al nombre del script)',
|
|
661
|
+
modalWarning: '⚠ Ya existe un script en {path}.<br>¿Realmente desea sobrescribirlo?',
|
|
662
|
+
modalDismiss: 'Elegir otro sufijo',
|
|
663
|
+
modalOverwrite: 'Sobrescribir',
|
|
664
|
+
modalSuccess: '✓ Restaurado con éxito.<br>¿Desea iniciar el script ahora?',
|
|
665
|
+
modalClose: 'No gracias',
|
|
666
|
+
modalStart: 'Iniciar ahora',
|
|
667
|
+
modalLoad: 'Cargar',
|
|
668
|
+
modalLoading: '⏳ Cargando...',
|
|
669
|
+
modalStarting: '⏳ Iniciando...',
|
|
670
|
+
modalStarted: '✓ Iniciado',
|
|
671
|
+
modalLoaded: '✓ ¡Cargado!',
|
|
672
|
+
modalUnknownError: '✗ Error desconocido',
|
|
673
|
+
modalErrorPrefix: '✗ Error: ',
|
|
674
|
+
copyBtn: 'Copiar código',
|
|
675
|
+
copyBtnAction: 'Copiar código',
|
|
676
|
+
copied: '✓ ¡Copiado!',
|
|
677
|
+
uploadLabel: '📂 Subir copia de seguridad',
|
|
678
|
+
localDropdown: '🗂️ Copias locales ▾',
|
|
679
|
+
ftpDropdown: '🌐 Copias FTP ▾',
|
|
680
|
+
smbDropdown: '🗄️ Copias SMB ▾',
|
|
681
|
+
sftpDropdown: '🔒 Copias SFTP ▾',
|
|
682
|
+
webdavDropdown: '☁️ Copias WebDAV ▾',
|
|
683
|
+
httpLoadBtn: '🌐 Cargar URL',
|
|
684
|
+
zipBtn: '📦 ZIP',
|
|
685
|
+
statusDefault: 'Cargar una copia de seguridad o seleccionar una fuente',
|
|
686
|
+
searchPlaceholder: 'Buscar en nombres, carpetas y código...',
|
|
687
|
+
expandAll: 'Expandir todo',
|
|
688
|
+
collapseAll: 'Contraer todo',
|
|
689
|
+
typeAll: 'Todos',
|
|
690
|
+
restoreBtn: 'Cargar en ioBroker',
|
|
691
|
+
downloadBtn: 'Descargar',
|
|
692
|
+
welcomeText: 'Sube una copia de seguridad o selecciona un archivo local,<br>para ver y restaurar scripts.',
|
|
693
|
+
noSocket: 'Sin socket. Compruebe si script-restore.{i} está en ejecución.',
|
|
694
|
+
timeout: 'Tiempo de espera agotado: el adaptador no responde. ¿Está script-restore.{i} en ejecución?',
|
|
695
|
+
},
|
|
696
|
+
it: {
|
|
697
|
+
loaderLoading: 'Caricamento backup...',
|
|
698
|
+
loaderProcessing: 'Elaborazione...',
|
|
699
|
+
modalTitle: 'Carica in ioBroker',
|
|
700
|
+
modalLabelScript: 'Script:',
|
|
701
|
+
modalLabelPath: 'Percorso:',
|
|
702
|
+
modalLabelType: 'Tipo:',
|
|
703
|
+
modalLabelSuffix: 'Suffisso (aggiunto al nome dello script)',
|
|
704
|
+
modalWarning: '⚠ Esiste già uno script in {path}.<br>Vuoi davvero sovrascriverlo?',
|
|
705
|
+
modalDismiss: 'Scegli un suffisso diverso',
|
|
706
|
+
modalOverwrite: 'Sovrascrivi',
|
|
707
|
+
modalSuccess: '✓ Ripristinato con successo.<br>Vuoi avviare lo script adesso?',
|
|
708
|
+
modalClose: 'No grazie',
|
|
709
|
+
modalStart: 'Avvia ora',
|
|
710
|
+
modalLoad: 'Carica',
|
|
711
|
+
modalLoading: '⏳ Caricamento...',
|
|
712
|
+
modalStarting: '⏳ Avvio...',
|
|
713
|
+
modalStarted: '✓ Avviato',
|
|
714
|
+
modalLoaded: '✓ Caricato!',
|
|
715
|
+
modalUnknownError: '✗ Errore sconosciuto',
|
|
716
|
+
modalErrorPrefix: '✗ Errore: ',
|
|
717
|
+
copyBtn: 'Copia codice',
|
|
718
|
+
copyBtnAction: 'Copia codice',
|
|
719
|
+
copied: '✓ Copiato!',
|
|
720
|
+
uploadLabel: '📂 Carica backup',
|
|
721
|
+
localDropdown: '🗂️ Backup locali ▾',
|
|
722
|
+
ftpDropdown: '🌐 Backup FTP ▾',
|
|
723
|
+
smbDropdown: '🗄️ Backup SMB ▾',
|
|
724
|
+
sftpDropdown: '🔒 Backup SFTP ▾',
|
|
725
|
+
webdavDropdown: '☁️ Backup WebDAV ▾',
|
|
726
|
+
httpLoadBtn: '🌐 Carica URL',
|
|
727
|
+
zipBtn: '📦 ZIP',
|
|
728
|
+
statusDefault: 'Carica un backup o seleziona una sorgente',
|
|
729
|
+
searchPlaceholder: 'Cerca in nomi, cartelle e codice...',
|
|
730
|
+
expandAll: 'Espandi tutto',
|
|
731
|
+
collapseAll: 'Comprimi tutto',
|
|
732
|
+
typeAll: 'Tutti',
|
|
733
|
+
restoreBtn: 'Carica in ioBroker',
|
|
734
|
+
downloadBtn: 'Scarica',
|
|
735
|
+
welcomeText: 'Carica un backup o seleziona un file locale,<br>per visualizzare e ripristinare gli script.',
|
|
736
|
+
noSocket: 'Nessun socket. Verificare se script-restore.{i} è in esecuzione.',
|
|
737
|
+
timeout: 'Timeout: l\'adattatore non risponde. script-restore.{i} è in esecuzione?',
|
|
738
|
+
},
|
|
739
|
+
nl: {
|
|
740
|
+
loaderLoading: 'Back-up laden...',
|
|
741
|
+
loaderProcessing: 'Verwerken...',
|
|
742
|
+
modalTitle: 'Laden in ioBroker',
|
|
743
|
+
modalLabelScript: 'Script:',
|
|
744
|
+
modalLabelPath: 'Pad:',
|
|
745
|
+
modalLabelType: 'Type:',
|
|
746
|
+
modalLabelSuffix: 'Achtervoegsel (toegevoegd aan de scriptnaam)',
|
|
747
|
+
modalWarning: '⚠ Er bestaat al een script op {path}.<br>Wilt u het echt overschrijven?',
|
|
748
|
+
modalDismiss: 'Ander achtervoegsel kiezen',
|
|
749
|
+
modalOverwrite: 'Overschrijven',
|
|
750
|
+
modalSuccess: '✓ Succesvol hersteld.<br>Wilt u het script nu starten?',
|
|
751
|
+
modalClose: 'Nee bedankt',
|
|
752
|
+
modalStart: 'Nu starten',
|
|
753
|
+
modalLoad: 'Laden',
|
|
754
|
+
modalLoading: '⏳ Laden...',
|
|
755
|
+
modalStarting: '⏳ Starten...',
|
|
756
|
+
modalStarted: '✓ Gestart',
|
|
757
|
+
modalLoaded: '✓ Geladen!',
|
|
758
|
+
modalUnknownError: '✗ Onbekende fout',
|
|
759
|
+
modalErrorPrefix: '✗ Fout: ',
|
|
760
|
+
copyBtn: 'Code kopiëren',
|
|
761
|
+
copyBtnAction: 'Code kopiëren',
|
|
762
|
+
copied: '✓ Gekopieerd!',
|
|
763
|
+
uploadLabel: '📂 Back-up uploaden',
|
|
764
|
+
localDropdown: '🗂️ Lokale back-ups ▾',
|
|
765
|
+
ftpDropdown: '🌐 FTP back-ups ▾',
|
|
766
|
+
smbDropdown: '🗄️ SMB back-ups ▾',
|
|
767
|
+
sftpDropdown: '🔒 SFTP back-ups ▾',
|
|
768
|
+
webdavDropdown: '☁️ WebDAV back-ups ▾',
|
|
769
|
+
httpLoadBtn: '🌐 URL laden',
|
|
770
|
+
zipBtn: '📦 ZIP',
|
|
771
|
+
statusDefault: 'Laad een back-up of kies een bron',
|
|
772
|
+
searchPlaceholder: 'Zoeken in namen, mappen en code...',
|
|
773
|
+
expandAll: 'Alles uitklappen',
|
|
774
|
+
collapseAll: 'Alles inklappen',
|
|
775
|
+
typeAll: 'Alle',
|
|
776
|
+
restoreBtn: 'Laden in ioBroker',
|
|
777
|
+
downloadBtn: 'Downloaden',
|
|
778
|
+
welcomeText: 'Upload een back-up of selecteer een lokaal bestand,<br>om scripts te bekijken en te herstellen.',
|
|
779
|
+
noSocket: 'Geen socket. Controleer of script-restore.{i} actief is.',
|
|
780
|
+
timeout: 'Time-out: adapter reageert niet. Is script-restore.{i} actief?',
|
|
781
|
+
},
|
|
782
|
+
pl: {
|
|
783
|
+
loaderLoading: 'Wczytywanie kopii zapasowej...',
|
|
784
|
+
loaderProcessing: 'Przetwarzanie...',
|
|
785
|
+
modalTitle: 'Wczytaj do ioBroker',
|
|
786
|
+
modalLabelScript: 'Skrypt:',
|
|
787
|
+
modalLabelPath: 'Ścieżka:',
|
|
788
|
+
modalLabelType: 'Typ:',
|
|
789
|
+
modalLabelSuffix: 'Sufiks (dodawany do nazwy skryptu)',
|
|
790
|
+
modalWarning: '⚠ Skrypt w {path} już istnieje.<br>Czy na pewno chcesz go nadpisać?',
|
|
791
|
+
modalDismiss: 'Wybierz inny sufiks',
|
|
792
|
+
modalOverwrite: 'Nadpisz',
|
|
793
|
+
modalSuccess: '✓ Przywrócono pomyślnie.<br>Czy chcesz teraz uruchomić skrypt?',
|
|
794
|
+
modalClose: 'Nie, dziękuję',
|
|
795
|
+
modalStart: 'Uruchom teraz',
|
|
796
|
+
modalLoad: 'Wczytaj',
|
|
797
|
+
modalLoading: '⏳ Wczytywanie...',
|
|
798
|
+
modalStarting: '⏳ Uruchamianie...',
|
|
799
|
+
modalStarted: '✓ Uruchomiono',
|
|
800
|
+
modalLoaded: '✓ Wczytano!',
|
|
801
|
+
modalUnknownError: '✗ Nieznany błąd',
|
|
802
|
+
modalErrorPrefix: '✗ Błąd: ',
|
|
803
|
+
copyBtn: 'Kopiuj kod',
|
|
804
|
+
copyBtnAction: 'Kopiuj kod',
|
|
805
|
+
copied: '✓ Skopiowano!',
|
|
806
|
+
uploadLabel: '📂 Prześlij kopię zapasową',
|
|
807
|
+
localDropdown: '🗂️ Lokalne kopie ▾',
|
|
808
|
+
ftpDropdown: '🌐 Kopie FTP ▾',
|
|
809
|
+
smbDropdown: '🗄️ Kopie SMB ▾',
|
|
810
|
+
sftpDropdown: '🔒 Kopie SFTP ▾',
|
|
811
|
+
webdavDropdown: '☁️ Kopie WebDAV ▾',
|
|
812
|
+
httpLoadBtn: '🌐 Wczytaj URL',
|
|
813
|
+
zipBtn: '📦 ZIP',
|
|
814
|
+
statusDefault: 'Wczytaj kopię zapasową lub wybierz źródło',
|
|
815
|
+
searchPlaceholder: 'Szukaj w nazwach, folderach i kodzie...',
|
|
816
|
+
expandAll: 'Rozwiń wszystko',
|
|
817
|
+
collapseAll: 'Zwiń wszystko',
|
|
818
|
+
typeAll: 'Wszystkie',
|
|
819
|
+
restoreBtn: 'Wczytaj do ioBroker',
|
|
820
|
+
downloadBtn: 'Pobierz',
|
|
821
|
+
welcomeText: 'Prześlij kopię zapasową lub wybierz plik lokalny,<br>aby wyświetlić i przywrócić skrypty.',
|
|
822
|
+
noSocket: 'Brak gniazda. Sprawdź, czy script-restore.{i} działa.',
|
|
823
|
+
timeout: 'Przekroczono czas: adapter nie odpowiada. Czy script-restore.{i} działa?',
|
|
824
|
+
},
|
|
825
|
+
pt: {
|
|
826
|
+
loaderLoading: 'A carregar cópia de segurança...',
|
|
827
|
+
loaderProcessing: 'A processar...',
|
|
828
|
+
modalTitle: 'Carregar no ioBroker',
|
|
829
|
+
modalLabelScript: 'Script:',
|
|
830
|
+
modalLabelPath: 'Caminho:',
|
|
831
|
+
modalLabelType: 'Tipo:',
|
|
832
|
+
modalLabelSuffix: 'Sufixo (adicionado ao nome do script)',
|
|
833
|
+
modalWarning: '⚠ Já existe um script em {path}.<br>Tem a certeza que deseja substituí-lo?',
|
|
834
|
+
modalDismiss: 'Escolher outro sufixo',
|
|
835
|
+
modalOverwrite: 'Substituir',
|
|
836
|
+
modalSuccess: '✓ Restaurado com sucesso.<br>Deseja iniciar o script agora?',
|
|
837
|
+
modalClose: 'Não, obrigado',
|
|
838
|
+
modalStart: 'Iniciar agora',
|
|
839
|
+
modalLoad: 'Carregar',
|
|
840
|
+
modalLoading: '⏳ A carregar...',
|
|
841
|
+
modalStarting: '⏳ A iniciar...',
|
|
842
|
+
modalStarted: '✓ Iniciado',
|
|
843
|
+
modalLoaded: '✓ Carregado!',
|
|
844
|
+
modalUnknownError: '✗ Erro desconhecido',
|
|
845
|
+
modalErrorPrefix: '✗ Erro: ',
|
|
846
|
+
copyBtn: 'Copiar código',
|
|
847
|
+
copyBtnAction: 'Copiar código',
|
|
848
|
+
copied: '✓ Copiado!',
|
|
849
|
+
uploadLabel: '📂 Carregar cópia de segurança',
|
|
850
|
+
localDropdown: '🗂️ Cópias locais ▾',
|
|
851
|
+
ftpDropdown: '🌐 Cópias FTP ▾',
|
|
852
|
+
smbDropdown: '🗄️ Cópias SMB ▾',
|
|
853
|
+
sftpDropdown: '🔒 Cópias SFTP ▾',
|
|
854
|
+
webdavDropdown: '☁️ Cópias WebDAV ▾',
|
|
855
|
+
httpLoadBtn: '🌐 Carregar URL',
|
|
856
|
+
zipBtn: '📦 ZIP',
|
|
857
|
+
statusDefault: 'Carregar uma cópia de segurança ou selecionar uma fonte',
|
|
858
|
+
searchPlaceholder: 'Pesquisar em nomes, pastas e código...',
|
|
859
|
+
expandAll: 'Expandir tudo',
|
|
860
|
+
collapseAll: 'Recolher tudo',
|
|
861
|
+
typeAll: 'Todos',
|
|
862
|
+
restoreBtn: 'Carregar no ioBroker',
|
|
863
|
+
downloadBtn: 'Transferir',
|
|
864
|
+
welcomeText: 'Carregue uma cópia de segurança ou selecione um ficheiro local,<br>para ver e restaurar scripts.',
|
|
865
|
+
noSocket: 'Sem socket. Verifique se script-restore.{i} está em execução.',
|
|
866
|
+
timeout: 'Tempo esgotado: o adaptador não responde. O script-restore.{i} está em execução?',
|
|
867
|
+
},
|
|
868
|
+
ru: {
|
|
869
|
+
loaderLoading: 'Загрузка резервной копии...',
|
|
870
|
+
loaderProcessing: 'Обработка...',
|
|
871
|
+
modalTitle: 'Загрузить в ioBroker',
|
|
872
|
+
modalLabelScript: 'Скрипт:',
|
|
873
|
+
modalLabelPath: 'Путь:',
|
|
874
|
+
modalLabelType: 'Тип:',
|
|
875
|
+
modalLabelSuffix: 'Суффикс (добавляется к имени скрипта)',
|
|
876
|
+
modalWarning: '⚠ Скрипт по пути {path} уже существует.<br>Вы действительно хотите перезаписать его?',
|
|
877
|
+
modalDismiss: 'Выбрать другой суффикс',
|
|
878
|
+
modalOverwrite: 'Перезаписать',
|
|
879
|
+
modalSuccess: '✓ Успешно восстановлено.<br>Хотите запустить скрипт сейчас?',
|
|
880
|
+
modalClose: 'Нет, спасибо',
|
|
881
|
+
modalStart: 'Запустить сейчас',
|
|
882
|
+
modalLoad: 'Загрузить',
|
|
883
|
+
modalLoading: '⏳ Загрузка...',
|
|
884
|
+
modalStarting: '⏳ Запуск...',
|
|
885
|
+
modalStarted: '✓ Запущен',
|
|
886
|
+
modalLoaded: '✓ Загружен!',
|
|
887
|
+
modalUnknownError: '✗ Неизвестная ошибка',
|
|
888
|
+
modalErrorPrefix: '✗ Ошибка: ',
|
|
889
|
+
copyBtn: 'Копировать код',
|
|
890
|
+
copyBtnAction: 'Копировать код',
|
|
891
|
+
copied: '✓ Скопировано!',
|
|
892
|
+
uploadLabel: '📂 Загрузить резервную копию',
|
|
893
|
+
localDropdown: '🗂️ Локальные резервные копии ▾',
|
|
894
|
+
ftpDropdown: '🌐 Резервные копии FTP ▾',
|
|
895
|
+
smbDropdown: '🗄️ Резервные копии SMB ▾',
|
|
896
|
+
sftpDropdown: '🔒 Резервные копии SFTP ▾',
|
|
897
|
+
webdavDropdown: '☁️ Резервные копии WebDAV ▾',
|
|
898
|
+
httpLoadBtn: '🌐 Загрузить URL',
|
|
899
|
+
zipBtn: '📦 ZIP',
|
|
900
|
+
statusDefault: 'Загрузите резервную копию или выберите источник',
|
|
901
|
+
searchPlaceholder: 'Поиск по именам, папкам и коду...',
|
|
902
|
+
expandAll: 'Развернуть всё',
|
|
903
|
+
collapseAll: 'Свернуть всё',
|
|
904
|
+
typeAll: 'Все',
|
|
905
|
+
restoreBtn: 'Загрузить в ioBroker',
|
|
906
|
+
downloadBtn: 'Скачать',
|
|
907
|
+
welcomeText: 'Загрузите резервную копию или выберите локальный файл,<br>чтобы просмотреть и восстановить скрипты.',
|
|
908
|
+
noSocket: 'Нет сокета. Проверьте, запущен ли script-restore.{i}.',
|
|
909
|
+
timeout: 'Таймаут: адаптер не отвечает. Запущен ли script-restore.{i}?',
|
|
910
|
+
},
|
|
911
|
+
uk: {
|
|
912
|
+
loaderLoading: 'Завантаження резервної копії...',
|
|
913
|
+
loaderProcessing: 'Обробка...',
|
|
914
|
+
modalTitle: 'Завантажити в ioBroker',
|
|
915
|
+
modalLabelScript: 'Скрипт:',
|
|
916
|
+
modalLabelPath: 'Шлях:',
|
|
917
|
+
modalLabelType: 'Тип:',
|
|
918
|
+
modalLabelSuffix: 'Суфікс (додається до назви скрипта)',
|
|
919
|
+
modalWarning: '⚠ Скрипт за шляхом {path} вже існує.<br>Ви дійсно хочете його перезаписати?',
|
|
920
|
+
modalDismiss: 'Вибрати інший суфікс',
|
|
921
|
+
modalOverwrite: 'Перезаписати',
|
|
922
|
+
modalSuccess: '✓ Успішно відновлено.<br>Хочете запустити скрипт зараз?',
|
|
923
|
+
modalClose: 'Ні, дякую',
|
|
924
|
+
modalStart: 'Запустити зараз',
|
|
925
|
+
modalLoad: 'Завантажити',
|
|
926
|
+
modalLoading: '⏳ Завантаження...',
|
|
927
|
+
modalStarting: '⏳ Запуск...',
|
|
928
|
+
modalStarted: '✓ Запущено',
|
|
929
|
+
modalLoaded: '✓ Завантажено!',
|
|
930
|
+
modalUnknownError: '✗ Невідома помилка',
|
|
931
|
+
modalErrorPrefix: '✗ Помилка: ',
|
|
932
|
+
copyBtn: 'Копіювати код',
|
|
933
|
+
copyBtnAction: 'Копіювати код',
|
|
934
|
+
copied: '✓ Скопійовано!',
|
|
935
|
+
uploadLabel: '📂 Завантажити резервну копію',
|
|
936
|
+
localDropdown: '🗂️ Локальні резервні копії ▾',
|
|
937
|
+
ftpDropdown: '🌐 Резервні копії FTP ▾',
|
|
938
|
+
smbDropdown: '🗄️ Резервні копії SMB ▾',
|
|
939
|
+
sftpDropdown: '🔒 Резервні копії SFTP ▾',
|
|
940
|
+
webdavDropdown: '☁️ Резервні копії WebDAV ▾',
|
|
941
|
+
httpLoadBtn: '🌐 Завантажити URL',
|
|
942
|
+
zipBtn: '📦 ZIP',
|
|
943
|
+
statusDefault: 'Завантажте резервну копію або оберіть джерело',
|
|
944
|
+
searchPlaceholder: 'Пошук за іменами, папками та кодом...',
|
|
945
|
+
expandAll: 'Розгорнути все',
|
|
946
|
+
collapseAll: 'Згорнути все',
|
|
947
|
+
typeAll: 'Усі',
|
|
948
|
+
restoreBtn: 'Завантажити в ioBroker',
|
|
949
|
+
downloadBtn: 'Завантажити',
|
|
950
|
+
welcomeText: 'Завантажте резервну копію або оберіть локальний файл,<br>щоб переглянути та відновити скрипти.',
|
|
951
|
+
noSocket: 'Немає сокета. Перевірте, чи запущено script-restore.{i}.',
|
|
952
|
+
timeout: 'Час очікування вичерпано: адаптер не відповідає. Чи запущено script-restore.{i}?',
|
|
953
|
+
},
|
|
954
|
+
'zh-cn': {
|
|
955
|
+
loaderLoading: '正在加载备份...',
|
|
956
|
+
loaderProcessing: '处理中...',
|
|
957
|
+
modalTitle: '加载到 ioBroker',
|
|
958
|
+
modalLabelScript: '脚本:',
|
|
959
|
+
modalLabelPath: '路径:',
|
|
960
|
+
modalLabelType: '类型:',
|
|
961
|
+
modalLabelSuffix: '后缀(附加到脚本名称)',
|
|
962
|
+
modalWarning: '⚠ {path} 下已存在一个脚本。<br>您真的要覆盖它吗?',
|
|
963
|
+
modalDismiss: '选择其他后缀',
|
|
964
|
+
modalOverwrite: '覆盖',
|
|
965
|
+
modalSuccess: '✓ 恢复成功。<br>是否立即启动该脚本?',
|
|
966
|
+
modalClose: '不,谢谢',
|
|
967
|
+
modalStart: '立即启动',
|
|
968
|
+
modalLoad: '加载',
|
|
969
|
+
modalLoading: '⏳ 加载中...',
|
|
970
|
+
modalStarting: '⏳ 启动中...',
|
|
971
|
+
modalStarted: '✓ 已启动',
|
|
972
|
+
modalLoaded: '✓ 已加载!',
|
|
973
|
+
modalUnknownError: '✗ 未知错误',
|
|
974
|
+
modalErrorPrefix: '✗ 错误:',
|
|
975
|
+
copyBtn: '复制代码',
|
|
976
|
+
copyBtnAction: '复制代码',
|
|
977
|
+
copied: '✓ 已复制!',
|
|
978
|
+
uploadLabel: '📂 上传备份',
|
|
979
|
+
localDropdown: '🗂️ 本地备份 ▾',
|
|
980
|
+
ftpDropdown: '🌐 FTP 备份 ▾',
|
|
981
|
+
smbDropdown: '🗄️ SMB 备份 ▾',
|
|
982
|
+
sftpDropdown: '🔒 SFTP 备份 ▾',
|
|
983
|
+
webdavDropdown: '☁️ WebDAV 备份 ▾',
|
|
984
|
+
httpLoadBtn: '🌐 加载 URL',
|
|
985
|
+
zipBtn: '📦 ZIP',
|
|
986
|
+
statusDefault: '加载备份或选择来源',
|
|
987
|
+
searchPlaceholder: '在名称、文件夹和代码中搜索...',
|
|
988
|
+
expandAll: '全部展开',
|
|
989
|
+
collapseAll: '全部折叠',
|
|
990
|
+
typeAll: '全部',
|
|
991
|
+
restoreBtn: '加载到 ioBroker',
|
|
992
|
+
downloadBtn: '下载',
|
|
993
|
+
welcomeText: '上传备份或选择本地文件,<br>以查看和恢复脚本。',
|
|
994
|
+
noSocket: '无套接字。请检查 script-restore.{i} 是否正在运行。',
|
|
995
|
+
timeout: '超时:适配器无响应。script-restore.{i} 是否正在运行?',
|
|
996
|
+
},
|
|
997
|
+
};
|
|
998
|
+
|
|
999
|
+
function detectLang() {
|
|
1000
|
+
// 1. URL parameter
|
|
1001
|
+
const lp = urlParams.get('lang') || urlParams.get('language');
|
|
1002
|
+
if (lp) return normLang(lp);
|
|
1003
|
+
// 2. localStorage
|
|
1004
|
+
try {
|
|
1005
|
+
const ls = localStorage.getItem('App.language') || localStorage.getItem('ioBroker.locale');
|
|
1006
|
+
if (ls) return normLang(ls);
|
|
1007
|
+
} catch(e) {}
|
|
1008
|
+
// 3. Parent frame
|
|
1009
|
+
try {
|
|
1010
|
+
const p = window.parent;
|
|
1011
|
+
if (p && (p.sysLang || p.systemLang)) return normLang(p.sysLang || p.systemLang);
|
|
1012
|
+
} catch(e) {}
|
|
1013
|
+
// 4. Navigator
|
|
1014
|
+
return normLang(navigator.language || 'en');
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
function normLang(l) {
|
|
1018
|
+
if (!l) return 'en';
|
|
1019
|
+
const ll = l.toLowerCase().replace('_', '-');
|
|
1020
|
+
if (ll === 'zh-cn' || ll === 'zh') return 'zh-cn';
|
|
1021
|
+
return ll.slice(0, 2);
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
const LANG = (function() {
|
|
1025
|
+
const detected = detectLang();
|
|
1026
|
+
return TRANSLATIONS[detected] ? detected : 'en';
|
|
1027
|
+
})();
|
|
1028
|
+
|
|
1029
|
+
function t(key) {
|
|
1030
|
+
return (TRANSLATIONS[LANG] && TRANSLATIONS[LANG][key]) || (TRANSLATIONS.en && TRANSLATIONS.en[key]) || key;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
function applyTranslations() {
|
|
1034
|
+
document.querySelectorAll('[data-i18n]').forEach(function(el) {
|
|
1035
|
+
el.textContent = t(el.getAttribute('data-i18n'));
|
|
1036
|
+
});
|
|
1037
|
+
document.querySelectorAll('[data-i18n-html]').forEach(function(el) {
|
|
1038
|
+
el.innerHTML = t(el.getAttribute('data-i18n-html'));
|
|
1039
|
+
});
|
|
1040
|
+
document.querySelectorAll('[data-i18n-placeholder]').forEach(function(el) {
|
|
1041
|
+
el.placeholder = t(el.getAttribute('data-i18n-placeholder'));
|
|
1042
|
+
});
|
|
1043
|
+
document.querySelectorAll('[data-i18n-title]').forEach(function(el) {
|
|
1044
|
+
el.title = t(el.getAttribute('data-i18n-title'));
|
|
1045
|
+
});
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
applyTranslations();
|
|
1049
|
+
|
|
523
1050
|
// === Dark Theme Detection ===
|
|
524
1051
|
function applyTheme(isDark) {
|
|
525
1052
|
document.body.classList.toggle('dark', !!isDark);
|
|
@@ -625,14 +1152,14 @@
|
|
|
625
1152
|
|
|
626
1153
|
function sendTo(command, message, callback) {
|
|
627
1154
|
if (!socket) {
|
|
628
|
-
callback({ error: '
|
|
1155
|
+
callback({ error: t('noSocket').replace('{i}', instance) });
|
|
629
1156
|
return;
|
|
630
1157
|
}
|
|
631
1158
|
let done = false;
|
|
632
1159
|
const timer = setTimeout(() => {
|
|
633
1160
|
if (done) return;
|
|
634
1161
|
done = true;
|
|
635
|
-
callback({ error: '
|
|
1162
|
+
callback({ error: t('timeout').replace('{i}', instance) });
|
|
636
1163
|
}, 30000);
|
|
637
1164
|
const wrapped = (result) => {
|
|
638
1165
|
if (done) return;
|
|
@@ -1038,13 +1565,13 @@
|
|
|
1038
1565
|
document.getElementById('spinnerEl').style.display = 'none';
|
|
1039
1566
|
document.getElementById('progressCircle').style.background = 'conic-gradient(var(--primary) 0%, #e9ecef 0%)';
|
|
1040
1567
|
document.getElementById('progressPercent').textContent = '0%';
|
|
1041
|
-
document.getElementById('loaderText').textContent = text || '
|
|
1568
|
+
document.getElementById('loaderText').textContent = text || t('loaderLoading');
|
|
1042
1569
|
document.getElementById('loader').style.display = 'flex';
|
|
1043
1570
|
}
|
|
1044
1571
|
function showLoaderSpinner(text) {
|
|
1045
1572
|
document.getElementById('progressContainer').style.display = 'none';
|
|
1046
1573
|
document.getElementById('spinnerEl').style.display = 'block';
|
|
1047
|
-
document.getElementById('loaderText').textContent = text || '
|
|
1574
|
+
document.getElementById('loaderText').textContent = text || t('loaderProcessing');
|
|
1048
1575
|
document.getElementById('loader').style.display = 'flex';
|
|
1049
1576
|
}
|
|
1050
1577
|
function updateProgress(pct) {
|
|
@@ -1061,7 +1588,7 @@
|
|
|
1061
1588
|
isAllExpanded = !isAllExpanded;
|
|
1062
1589
|
const btn = document.getElementById('expandToggleBtn');
|
|
1063
1590
|
btn.innerHTML = isAllExpanded ? '📁' : '📂';
|
|
1064
|
-
btn.title = isAllExpanded ? '
|
|
1591
|
+
btn.title = isAllExpanded ? t('collapseAll') : t('expandAll');
|
|
1065
1592
|
document.querySelectorAll('.tree-folder').forEach(el => {
|
|
1066
1593
|
const p = el.dataset.path;
|
|
1067
1594
|
const icon = el.querySelector('.folder-icon');
|
|
@@ -1248,12 +1775,12 @@
|
|
|
1248
1775
|
ta.value = txt; document.body.appendChild(ta); ta.select();
|
|
1249
1776
|
try {
|
|
1250
1777
|
document.execCommand('copy');
|
|
1251
|
-
btn.textContent = '
|
|
1778
|
+
btn.textContent = t('copied');
|
|
1252
1779
|
btn.classList.replace('btn-outline-light', 'btn-outline-success');
|
|
1253
1780
|
} finally {
|
|
1254
1781
|
document.body.removeChild(ta);
|
|
1255
1782
|
setTimeout(() => {
|
|
1256
|
-
btn.textContent = '
|
|
1783
|
+
btn.textContent = t('copyBtnAction');
|
|
1257
1784
|
btn.classList.replace('btn-outline-success', 'btn-outline-light');
|
|
1258
1785
|
}, 1500);
|
|
1259
1786
|
}
|
|
@@ -1325,18 +1852,18 @@
|
|
|
1325
1852
|
const msgEl = document.getElementById('rmMsg');
|
|
1326
1853
|
const confirmBtn = document.getElementById('rmConfirmBtn');
|
|
1327
1854
|
msgEl.style.color = '#aaa';
|
|
1328
|
-
msgEl.textContent = '
|
|
1855
|
+
msgEl.textContent = t('modalLoading');
|
|
1329
1856
|
confirmBtn.disabled = true;
|
|
1330
1857
|
sendTo('restoreScript', { path: s.path, name: s.name, type: s.type, source: s.source, suffix, overwrite: !!overwrite }, function(result) {
|
|
1331
1858
|
if (result && result.exists) {
|
|
1332
|
-
document.
|
|
1859
|
+
document.querySelector('#rmWarning p').innerHTML = t('modalWarning').replace('{path}', '<code>' + escapeHTML(result.id.replace(/^script\.js\./, '')) + '</code>');
|
|
1333
1860
|
document.getElementById('rmWarning').style.display = 'block';
|
|
1334
1861
|
document.getElementById('rmSuffix').disabled = true;
|
|
1335
1862
|
msgEl.textContent = '';
|
|
1336
1863
|
} else if (result && result.error) {
|
|
1337
1864
|
confirmBtn.disabled = false;
|
|
1338
1865
|
msgEl.style.color = '#dc3545';
|
|
1339
|
-
msgEl.textContent = '
|
|
1866
|
+
msgEl.textContent = t('modalErrorPrefix') + result.error;
|
|
1340
1867
|
} else if (result && result.success) {
|
|
1341
1868
|
_restoredScriptId = result.id;
|
|
1342
1869
|
msgEl.textContent = '';
|
|
@@ -1345,7 +1872,7 @@
|
|
|
1345
1872
|
} else {
|
|
1346
1873
|
confirmBtn.disabled = false;
|
|
1347
1874
|
msgEl.style.color = '#dc3545';
|
|
1348
|
-
msgEl.textContent = '
|
|
1875
|
+
msgEl.textContent = t('modalUnknownError');
|
|
1349
1876
|
}
|
|
1350
1877
|
});
|
|
1351
1878
|
}
|
|
@@ -1367,16 +1894,16 @@
|
|
|
1367
1894
|
if (!_restoredScriptId) return;
|
|
1368
1895
|
const startBtn = document.getElementById('rmStartBtn');
|
|
1369
1896
|
startBtn.disabled = true;
|
|
1370
|
-
startBtn.textContent = '
|
|
1897
|
+
startBtn.textContent = t('modalStarting');
|
|
1371
1898
|
sendTo('enableScript', { id: _restoredScriptId }, function(result) {
|
|
1372
1899
|
if (result && result.success) {
|
|
1373
|
-
startBtn.textContent = '
|
|
1900
|
+
startBtn.textContent = t('modalStarted');
|
|
1374
1901
|
setTimeout(() => closeRestoreModal(), 1000);
|
|
1375
1902
|
} else {
|
|
1376
1903
|
startBtn.disabled = false;
|
|
1377
|
-
startBtn.textContent = '
|
|
1904
|
+
startBtn.textContent = t('modalStart');
|
|
1378
1905
|
const p = document.querySelector('#rmSuccess p');
|
|
1379
|
-
p.innerHTML = '
|
|
1906
|
+
p.innerHTML = t('modalErrorPrefix') + escapeHTML((result && result.error) || 'Unbekannt');
|
|
1380
1907
|
p.style.color = '#dc3545';
|
|
1381
1908
|
}
|
|
1382
1909
|
});
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "script-restore",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.2",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.1.2": {
|
|
7
|
+
"en": "add full i18n to tab UI: all strings translated into de/en/fr/es/it/nl/pl/pt/ru/uk/zh-cn",
|
|
8
|
+
"de": "fügen Sie volle i18n zu Tab UI: alle Strings übersetzt in de/en/fr/es/it/nl/pl/pt/ru/uk/zh-cn",
|
|
9
|
+
"ru": "добавить полный i18n в вкладку UI: все строки переведены в de/en/fr/es/it/nl/pl/pt/ru/uk/zh-cn",
|
|
10
|
+
"pt": "adicionar i18n completo à guia UI: todas as strings traduzidas para de/en/fr/es/it/nl/pl/pt/ru/uk/zh-cn",
|
|
11
|
+
"nl": "volledige i18n toevoegen aan tab UI: alle tekenreeksen vertaald in de/en/fr/es/it/nl/pl/pt/ru/uk/zh-cn",
|
|
12
|
+
"fr": "ajouter i18n complet à l'onglet UI: toutes les chaînes traduites en de/en/fr/es/it/nl/pl/pt/ru/uk/zh-cn",
|
|
13
|
+
"it": "aggiungere i18n completo alla scheda UI: tutte le stringhe tradotte in de/en/fr/es/it/nl/pl/pt/ru/uk/zh-cn",
|
|
14
|
+
"es": "añadir i18n completo a la pestaña UI: todas las cadenas traducidas a de/en/fr/es/it/nl/pl/pt/ru/uk/zh-cn",
|
|
15
|
+
"pl": "dodaj pełny i18n do zakładki Interfejs: wszystkie struny przetłumaczone na de / en / fr / es / it / nl / pl / pt / ru / uk / zh- cn",
|
|
16
|
+
"uk": "додати повну i18n в закладку UI: всі рядки, перекладені в de/en/fr/es/nl/pl/pt/ru/uk/zh-cn",
|
|
17
|
+
"zh-cn": "将完整 i18n 添加到 Tab UI 中: 所有字符串翻译为 de/en/fr/es/it/nl/pl/pt/ru/uk/zh-cn"
|
|
18
|
+
},
|
|
6
19
|
"0.1.1": {
|
|
7
20
|
"en": "allow overwriting existing scripts during restore (confirmation dialog with path display)\nallow empty suffix to restore script under its original name\nprompt to start script immediately after successful restore",
|
|
8
21
|
"de": "das überschreiben bestehender skripte während der wiederherstellung (bestätigungsdialog mit pfadanzeige)\nleere suffix erlauben, skript unter seinem ursprünglichen namen wiederherzustellen\nscript sofort nach erfolgreicher wiederherstellung starten",
|
|
@@ -80,19 +93,6 @@
|
|
|
80
93
|
"pl": "jsonConfig: atrybuty rozmiaru responsywnego, wsparcie i18n, usunięcie przestarzałych plików admin",
|
|
81
94
|
"uk": "jsonConfig: атрибути розміру, підтримка i18n, видалення застарілих файлів admin",
|
|
82
95
|
"zh-cn": "jsonConfig:添加响应式尺寸属性、i18n 支持,删除过时的 admin 文件"
|
|
83
|
-
},
|
|
84
|
-
"0.0.8": {
|
|
85
|
-
"en": "Migrate settings UI to jsonConfig (admin 5+); fix node:fs import; update Dependabot schedule; migrate automerge workflow",
|
|
86
|
-
"de": "Einstellungen auf jsonConfig (Admin 5+) migriert; node:fs-Import korrigiert; Dependabot-Schedule aktualisiert; Automerge-Workflow migriert",
|
|
87
|
-
"ru": "Миграция UI настроек на jsonConfig (admin 5+); исправлен импорт node:fs; обновлён Dependabot; миграция automerge workflow",
|
|
88
|
-
"pt": "Migrar UI de configurações para jsonConfig (admin 5+); corrigir importação node:fs; atualizar Dependabot; migrar workflow automerge",
|
|
89
|
-
"nl": "Instellingen UI migreren naar jsonConfig (admin 5+); node:fs import gecorrigeerd; Dependabot schedule bijgewerkt; automerge workflow gemigreerd",
|
|
90
|
-
"fr": "Migration de l'UI des paramètres vers jsonConfig (admin 5+); correction de l'import node:fs; mise à jour Dependabot; migration du workflow automerge",
|
|
91
|
-
"it": "Migrazione UI impostazioni a jsonConfig (admin 5+); corretto import node:fs; aggiornato Dependabot; migrato workflow automerge",
|
|
92
|
-
"es": "Migrar UI de configuración a jsonConfig (admin 5+); corregir importación node:fs; actualizar Dependabot; migrar workflow automerge",
|
|
93
|
-
"pl": "Migracja UI ustawień do jsonConfig (admin 5+); poprawka importu node:fs; aktualizacja Dependabot; migracja workflow automerge",
|
|
94
|
-
"uk": "Міграція UI налаштувань на jsonConfig (admin 5+); виправлено імпорт node:fs; оновлено Dependabot; міграція automerge workflow",
|
|
95
|
-
"zh-cn": "将设置 UI 迁移至 jsonConfig(admin 5+);修复 node:fs 导入;更新 Dependabot 计划;迁移 automerge 工作流"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|