feat: Full UI internationalization, pool hashrate stats, and layout caching

- Replace all hardcoded English strings with TR() translation keys across
  every tab, dialog, and component (~20 UI files)
- Expand all 8 language files (de, es, fr, ja, ko, pt, ru, zh) with
  complete translations (~37k lines added)
- Improve i18n loader with exe-relative path fallback and English base
  fallback for missing keys
- Add pool-side hashrate polling via pool stats API in xmrig_manager
- Introduce Layout::beginFrame() per-frame caching and refresh balance
  layout config only on schema generation change
- Offload daemon output parsing to worker thread
- Add CJK subset fallback font for Chinese/Japanese/Korean glyphs
This commit is contained in:
2026-03-11 00:40:50 -05:00
parent f416ff3d09
commit 2c5a658ea5
71 changed files with 43567 additions and 5267 deletions
+22 -3
View File
@@ -481,17 +481,36 @@ elseif(EXISTS ${CMAKE_SOURCE_DIR}/../SilentDragonX/res/Ubuntu-R.ttf)
)
endif()
# Copy language files
# Copy language files at BUILD time (not just cmake configure time)
# so edits to res/lang/*.json are picked up by 'make' without re-running cmake.
file(GLOB LANG_FILES ${CMAKE_SOURCE_DIR}/res/lang/*.json)
if(LANG_FILES)
foreach(LANG_FILE ${LANG_FILES})
get_filename_component(LANG_FILENAME ${LANG_FILE} NAME)
configure_file(
add_custom_command(
OUTPUT ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/res/lang/${LANG_FILENAME}
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${LANG_FILE}
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/res/lang/${LANG_FILENAME}
COPYONLY
DEPENDS ${LANG_FILE}
COMMENT "Copying ${LANG_FILENAME}"
)
list(APPEND LANG_OUTPUTS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/res/lang/${LANG_FILENAME})
# Also regenerate the embedded header so the binary always has fresh translations
get_filename_component(LANG_CODE ${LANG_FILENAME} NAME_WE)
set(LANG_HEADER ${CMAKE_SOURCE_DIR}/src/embedded/lang_${LANG_CODE}.h)
add_custom_command(
OUTPUT ${LANG_HEADER}
COMMAND xxd -i "res/lang/${LANG_FILENAME}" > "src/embedded/lang_${LANG_CODE}.h"
DEPENDS ${LANG_FILE}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "Embedding lang_${LANG_CODE}.h"
)
list(APPEND LANG_OUTPUTS ${LANG_HEADER})
endforeach()
add_custom_target(copy_langs ALL DEPENDS ${LANG_OUTPUTS})
add_dependencies(ObsidianDragon copy_langs)
message(STATUS " Language files: ${LANG_FILES}")
endif()
-3
View File
@@ -8,6 +8,3 @@
# 203.0.113.42
#
# Rebuild the wallet after editing this file.
185.159.129.12
185.228.233.222
Binary file not shown.
+777 -121
View File
@@ -1,139 +1,795 @@
{
"balance": "Kontostand",
"send": "Senden",
"receive": "Empfangen",
"transactions": "Transaktionen",
"mining": "Mining",
"peers": "Knoten",
"market": "Markt",
"settings": "Einstellungen",
"summary": "Übersicht",
"shielded": "Geschützt",
"transparent": "Transparent",
"total": "Gesamt",
"unconfirmed": "Unbestätigt",
"your_addresses": "Ihre Adressen",
"z_addresses": "Z-Adressen",
"t_addresses": "T-Adressen",
"no_addresses": "Keine Adressen gefunden. Erstellen Sie eine mit den Schaltflächen oben.",
"new_z_address": "Neue Z-Adresse",
"new_t_address": "Neue T-Adresse",
"type": "Typ",
"24h_change": "24h Änderung",
"24h_volume": "24h Volumen",
"about": "Über",
"about_block_explorer": "Block-Explorer",
"about_block_height": "Blockhöhe:",
"about_build_date": "Erstellungsdatum:",
"about_build_type": "Build-Typ:",
"about_chain": "Chain:",
"about_connections": "Verbindungen:",
"about_credits": "Danksagungen",
"about_daemon": "Daemon:",
"about_debug": "Debug",
"about_dragonx": "Über ObsidianDragon",
"about_edition": "ImGui Edition",
"about_github": "GitHub",
"about_imgui": "ImGui:",
"about_license": "Lizenz",
"about_license_text": "Diese Software wird unter der GNU General Public License v3 (GPLv3) veröffentlicht. Sie dürfen diese Software gemäß den Lizenzbedingungen frei verwenden, modifizieren und verbreiten.",
"about_peers_count": "%zu Peers",
"about_release": "Release",
"about_title": "Über ObsidianDragon",
"about_version": "Version:",
"about_website": "Webseite",
"acrylic": "Acryl",
"add": "Hinzufügen",
"address": "Adresse",
"copy_address": "Vollständige Adresse kopieren",
"send_from_this_address": "Von dieser Adresse senden",
"export_private_key": "Privaten Schlüssel exportieren",
"export_viewing_key": "Ansichtsschlüssel exportieren",
"show_qr_code": "QR-Code anzeigen",
"not_connected": "Nicht mit Daemon verbunden...",
"pay_from": "Zahlen von",
"send_to": "Senden an",
"address_book_add": "Adresse hinzufügen",
"address_book_add_new": "Neue hinzufügen",
"address_book_added": "Adresse zum Buch hinzugefügt",
"address_book_count": "%zu Adressen gespeichert",
"address_book_deleted": "Eintrag gelöscht",
"address_book_edit": "Adresse bearbeiten",
"address_book_empty": "Keine gespeicherten Adressen. Klicken Sie auf 'Neue hinzufügen', um eine hinzuzufügen.",
"address_book_exists": "Adresse existiert bereits im Buch",
"address_book_title": "Adressbuch",
"address_book_update_failed": "Aktualisierung fehlgeschlagen - Adresse könnte doppelt sein",
"address_book_updated": "Adresse aktualisiert",
"address_copied": "Adresse in Zwischenablage kopiert",
"address_details": "Adressdetails",
"address_label": "Adresse:",
"address_upper": "ADRESSE",
"address_url": "Adress-URL",
"addresses_appear_here": "Ihre Empfangsadressen erscheinen hier, sobald Sie verbunden sind.",
"advanced": "ERWEITERT",
"all_filter": "Alle",
"allow_custom_fees": "Benutzerdefinierte Gebühren erlauben",
"amount": "Betrag",
"memo": "Memo (optional, verschlüsselt)",
"miner_fee": "Miner-Gebühr",
"fee": "Gebühr",
"send_transaction": "Transaktion senden",
"clear": "Löschen",
"select_address": "Adresse auswählen...",
"paste": "Einfügen",
"max": "Max",
"amount_details": "BETRAGSDETAILS",
"amount_exceeds_balance": "Betrag übersteigt Guthaben",
"amount_label": "Betrag:",
"appearance": "ERSCHEINUNGSBILD",
"auto_shield": "Mining automatisch abschirmen",
"available": "Verfügbar",
"invalid_address": "Ungültiges Adressformat",
"memo_z_only": "Hinweis: Memos sind nur beim Senden an geschützte (z) Adressen verfügbar",
"backup_backing_up": "Sicherung läuft...",
"backup_create": "Sicherung erstellen",
"backup_created": "Wallet-Sicherung erstellt",
"backup_data": "SICHERUNG & DATEN",
"backup_description": "Erstellen Sie eine Sicherung Ihrer wallet.dat-Datei. Diese Datei enthält alle Ihre privaten Schlüssel und den Transaktionsverlauf. Bewahren Sie die Sicherung an einem sicheren Ort auf.",
"backup_destination": "Sicherungsziel:",
"backup_source": "Quelle: %s",
"backup_tip_external": "Speichern Sie Sicherungen auf externen Laufwerken oder Cloud-Speicher",
"backup_tip_multiple": "Erstellen Sie mehrere Sicherungen an verschiedenen Orten",
"backup_tip_test": "Testen Sie regelmäßig die Wiederherstellung aus der Sicherung",
"backup_tips": "Tipps:",
"backup_title": "Wallet sichern",
"backup_wallet": "Wallet sichern...",
"backup_wallet_not_found": "Warnung: wallet.dat nicht am erwarteten Speicherort gefunden",
"balance": "Guthaben",
"balance_layout": "Guthaben-Layout",
"ban": "Sperren",
"banned_peers": "Gesperrte Peers",
"block": "Block",
"block_bits": "Bits:",
"block_click_copy": "Klicken zum Kopieren",
"block_click_next": "Klicken für nächsten Block",
"block_click_prev": "Klicken für vorherigen Block",
"block_explorer": "Block-Explorer",
"block_get_info": "Block-Info abrufen",
"block_hash": "Block-Hash:",
"block_hash_copied": "Block-Hash kopiert",
"block_height": "Blockhöhe:",
"block_info_title": "Block-Informationen",
"block_merkle_root": "Merkle-Root:",
"block_nav_next": "Weiter >>",
"block_nav_prev": "<< Zurück",
"block_next": "Nächster Block:",
"block_previous": "Vorheriger Block:",
"block_size": "Größe:",
"block_timestamp": "Zeitstempel:",
"block_transactions": "Transaktionen:",
"blockchain_syncing": "Blockchain synchronisiert (%.1f%%)... Guthaben könnten ungenau sein.",
"cancel": "Abbrechen",
"characters": "Zeichen",
"from": "Von",
"to": "An",
"sending": "Transaktion wird gesendet",
"clear": "Leeren",
"clear_all_bans": "Alle Sperren aufheben",
"clear_anyway": "Trotzdem löschen",
"clear_form_confirm": "Alle Formularfelder leeren?",
"clear_request": "Anfrage leeren",
"click_copy_address": "Klicken zum Kopieren der Adresse",
"click_copy_uri": "Klicken zum Kopieren der URI",
"click_to_copy": "Klicken zum Kopieren",
"close": "Schließen",
"conf_count": "%d Best.",
"confirm_and_send": "Bestätigen & Senden",
"confirm_clear_ztx_title": "Z-Tx-Verlauf löschen bestätigen",
"confirm_clear_ztx_warning1": "Das Löschen des Z-Transaktionsverlaufs kann dazu führen, dass Ihr geschirmtes Guthaben als 0 angezeigt wird, bis ein Wallet-Rescan durchgeführt wird.",
"confirm_clear_ztx_warning2": "Wenn dies geschieht, müssen Sie Ihre Z-Adresse-Privatschlüssel mit aktiviertem Rescan neu importieren, um Ihr Guthaben wiederherzustellen.",
"confirm_send": "Senden bestätigen",
"confirm_transaction": "Transaktion bestätigen",
"confirm_and_send": "Bestätigen & Senden",
"cancel": "Abbrechen",
"receiving_addresses": "Ihre Empfangsadressen",
"new_z_shielded": "Neue z-Adresse (geschützt)",
"new_t_transparent": "Neue t-Adresse (transparent)",
"address_details": "Adressdetails",
"view_on_explorer": "Im Explorer ansehen",
"qr_code": "QR-Code",
"request_payment": "Zahlung anfordern",
"date": "Datum",
"status": "Status",
"confirmations": "Bestätigungen",
"confirmations_display": "%d Bestätigungen | %s",
"confirmed": "Bestätigt",
"pending": "Ausstehend",
"sent": "gesendet",
"received": "empfangen",
"mined": "geschürft",
"mining_control": "Mining-Steuerung",
"start_mining": "Mining starten",
"stop_mining": "Mining stoppen",
"mining_threads": "Mining-Threads",
"mining_statistics": "Mining-Statistiken",
"local_hashrate": "Lokale Hashrate",
"network_hashrate": "Netzwerk-Hashrate",
"connected": "Verbunden",
"connected_peers": "Verbundene Peers",
"connecting": "Verbinde...",
"console": "Konsole",
"console_auto_scroll": "Automatisch scrollen",
"console_available_commands": "Verfügbare Befehle:",
"console_capturing_output": "Erfasse Daemon-Ausgabe...",
"console_clear": "Leeren",
"console_clear_console": "Konsole leeren",
"console_cleared": "Konsole geleert",
"console_click_commands": "Befehle oben klicken zum Einfügen",
"console_click_insert": "Klicken zum Einfügen",
"console_click_insert_params": "Klicken zum Einfügen mit Parametern",
"console_close": "Schließen",
"console_commands": "Befehle",
"console_common_rpc": "Häufige RPC-Befehle:",
"console_completions": "Vervollständigungen:",
"console_connected": "Verbunden mit Daemon",
"console_copy_all": "Alles kopieren",
"console_copy_selected": "Kopieren",
"console_daemon": "Daemon",
"console_daemon_error": "Daemon-Fehler!",
"console_daemon_started": "Daemon gestartet",
"console_daemon_stopped": "Daemon gestoppt",
"console_disconnected": "Vom Daemon getrennt",
"console_errors": "Fehler",
"console_filter_hint": "Ausgabe filtern...",
"console_help_clear": " clear - Konsole leeren",
"console_help_getbalance": " getbalance - Transparentes Guthaben anzeigen",
"console_help_getblockcount": " getblockcount - Aktuelle Blockhöhe anzeigen",
"console_help_getinfo": " getinfo - Knoteninformationen anzeigen",
"console_help_getmininginfo": " getmininginfo - Mining-Status anzeigen",
"console_help_getpeerinfo": " getpeerinfo - Verbundene Peers anzeigen",
"console_help_gettotalbalance": " gettotalbalance - Gesamtguthaben anzeigen",
"console_help_help": " help - Diese Hilfe anzeigen",
"console_help_setgenerate": " setgenerate - Mining steuern",
"console_help_stop": " stop - Daemon stoppen",
"console_line_count": "%zu Zeilen",
"console_new_lines": "%d neue Zeilen",
"console_no_daemon": "Kein Daemon",
"console_not_connected": "Fehler: Nicht mit Daemon verbunden",
"console_rpc_reference": "RPC-Befehlsreferenz",
"console_scanline": "Konsolen-Scanline",
"console_search_commands": "Befehle suchen...",
"console_select_all": "Alles auswählen",
"console_show_daemon_output": "Daemon-Ausgabe anzeigen",
"console_show_errors_only": "Nur Fehler anzeigen",
"console_show_rpc_ref": "RPC-Befehlsreferenz anzeigen",
"console_showing_lines": "Zeige %zu von %zu Zeilen",
"console_starting_node": "Knoten wird gestartet...",
"console_status_error": "Fehler",
"console_status_running": "Läuft",
"console_status_starting": "Startet",
"console_status_stopped": "Gestoppt",
"console_status_stopping": "Stoppt",
"console_status_unknown": "Unbekannt",
"console_tab_completion": "Tab zur Vervollständigung",
"console_type_help": "Geben Sie 'help' ein für verfügbare Befehle",
"console_welcome": "Willkommen bei ObsidianDragon Konsole",
"console_zoom_in": "Vergrößern",
"console_zoom_out": "Verkleinern",
"copy": "Kopieren",
"copy_address": "Vollständige Adresse kopieren",
"copy_error": "Fehler kopieren",
"copy_to_clipboard": "In Zwischenablage kopieren",
"copy_txid": "TxID kopieren",
"copy_uri": "URI kopieren",
"current_price": "Aktueller Preis",
"custom_fees": "Benutzerdefinierte Gebühren",
"dark": "Dunkel",
"date": "Datum",
"date_label": "Datum:",
"debug_logging": "FEHLERPROTOKOLLIERUNG",
"delete": "Löschen",
"difficulty": "Schwierigkeit",
"disconnected": "Getrennt",
"dismiss": "Verwerfen",
"display": "Anzeige",
"dragonx_green": "DragonX (Grün)",
"edit": "Bearbeiten",
"error": "Fehler",
"error_format": "Fehler: %s",
"est_time_to_block": "Gesch. Zeit bis Block",
"exit": "Beenden",
"explorer": "EXPLORER",
"export": "Exportieren",
"export_csv": "CSV exportieren",
"export_keys_btn": "Schlüssel exportieren",
"export_keys_danger": "ACHTUNG: Dies exportiert ALLE privaten Schlüssel aus Ihrer Wallet! Jeder mit Zugriff auf diese Datei kann Ihre Gelder stehlen. Sicher aufbewahren und nach Gebrauch löschen.",
"export_keys_include_t": "T-Adressen einschließen (transparent)",
"export_keys_include_z": "Z-Adressen einschließen (abgeschirmt)",
"export_keys_options": "Export-Optionen:",
"export_keys_progress": "Exportiere %d/%d...",
"export_keys_success": "Schlüssel erfolgreich exportiert",
"export_keys_title": "Alle privaten Schlüssel exportieren",
"export_private_key": "Privaten Schlüssel exportieren",
"export_tx_count": "%zu Transaktionen als CSV exportieren.",
"export_tx_file_fail": "CSV-Datei konnte nicht erstellt werden",
"export_tx_none": "Keine Transaktionen zum Exportieren",
"export_tx_success": "Transaktionen erfolgreich exportiert",
"export_tx_title": "Transaktionen als CSV exportieren",
"export_viewing_key": "Betrachtungsschlüssel exportieren",
"failed_create_shielded": "Abgeschirmte Adresse konnte nicht erstellt werden",
"failed_create_transparent": "Transparente Adresse konnte nicht erstellt werden",
"favorite_address": "Als Favorit markieren",
"fee": "Gebühr",
"fee_high": "Hoch",
"fee_label": "Gebühr:",
"fee_low": "Niedrig",
"fee_normal": "Normal",
"fetch_prices": "Preise abrufen",
"file": "Datei",
"file_save_location": "Datei wird gespeichert in: ~/.config/ObsidianDragon/",
"font_scale": "Schriftgröße",
"from": "Von",
"from_upper": "VON",
"full_details": "Alle Details",
"general": "Allgemein",
"go_to_receive": "Zum Empfangen",
"height": "Höhe",
"help": "Hilfe",
"hide": "Ausblenden",
"hide_address": "Adresse ausblenden",
"hide_zero_balances": "Nullsalden ausblenden",
"history": "Verlauf",
"immature_type": "Unreif",
"import": "Importieren",
"import_key_btn": "Schlüssel importieren",
"import_key_formats": "Unterstützte Schlüsselformate:",
"import_key_full_rescan": "(0 = vollständiger Rescan)",
"import_key_label": "Privater Schlüssel:",
"import_key_no_valid": "Keine gültigen Schlüssel in der Eingabe gefunden",
"import_key_progress": "Importiere %d/%d...",
"import_key_rescan": "Blockchain nach Import neu scannen",
"import_key_start_height": "Starthöhe:",
"import_key_success": "Schlüssel erfolgreich importiert",
"import_key_t_format": "T-Adresse WIF private Schlüssel",
"import_key_title": "Privaten Schlüssel importieren",
"import_key_tooltip": "Geben Sie einen oder mehrere private Schlüssel ein, einen pro Zeile.\nUnterstützt sowohl z-Adresse als auch t-Adresse Schlüssel.\nZeilen die mit # beginnen werden als Kommentare behandelt.",
"import_key_warning": "Warnung: Teilen Sie niemals Ihre privaten Schlüssel! Das Importieren von Schlüsseln aus nicht vertrauenswürdigen Quellen kann Ihr Wallet gefährden.",
"import_key_z_format": "Z-Adresse Ausgabeschlüssel (secret-extended-key-...)",
"import_private_key": "Privaten Schlüssel importieren...",
"invalid_address": "Ungültiges Adressformat",
"ip_address": "IP-Adresse",
"keep": "Behalten",
"keep_daemon": "Daemon weiterlaufen lassen",
"key_export_click_retrieve": "Klicken Sie, um den Schlüssel aus Ihrer Wallet abzurufen",
"key_export_fetching": "Schlüssel wird aus Wallet abgerufen...",
"key_export_private_key": "Privater Schlüssel:",
"key_export_private_warning": "Halten Sie diesen Schlüssel GEHEIM! Jeder mit diesem Schlüssel kann Ihre Gelder ausgeben. Teilen Sie ihn niemals online oder mit nicht vertrauenswürdigen Parteien.",
"key_export_reveal": "Schlüssel anzeigen",
"key_export_viewing_key": "Betrachtungsschlüssel:",
"key_export_viewing_keys_zonly": "Anzeigeschlüssel sind nur für geschirmte (z) Adressen verfügbar",
"key_export_viewing_warning": "Dieser Betrachtungsschlüssel ermöglicht es anderen, Ihre eingehenden Transaktionen und Ihr Guthaben zu sehen, aber NICHT Ihre Gelder auszugeben. Teilen Sie ihn nur mit vertrauenswürdigen Parteien.",
"label": "Bezeichnung:",
"language": "Sprache",
"light": "Hell",
"loading": "Laden...",
"loading_addresses": "Adressen werden geladen...",
"local_hashrate": "Lokale Hashrate",
"low_spec_mode": "Energiesparmodus",
"market": "Markt",
"market_12h": "12h",
"market_18h": "18h",
"market_24h": "24h",
"market_24h_volume": "24H VOLUMEN",
"market_6h": "6h",
"market_attribution": "Preisdaten von NonKYC",
"market_btc_price": "BTC PREIS",
"market_cap": "Marktkapitalisierung",
"market_no_history": "Kein Preisverlauf verfügbar",
"market_no_price": "Keine Preisdaten",
"market_now": "Jetzt",
"market_pct_shielded": "%.0f%% Abgeschirmt",
"market_portfolio": "PORTFOLIO",
"market_price_unavailable": "Preisdaten nicht verfügbar",
"market_refresh_price": "Preisdaten aktualisieren",
"market_trade_on": "Handeln auf %s",
"mature": "Reif",
"max": "Max",
"memo": "Memo (optional, verschlüsselt)",
"memo_label": "Memo:",
"memo_optional": "MEMO (OPTIONAL)",
"memo_upper": "MEMO",
"memo_z_only": "Hinweis: Memos sind nur beim Senden an abgeschirmte (z) Adressen verfügbar",
"merge_description": "Mehrere UTXOs zu einer einzelnen abgeschirmten Adresse zusammenführen. Dies kann die Wallet-Größe reduzieren und die Privatsphäre verbessern.",
"merge_funds": "Gelder zusammenführen",
"merge_started": "Zusammenführung gestartet",
"merge_title": "An Adresse zusammenführen",
"mine_when_idle": "Im Leerlauf minen",
"mined": "gemined",
"mined_filter": "Gemined",
"mined_type": "Gemined",
"mined_upper": "GEMINED",
"miner_fee": "Miner-Gebühr",
"mining": "Mining",
"mining_active": "Aktiv",
"mining_address_copied": "Mining-Adresse kopiert",
"mining_all_time": "Gesamt",
"mining_already_saved": "Pool-URL bereits gespeichert",
"mining_block_copied": "Block-Hash kopiert",
"mining_chart_1m_ago": "vor 1m",
"mining_chart_5m_ago": "vor 5m",
"mining_chart_now": "Jetzt",
"mining_chart_start": "Start",
"mining_click": "Klicken",
"mining_click_copy_address": "Klicken zum Kopieren der Adresse",
"mining_click_copy_block": "Klicken zum Kopieren des Block-Hash",
"mining_click_copy_difficulty": "Klicken zum Kopieren der Schwierigkeit",
"mining_connected": "Verbunden",
"mining_connecting": "Verbinde...",
"mining_control": "Mining-Steuerung",
"mining_difficulty_copied": "Schwierigkeit kopiert",
"mining_est_block": "Gesch. Block",
"mining_est_daily": "Gesch. täglich",
"mining_filter_all": "Alle",
"mining_filter_tip_all": "Alle Einnahmen anzeigen",
"mining_filter_tip_pool": "Nur Pool-Einnahmen anzeigen",
"mining_filter_tip_solo": "Nur Solo-Einnahmen anzeigen",
"mining_idle_off_tooltip": "Leerlauf-Mining aktivieren",
"mining_idle_on_tooltip": "Leerlauf-Mining deaktivieren",
"mining_local_hashrate": "Lokale Hashrate",
"mining_mine": "Minen",
"mining_mining_addr": "Mining-Adr.",
"mining_network": "Netzwerk",
"mining_no_blocks_yet": "Noch keine Blöcke gefunden",
"mining_no_payouts_yet": "Noch keine Pool-Auszahlungen",
"mining_no_saved_addresses": "Keine gespeicherten Adressen",
"mining_no_saved_pools": "Keine gespeicherten Pools",
"mining_off": "Mining ist AUS",
"mining_on": "Mining ist AN",
"connected_peers": "Verbundene Knoten",
"banned_peers": "Gesperrte Knoten",
"ip_address": "IP-Adresse",
"version": "Version",
"height": "Höhe",
"ping": "Ping",
"ban": "Sperren",
"unban": "Entsperren",
"clear_all_bans": "Alle Sperren aufheben",
"price_chart": "Preisdiagramm",
"current_price": "Aktueller Preis",
"24h_change": "24h-Änderung",
"24h_volume": "24h-Volumen",
"market_cap": "Marktkapitalisierung",
"general": "Allgemein",
"display": "Anzeige",
"mining_open_in_explorer": "Im Explorer öffnen",
"mining_payout_address": "Auszahlungsadresse",
"mining_payout_tooltip": "Adresse für Mining-Belohnungen",
"mining_pool": "Pool",
"mining_pool_hashrate": "Pool-Hashrate",
"mining_pool_url": "Pool-URL",
"mining_recent_blocks": "LETZTE BLÖCKE",
"mining_recent_payouts": "LETZTE POOL-AUSZAHLUNGEN",
"mining_remove": "Entfernen",
"mining_reset_defaults": "Standardwerte zurücksetzen",
"mining_save_payout_address": "Auszahlungsadresse speichern",
"mining_save_pool_url": "Pool-URL speichern",
"mining_saved_addresses": "Gespeicherte Adressen:",
"mining_saved_pools": "Gespeicherte Pools:",
"mining_shares": "Shares",
"mining_show_chart": "Diagramm",
"mining_show_log": "Protokoll",
"mining_solo": "Solo",
"mining_starting": "Startet...",
"mining_starting_tooltip": "Miner startet...",
"mining_statistics": "Mining-Statistiken",
"mining_stop": "Stopp",
"mining_stop_solo_for_pool": "Solo-Mining stoppen bevor Pool-Mining gestartet wird",
"mining_stop_solo_for_pool_settings": "Solo-Mining stoppen um Pool-Einstellungen zu ändern",
"mining_stopping": "Stoppt...",
"mining_stopping_tooltip": "Miner stoppt...",
"mining_syncing_tooltip": "Blockchain synchronisiert...",
"mining_threads": "Mining-Threads",
"mining_to_save": "zum Speichern",
"mining_today": "Heute",
"mining_uptime": "Laufzeit",
"mining_yesterday": "Gestern",
"network": "Netzwerk",
"theme": "Design",
"language": "Sprache",
"dragonx_green": "DragonX (Grün)",
"dark": "Dunkel",
"light": "Hell",
"allow_custom_fees": "Benutzerdefinierte Gebühren erlauben",
"use_embedded_daemon": "Integrierten dragonxd verwenden",
"save": "Speichern",
"close": "Schließen",
"file": "Datei",
"edit": "Bearbeiten",
"view": "Ansicht",
"help": "Hilfe",
"import_private_key": "Privaten Schlüssel importieren...",
"backup_wallet": "Wallet sichern...",
"exit": "Beenden",
"about_dragonx": "Über ObsidianDragon",
"refresh_now": "Jetzt aktualisieren",
"about": "Über",
"import": "Importieren",
"export": "Exportieren",
"copy_to_clipboard": "In Zwischenablage kopieren",
"connected": "Verbunden",
"disconnected": "Getrennt",
"connecting": "Verbinde...",
"syncing": "Synchronisiere...",
"block": "Block",
"network_fee": "NETZWERKGEBÜHR",
"network_hashrate": "Netzwerk-Hashrate",
"new": "+ Neu",
"new_shielded_created": "Neue abgeschirmte Adresse erstellt",
"new_t_address": "Neue T-Adresse",
"new_t_transparent": "Neue t-Adresse (Transparent)",
"new_transparent_created": "Neue transparente Adresse erstellt",
"new_z_address": "Neue Z-Adresse",
"new_z_shielded": "Neue z-Adresse (Abgeschirmt)",
"no_addresses": "Keine Adressen gefunden. Erstellen Sie eine mit den Schaltflächen oben.",
"no_addresses_available": "Keine Adressen verfügbar",
"error": "Fehler",
"no_addresses_match": "Keine Adressen passen zum Filter",
"no_addresses_with_balance": "Keine Adressen mit Guthaben",
"no_matching": "Keine passenden Transaktionen",
"no_recent_receives": "Keine kürzlichen Empfänge",
"no_recent_sends": "Keine kürzlichen Sendungen",
"no_transactions": "Keine Transaktionen gefunden",
"node": "KNOTEN",
"node_security": "KNOTEN & SICHERHEIT",
"noise": "Rauschen",
"not_connected": "Nicht mit Daemon verbunden...",
"not_connected_to_daemon": "Nicht mit Daemon verbunden",
"notes": "Notizen",
"notes_optional": "Notizen (optional):",
"output_filename": "Ausgabedateiname:",
"overview": "Übersicht",
"paste": "Einfügen",
"paste_from_clipboard": "Aus Zwischenablage einfügen",
"pay_from": "Zahlen von",
"payment_request": "ZAHLUNGSANFRAGE",
"payment_request_copied": "Zahlungsanfrage kopiert",
"payment_uri_copied": "Zahlungs-URI kopiert",
"peers": "Peers",
"peers_avg_ping": "Durchschn. Ping",
"peers_ban_24h": "Peer 24h sperren",
"peers_ban_score": "Sperr-Score: %d",
"peers_banned": "Gesperrt",
"peers_banned_count": "Gesperrt: %d",
"peers_best_block": "Bester Block",
"peers_blockchain": "BLOCKCHAIN",
"peers_blocks": "Blöcke",
"peers_blocks_left": "%d Blöcke übrig",
"peers_clear_all_bans": "Alle Sperren aufheben",
"peers_click_copy": "Klicken zum Kopieren",
"peers_connected": "Verbunden",
"peers_connected_count": "Verbunden: %d",
"peers_copy_ip": "IP kopieren",
"peers_dir_in": "Ein",
"peers_dir_out": "Aus",
"peers_hash_copied": "Hash kopiert",
"peers_hashrate": "Hashrate",
"peers_in_out": "Ein/Aus",
"peers_longest": "Längste",
"peers_longest_chain": "Längste Chain",
"peers_memory": "Speicher",
"peers_no_banned": "Keine gesperrten Peers",
"peers_no_connected": "Keine verbundenen Peers",
"peers_no_tls": "Kein TLS",
"peers_notarized": "Notarisiert",
"peers_p2p_port": "P2P-Port",
"peers_peer_label": "Peer: %s",
"peers_protocol": "Protokoll",
"peers_received": "Empfangen",
"peers_refresh": "Aktualisieren",
"peers_refresh_tooltip": "Peer-Liste aktualisieren",
"peers_refreshing": "Aktualisiere...",
"peers_sent": "Gesendet",
"peers_tt_id": "ID: %d",
"peers_tt_received": "Empfangen: %s",
"peers_tt_sent": "Gesendet: %s",
"peers_tt_services": "Dienste: %s",
"peers_tt_start_height": "Starthöhe: %d",
"peers_tt_synced": "Synchronisiert H/B: %d/%d",
"peers_tt_tls_cipher": "TLS: %s",
"peers_unban": "Entsperren",
"peers_upper": "PEERS",
"peers_version": "Version",
"pending": "Ausstehend",
"ping": "Ping",
"price_chart": "Preisdiagramm",
"qr_code": "QR-Code",
"qr_failed": "QR-Code konnte nicht generiert werden",
"qr_title": "QR-Code",
"qr_unavailable": "QR nicht verfügbar",
"ram_daemon_gb": "Daemon: %.1f GB (%s)",
"ram_daemon_mb": "Daemon: %.0f MB (%s)",
"ram_system_gb": "System: %.1f / %.0f GB",
"ram_wallet_gb": "Wallet: %.1f GB",
"ram_wallet_mb": "Wallet: %.0f MB",
"receive": "Empfangen",
"received": "empfangen",
"received_filter": "Empfangen",
"received_label": "Empfangen",
"received_upper": "EMPFANGEN",
"receiving_addresses": "Ihre Empfangsadressen",
"recent_received": "KÜRZLICH EMPFANGEN",
"recent_sends": "KÜRZLICH GESENDET",
"recipient": "EMPFÄNGER",
"recv_type": "Empf.",
"refresh": "Aktualisieren",
"refresh_now": "Jetzt aktualisieren",
"remove_favorite": "Favorit entfernen",
"report_bug": "Fehler melden",
"request_amount": "Betrag (optional):",
"request_copy_uri": "URI kopieren",
"request_description": "Erstellen Sie eine Zahlungsanfrage, die andere scannen oder kopieren können. Der QR-Code enthält Ihre Adresse und optionalen Betrag/Memo.",
"request_label": "Bezeichnung (optional):",
"request_memo": "Memo (optional):",
"request_payment": "Zahlung anfordern",
"request_payment_uri": "Zahlungs-URI:",
"request_receive_address": "Empfangsadresse:",
"request_select_address": "Adresse auswählen...",
"request_shielded_addrs": "-- Abgeschirmte Adressen --",
"request_title": "Zahlung anfordern",
"request_transparent_addrs": "-- Transparente Adressen --",
"request_uri_copied": "Zahlungs-URI in Zwischenablage kopiert",
"rescan": "Neu scannen",
"reset_to_defaults": "Standardwerte zurücksetzen",
"restore_address": "Adresse wiederherstellen",
"review_send": "Senden prüfen",
"rpc_host": "RPC-Host",
"rpc_pass": "Passwort",
"rpc_port": "Port",
"rpc_user": "Benutzername",
"save": "Speichern",
"save_settings": "Einstellungen speichern",
"save_z_transactions": "Z-Tx in Tx-Liste speichern",
"search_placeholder": "Suchen...",
"security": "SICHERHEIT",
"select_address": "Adresse auswählen...",
"select_receiving_address": "Empfangsadresse auswählen...",
"select_source_address": "Quelladresse auswählen...",
"send": "Senden",
"send_amount": "Betrag",
"send_amount_details": "BETRAGSDETAILS",
"send_amount_upper": "BETRAG",
"send_clear_fields": "Alle Formularfelder leeren?",
"send_copy_error": "Fehler kopieren",
"send_dismiss": "Verwerfen",
"send_error_copied": "Fehler in Zwischenablage kopiert",
"send_error_prefix": "Fehler: %s",
"send_exceeds_available": "Übersteigt verfügbar (%.8f)",
"send_fee": "Gebühr",
"send_fee_high": "Hoch",
"send_fee_low": "Niedrig",
"send_fee_normal": "Normal",
"send_form_restored": "Formular wiederhergestellt",
"send_from_this_address": "Von dieser Adresse senden",
"send_go_to_receive": "Zum Empfangen",
"send_keep": "Behalten",
"send_network_fee": "NETZWERKGEBÜHR",
"send_no_balance": "Kein Guthaben",
"send_no_recent": "Keine kürzlichen Sendungen",
"send_recent_sends": "KÜRZLICH GESENDET",
"send_recipient": "EMPFÄNGER",
"send_select_source": "Quelladresse auswählen...",
"send_sending_from": "SENDEN VON",
"send_submitting": "Transaktion wird übermittelt...",
"send_switch_to_receive": "Wechseln Sie zu Empfangen, um Ihre Adresse zu erhalten und Gelder zu empfangen.",
"send_to": "Senden an",
"send_tooltip_enter_amount": "Geben Sie einen Betrag zum Senden ein",
"send_tooltip_exceeds_balance": "Betrag übersteigt verfügbares Guthaben",
"send_tooltip_in_progress": "Transaktion bereits in Bearbeitung",
"send_tooltip_invalid_address": "Geben Sie eine gültige Empfängeradresse ein",
"send_tooltip_not_connected": "Nicht mit Daemon verbunden",
"send_tooltip_select_source": "Wählen Sie zuerst eine Quelladresse",
"send_tooltip_syncing": "Warten Sie auf die Blockchain-Synchronisierung",
"send_total": "Gesamt",
"send_transaction": "Transaktion senden",
"send_tx_failed": "Transaktion fehlgeschlagen",
"send_tx_sent": "Transaktion gesendet!",
"send_tx_success": "Transaktion erfolgreich gesendet!",
"send_txid_copied": "TxID in Zwischenablage kopiert",
"send_txid_label": "TxID: %s",
"send_valid_shielded": "Gültige abgeschirmte Adresse",
"send_valid_transparent": "Gültige transparente Adresse",
"send_wallet_empty": "Ihre Wallet ist leer",
"send_yes_clear": "Ja, leeren",
"sending": "Transaktion wird gesendet",
"sending_from": "SENDEN VON",
"sent": "gesendet",
"sent_filter": "Gesendet",
"sent_type": "Gesendet",
"sent_upper": "GESENDET",
"settings": "Einstellungen",
"settings_about_text": "Eine geschirmte Kryptowährungs-Wallet für DragonX (DRGX), erstellt mit Dear ImGui für ein leichtes, portables Erlebnis.",
"settings_acrylic_level": "Acrylstufe:",
"settings_address_book": "Adressbuch...",
"settings_auto_detected": "Automatisch erkannt aus DRAGONX.conf",
"settings_auto_lock": "AUTO-SPERRE",
"settings_auto_shield_desc": "Transparente Guthaben automatisch an geschirmte Adressen verschieben",
"settings_auto_shield_funds": "Transparente Guthaben automatisch abschirmen",
"settings_backup": "Sicherung...",
"settings_block_explorer_urls": "Block-Explorer-URLs",
"settings_builtin": "Integriert",
"settings_change_passphrase": "Passphrase ändern",
"settings_change_pin": "PIN ändern",
"settings_clear_ztx": "Z-Tx-Verlauf löschen",
"settings_clear_ztx_desc": "Lokal gespeicherte geschirmte Transaktionsdaten löschen",
"settings_clear_ztx_long": "Gespeicherten Z-Transaktionsverlauf löschen",
"settings_configure_explorer": "Externe Block-Explorer-Links konfigurieren",
"settings_configure_rpc": "Verbindung zum dragonxd-Daemon konfigurieren",
"settings_connection": "Verbindung",
"settings_copyright": "Copyright 2024-2026 DragonX-Entwickler | GPLv3-Lizenz",
"settings_custom": "Benutzerdefiniert",
"settings_data_dir": "Datenverzeichnis:",
"settings_debug_changed": "Debug-Kategorien geändert — Daemon neu starten zum Anwenden",
"settings_debug_restart_note": "Änderungen werden nach einem Neustart des Daemons wirksam.",
"settings_debug_select": "Kategorien auswählen, um Daemon-Fehlerprotokollierung zu aktivieren (-debug= Flags).",
"settings_encrypt_first_pin": "Verschlüsseln Sie zuerst die Wallet, um PIN zu aktivieren",
"settings_encrypt_wallet": "Wallet verschlüsseln",
"settings_explorer_hint": "URLs sollten einen abschließenden Schrägstrich enthalten. Die txid/Adresse wird angehängt.",
"settings_export_all": "Alle exportieren...",
"settings_export_csv": "CSV exportieren...",
"settings_export_key": "Schlüssel exportieren...",
"settings_gradient_bg": "Hintergrund-Verlauf",
"settings_gradient_desc": "Strukturierte Hintergründe durch sanfte Verläufe ersetzen",
"settings_idle_after": "nach",
"settings_import_key": "Schlüssel importieren...",
"settings_language_note": "Hinweis: Manche Texte erfordern einen Neustart zur Aktualisierung",
"settings_lock_now": "Jetzt sperren",
"settings_locked": "Gesperrt",
"settings_merge_to_address": "An Adresse zusammenführen...",
"settings_noise_opacity": "Rauschdichte:",
"settings_not_encrypted": "Nicht verschlüsselt",
"settings_not_found": "Nicht gefunden",
"settings_other": "Sonstiges",
"settings_pin_active": "PIN",
"settings_privacy": "Datenschutz",
"settings_quick_unlock_pin": "Schnell-Entsperr-PIN",
"settings_reduce_transparency": "Transparenz reduzieren",
"settings_remove_encryption": "Verschlüsselung entfernen",
"settings_remove_pin": "PIN entfernen",
"settings_request_payment": "Zahlung anfordern...",
"settings_rescan_desc": "Blockchain nach fehlenden Transaktionen neu scannen",
"settings_restart_daemon": "Daemon neu starten",
"settings_rpc_connection": "RPC-Verbindung",
"settings_rpc_note": "Hinweis: Verbindungseinstellungen werden automatisch aus DRAGONX.conf erkannt",
"settings_save_shielded_desc": "Speichert z-addr Transaktionen in einer lokalen Datei zur Ansicht",
"settings_save_shielded_local": "Geschirmten Transaktionsverlauf lokal speichern",
"settings_set_pin": "PIN festlegen",
"settings_shield_mining": "Mining abschirmen...",
"settings_solid_colors_desc": "Feste Farben anstelle von Unschärfe-Effekten verwenden (Barrierefreiheit)",
"settings_tor_desc": "Alle Verbindungen für erhöhte Privatsphäre über Tor leiten",
"settings_unlocked": "Entsperrt",
"settings_use_tor_network": "Tor für Netzwerkverbindungen verwenden",
"settings_validate_address": "Adresse überprüfen...",
"settings_visual_effects": "Visuelle Effekte",
"settings_wallet_file_size": "Wallet-Dateigröße: %s",
"settings_wallet_info": "Wallet-Informationen",
"settings_wallet_location": "Wallet-Speicherort: %s",
"settings_wallet_maintenance": "Wallet-Wartung",
"settings_wallet_not_found": "Wallet-Datei nicht gefunden",
"settings_wallet_size_label": "Wallet-Größe:",
"setup_wizard": "Einrichtungsassistent",
"share": "Teilen",
"shield_check_status": "Status prüfen",
"shield_completed": "Vorgang erfolgreich abgeschlossen!",
"shield_description": "Schirmen Sie Ihre Mining-Belohnungen ab, indem Sie Coinbase-Ausgaben von transparenten Adressen an eine abgeschirmte Adresse senden. Dies verbessert die Privatsphäre, indem Ihre Mining-Einkünfte verborgen werden.",
"shield_from_address": "Von Adresse:",
"shield_funds": "Gelder abschirmen",
"shield_in_progress": "Vorgang läuft...",
"shield_max_utxos": "Max. UTXOs pro Vorgang",
"shield_merge_done": "Abschirmung/Zusammenführung abgeschlossen!",
"shield_operation_id": "Vorgangs-ID: %s",
"shield_select_z": "z-Adresse auswählen...",
"shield_started": "Abschirmvorgang gestartet",
"shield_title": "Coinbase-Belohnungen abschirmen",
"shield_to_address": "An Adresse (Abgeschirmt):",
"shield_utxo_limit": "UTXO-Limit:",
"shield_wildcard_hint": "Verwenden Sie '*' um von allen transparenten Adressen abzuschirmen",
"shielded": "Abgeschirmt",
"shielded_to": "ABGESCHIRMT AN",
"shielded_type": "Abgeschirmt",
"show": "Anzeigen",
"show_hidden": "Ausgeblendete anzeigen (%d)",
"show_qr_code": "QR-Code anzeigen",
"showing_transactions": "Zeige %d–%d von %d Transaktionen (gesamt: %zu)",
"simple_background": "Einfacher Hintergrund",
"start_mining": "Mining starten",
"status": "Status",
"stop_external": "Externen Daemon stoppen",
"stop_mining": "Mining stoppen",
"submitting_transaction": "Transaktion wird übermittelt...",
"success": "Erfolg",
"summary": "Zusammenfassung",
"syncing": "Synchronisiere...",
"t_addresses": "T-Adressen",
"test_connection": "Testen",
"theme": "Design",
"theme_effects": "Design-Effekte",
"time_days_ago": "vor %d Tagen",
"time_hours_ago": "vor %d Stunden",
"time_minutes_ago": "vor %d Minuten",
"time_seconds_ago": "vor %d Sekunden",
"to": "An",
"to_upper": "AN",
"tools": "WERKZEUGE",
"total": "Gesamt",
"transaction_id": "TRANSAKTIONS-ID",
"transaction_sent": "Transaktion erfolgreich gesendet",
"transaction_sent_msg": "Transaktion gesendet!",
"transaction_url": "Transaktions-URL",
"transactions": "Transaktionen",
"transactions_upper": "TRANSAKTIONEN",
"transparent": "Transparent",
"tt_addr_url": "Basis-URL zum Anzeigen von Adressen in einem Block-Explorer",
"tt_address_book": "Gespeicherte Adressen für schnelles Senden verwalten",
"tt_auto_lock": "Wallet nach dieser Inaktivitätszeit sperren",
"tt_auto_shield": "Transparentes Guthaben automatisch an geschirmte Adressen für Datenschutz verschieben",
"tt_backup": "Eine Sicherungskopie Ihrer wallet.dat erstellen",
"tt_block_explorer": "Den DragonX Block-Explorer im Browser öffnen",
"tt_blur": "Unschärfe-Stärke (0%% = aus, 100%% = maximum)",
"tt_change_pass": "Die Wallet-Verschlüsselungspassphrase ändern",
"tt_change_pin": "Ihre Entsperr-PIN ändern",
"tt_clear_ztx": "Lokal zwischengespeicherten Z-Transaktionsverlauf löschen",
"tt_custom_fees": "Manuelle Gebühreneingabe beim Senden von Transaktionen aktivieren",
"tt_custom_theme": "Benutzerdefiniertes Theme aktiv",
"tt_debug_collapse": "Debug-Protokollierungsoptionen einklappen",
"tt_debug_expand": "Debug-Protokollierungsoptionen ausklappen",
"tt_encrypt": "wallet.dat mit einer Passphrase verschlüsseln",
"tt_export_all": "Alle privaten Schlüssel in eine Datei exportieren",
"tt_export_csv": "Transaktionsverlauf als CSV-Tabelle exportieren",
"tt_export_key": "Den privaten Schlüssel der ausgewählten Adresse exportieren",
"tt_fetch_prices": "DRGX-Marktpreise von der CoinGecko-API abrufen",
"tt_font_scale": "Alle Texte und UI skalieren (1.0x = Standard, bis 1.5x).",
"tt_idle_delay": "Wie lange vor dem Start des Minings gewartet werden soll",
"tt_import_key": "Einen privaten Schlüssel (zkey oder tkey) in diese Wallet importieren",
"tt_keep_daemon": "Der Daemon wird beim Ausführen des Einrichtungsassistenten gestoppt",
"tt_language": "Schnittstellensprache der Wallet-UI",
"tt_layout_hotkey": "Hotkey: Links-/Rechts-Pfeiltasten zum Wechseln der Balance-Layouts",
"tt_lock": "Die Wallet sofort sperren",
"tt_low_spec": "Alle aufwendigen visuellen Effekte deaktivieren\\nHotkey: Ctrl+Shift+Down",
"tt_merge": "Mehrere UTXOs einer Adresse zusammenführen",
"tt_mine_idle": "Mining automatisch starten, wenn das\\nSystem inaktiv ist (keine Tastatur-/Mauseingabe)",
"tt_noise": "Körnungstextur-Intensität (0%% = aus, 100%% = maximum)",
"tt_open_dir": "Klicken, um im Dateimanager zu öffnen",
"tt_remove_encrypt": "Verschlüsselung entfernen und Wallet ungeschützt speichern",
"tt_remove_pin": "PIN entfernen und Passphrase zum Entsperren erfordern",
"tt_report_bug": "Ein Problem im Projekt-Tracker melden",
"tt_request_payment": "Eine Zahlungsanforderung mit QR-Code generieren",
"tt_rescan": "Blockchain nach fehlenden Transaktionen neu scannen",
"tt_reset_settings": "Einstellungen von der Festplatte neu laden (nicht gespeicherte Änderungen rückgängig machen)",
"tt_restart_daemon": "Daemon neu starten, um Änderungen der Debug-Protokollierung anzuwenden",
"tt_rpc_host": "Hostname des DragonX-Daemons",
"tt_rpc_pass": "RPC-Authentifizierungspasswort",
"tt_rpc_port": "Port für RPC-Verbindungen des Daemons",
"tt_rpc_user": "RPC-Authentifizierungsbenutzername",
"tt_save_settings": "Alle Einstellungen auf der Festplatte speichern",
"tt_save_ztx": "Z-Adresse-Transaktionsverlauf lokal für schnelleres Laden speichern",
"tt_scan_themes": "Nach neuen Themes suchen.\\nTheme-Ordner ablegen in:\\n%s",
"tt_scanline": "CRT-Scanlinieneffekt in der Konsole",
"tt_set_pin": "Eine 4-8-stellige PIN für schnelles Entsperren festlegen",
"tt_shield_mining": "Transparente Mining-Belohnungen an eine geschirmte Adresse verschieben",
"tt_simple_bg": "Einen einfachen Verlauf für den Hintergrund verwenden\\nHotkey: Ctrl+Up",
"tt_simple_bg_alt": "Eine Verlaufsversion des Theme-Hintergrundbilds verwenden\\nHotkey: Ctrl+Up",
"tt_stop_external": "Gilt bei Verbindung zu einem Daemon,\\nder außerhalb dieser Wallet gestartet wurde",
"tt_test_conn": "Die RPC-Verbindung zum Daemon überprüfen",
"tt_theme_effects": "Schimmer, Glühen, Farbton-Zyklen pro Theme",
"tt_theme_hotkey": "Hotkey: Ctrl+Links/Rechts zum Wechseln der Themes",
"tt_tor": "Daemon-Verbindungen für Anonymität über das Tor-Netzwerk leiten",
"tt_tx_url": "Basis-URL zum Anzeigen von Transaktionen in einem Block-Explorer",
"tt_ui_opacity": "Karten- und Seitenleisten-Deckkraft (100%% = vollständig undurchsichtig, niedriger = durchsichtiger)",
"tt_validate": "Prüfen, ob eine DragonX-Adresse gültig ist",
"tt_verbose": "Detaillierte Verbindungsdiagnosen,\\nDaemon-Status und Port-Besitzer-Info\\nin der Konsolen-Registerkarte protokollieren",
"tt_website": "Die DragonX-Website öffnen",
"tt_window_opacity": "Hintergrund-Deckkraft (niedriger = Desktop durch Fenster sichtbar)",
"tt_wizard": "Den Ersteinrichtungsassistenten erneut ausführen\\nDer Daemon wird neu gestartet",
"tx_confirmations": "%d Bestätigungen",
"tx_details_title": "Transaktionsdetails",
"tx_from_address": "Von Adresse:",
"tx_id_label": "Transaktions-ID:",
"tx_immature": "UNREIF",
"tx_mined": "GEMINED",
"tx_received": "EMPFANGEN",
"tx_sent": "GESENDET",
"tx_to_address": "An Adresse:",
"tx_view_explorer": "Im Explorer anzeigen",
"txs_count": "%d Txs",
"type": "Typ",
"ui_opacity": "UI-Transparenz",
"unban": "Entsperren",
"unconfirmed": "Unbestätigt",
"undo_clear": "Leeren rückgängig",
"unknown": "Unbekannt",
"use_embedded_daemon": "Eingebetteten dragonxd verwenden",
"use_tor": "Tor verwenden",
"validate_btn": "Validieren",
"validate_description": "Geben Sie eine DragonX-Adresse ein, um zu prüfen, ob sie gültig ist und ob sie zu dieser Wallet gehört.",
"validate_invalid": "UNGÜLTIG",
"validate_is_mine": "Diese Wallet besitzt diese Adresse",
"validate_not_mine": "Nicht im Besitz dieser Wallet",
"validate_ownership": "Eigentum:",
"validate_results": "Ergebnisse:",
"validate_shielded_type": "Abgeschirmt (z-Adresse)",
"validate_status": "Status:",
"validate_title": "Adresse validieren",
"validate_transparent_type": "Transparent (t-Adresse)",
"validate_type": "Typ:",
"validate_valid": "GÜLTIG",
"validating": "Validiere...",
"verbose_logging": "Ausführliches Logging",
"version": "Version",
"view": "Ansicht",
"view_details": "Details anzeigen",
"view_on_explorer": "Im Explorer anzeigen",
"waiting_for_daemon": "Warte auf Daemon-Verbindung...",
"wallet": "WALLET",
"wallet_empty": "Ihre Wallet ist leer",
"wallet_empty_hint": "Wechseln Sie zu Empfangen, um Ihre Adresse zu erhalten und Gelder zu empfangen.",
"warning": "Warnung",
"amount_exceeds_balance": "Betrag übersteigt Kontostand",
"transaction_sent": "Transaktion erfolgreich gesendet"
"warning_upper": "WARNUNG!",
"website": "Webseite",
"window_opacity": "Fenster-Transparenz",
"yes_clear": "Ja, leeren",
"your_addresses": "Ihre Adressen",
"z_addresses": "Z-Adressen"
}
+789 -133
View File
@@ -1,139 +1,795 @@
{
"balance": "Saldo",
"send": "Enviar",
"receive": "Recibir",
"transactions": "Transacciones",
"mining": "Minería",
"peers": "Nodos",
"market": "Mercado",
"settings": "Configuración",
"summary": "Resumen",
"shielded": "Protegido",
"transparent": "Transparente",
"total": "Total",
"unconfirmed": "Sin Confirmar",
"your_addresses": "Tus Direcciones",
"z_addresses": "Direcciones-Z",
"t_addresses": "Direcciones-T",
"no_addresses": "No se encontraron direcciones. Crea una usando los botones de arriba.",
"new_z_address": "Nueva Dir-Z",
"new_t_address": "Nueva Dir-T",
"type": "Tipo",
"address": "Dirección",
"copy_address": "Copiar Dirección Completa",
"send_from_this_address": "Enviar Desde Esta Dirección",
"export_private_key": "Exportar Clave Privada",
"export_viewing_key": "Exportar Clave de Vista",
"show_qr_code": "Mostrar Código QR",
"not_connected": "No conectado al daemon...",
"pay_from": "Pagar Desde",
"send_to": "Enviar A",
"amount": "Cantidad",
"memo": "Memo (opcional, encriptado)",
"miner_fee": "Comisión de Minero",
"fee": "Comisión",
"send_transaction": "Enviar Transacción",
"clear": "Limpiar",
"select_address": "Seleccionar dirección...",
"paste": "Pegar",
"max": "Máximo",
"available": "Disponible",
"invalid_address": "Formato de dirección inválido",
"memo_z_only": "Nota: Los memos solo están disponibles al enviar a direcciones protegidas (z)",
"characters": "caracteres",
"from": "Desde",
"to": "A",
"sending": "Enviando transacción",
"confirm_send": "Confirmar Envío",
"confirm_transaction": "Confirmar Transacción",
"confirm_and_send": "Confirmar y Enviar",
"cancel": "Cancelar",
"receiving_addresses": "Tus Direcciones de Recepción",
"new_z_shielded": "Nueva Dirección-z (Protegida)",
"new_t_transparent": "Nueva Dirección-t (Transparente)",
"address_details": "Detalles de Dirección",
"view_on_explorer": "Ver en Explorador",
"qr_code": "Código QR",
"request_payment": "Solicitar Pago",
"date": "Fecha",
"status": "Estado",
"confirmations": "Confirmaciones",
"confirmed": "Confirmada",
"pending": "Pendiente",
"sent": "enviado",
"received": "recibido",
"mined": "minado",
"mining_control": "Control de Minería",
"start_mining": "Iniciar Minería",
"stop_mining": "Detener Minería",
"mining_threads": "Hilos de Minería",
"mining_statistics": "Estadísticas de Minería",
"local_hashrate": "Tasa Hash Local",
"network_hashrate": "Tasa Hash de Red",
"difficulty": "Dificultad",
"est_time_to_block": "Tiempo Est. al Bloque",
"mining_off": "Minería APAGADA",
"mining_on": "Minería ENCENDIDA",
"connected_peers": "Nodos Conectados",
"banned_peers": "Nodos Bloqueados",
"ip_address": "Dirección IP",
"version": "Versión",
"height": "Altura",
"ping": "Ping",
"ban": "Bloquear",
"unban": "Desbloquear",
"clear_all_bans": "Limpiar Todos los Bloqueos",
"price_chart": "Gráfico de Precio",
"current_price": "Precio Actual",
"24h_change": "Cambio 24h",
"24h_volume": "Volumen 24h",
"market_cap": "Cap. de Mercado",
"general": "General",
"display": "Pantalla",
"network": "Red",
"theme": "Tema",
"language": "Idioma",
"dragonx_green": "DragonX (Verde)",
"dark": "Oscuro",
"light": "Claro",
"allow_custom_fees": "Permitir comisiones personalizadas",
"use_embedded_daemon": "Usar dragonxd integrado",
"save": "Guardar",
"close": "Cerrar",
"file": "Archivo",
"edit": "Editar",
"view": "Ver",
"help": "Ayuda",
"import_private_key": "Importar Clave Privada...",
"backup_wallet": "Respaldar Cartera...",
"exit": "Salir",
"about_dragonx": "Acerca de DragonX",
"refresh_now": "Actualizar Ahora",
"about": "Acerca de",
"import": "Importar",
"export": "Exportar",
"copy_to_clipboard": "Copiar al Portapapeles",
"connected": "Conectado",
"disconnected": "Desconectado",
"connecting": "Conectando...",
"syncing": "Sincronizando...",
"block": "Bloque",
"no_addresses_available": "No hay direcciones disponibles",
"error": "Error",
"success": "Éxito",
"warning": "Advertencia",
"about_block_explorer": "Explorador de Bloques",
"about_block_height": "Altura de Bloque:",
"about_build_date": "Fecha de Compilación:",
"about_build_type": "Tipo de Compilación:",
"about_chain": "Cadena:",
"about_connections": "Conexiones:",
"about_credits": "Créditos",
"about_daemon": "Daemon:",
"about_debug": "Depuración",
"about_dragonx": "Acerca de DragonX",
"about_edition": "Edición ImGui",
"about_github": "GitHub",
"about_imgui": "ImGui:",
"about_license": "Licencia",
"about_license_text": "Este software se distribuye bajo la Licencia Pública General de GNU v3 (GPLv3). Usted es libre de usar, modificar y distribuir este software bajo los términos de la licencia.",
"about_peers_count": "%zu nodos",
"about_release": "Producción",
"about_title": "Acerca de ObsidianDragon",
"about_version": "Versión:",
"about_website": "Sitio Web",
"acrylic": "Acrílico",
"add": "Agregar",
"address": "Dirección",
"address_book_add": "Agregar Dirección",
"address_book_add_new": "Agregar Nueva",
"address_book_added": "Dirección agregada a la libreta",
"address_book_count": "%zu direcciones guardadas",
"address_book_deleted": "Entrada eliminada",
"address_book_edit": "Editar Dirección",
"address_book_empty": "No hay direcciones guardadas. Haz clic en 'Agregar Nueva' para añadir una.",
"address_book_exists": "La dirección ya existe en la libreta",
"address_book_title": "Libreta de Direcciones",
"address_book_update_failed": "Error al actualizar - la dirección puede estar duplicada",
"address_book_updated": "Dirección actualizada",
"address_copied": "Dirección copiada al portapapeles",
"address_details": "Detalles de Dirección",
"address_label": "Dirección:",
"address_upper": "DIRECCIÓN",
"address_url": "URL de Dirección",
"addresses_appear_here": "Tus direcciones de recepción aparecerán aquí una vez conectado.",
"advanced": "AVANZADO",
"all_filter": "Todos",
"allow_custom_fees": "Permitir comisiones personalizadas",
"amount": "Cantidad",
"amount_details": "DETALLES DE CANTIDAD",
"amount_exceeds_balance": "La cantidad excede el saldo",
"transaction_sent": "Transacción enviada exitosamente"
"amount_label": "Cantidad:",
"appearance": "APARIENCIA",
"auto_shield": "Auto-proteger minería",
"available": "Disponible",
"backup_backing_up": "Respaldando...",
"backup_create": "Crear Respaldo",
"backup_created": "Respaldo de cartera creado",
"backup_data": "RESPALDO Y DATOS",
"backup_description": "Crea un respaldo de tu archivo wallet.dat. Este archivo contiene todas tus claves privadas e historial de transacciones. Guarda el respaldo en un lugar seguro.",
"backup_destination": "Destino del respaldo:",
"backup_source": "Origen: %s",
"backup_tip_external": "Guarda respaldos en unidades externas o almacenamiento en la nube",
"backup_tip_multiple": "Crea múltiples respaldos en diferentes ubicaciones",
"backup_tip_test": "Prueba restaurar desde el respaldo periódicamente",
"backup_tips": "Consejos:",
"backup_title": "Respaldar Cartera",
"backup_wallet": "Respaldar Cartera...",
"backup_wallet_not_found": "Advertencia: wallet.dat no encontrado en la ubicación esperada",
"balance": "Saldo",
"balance_layout": "Diseño de Saldo",
"ban": "Bloquear",
"banned_peers": "Nodos Bloqueados",
"block": "Bloque",
"block_bits": "Bits:",
"block_click_copy": "Clic para copiar",
"block_click_next": "Clic para ver bloque siguiente",
"block_click_prev": "Clic para ver bloque anterior",
"block_explorer": "Explorador de Bloques",
"block_get_info": "Obtener Info del Bloque",
"block_hash": "Hash del Bloque:",
"block_hash_copied": "Hash de bloque copiado",
"block_height": "Altura del Bloque:",
"block_info_title": "Información del Bloque",
"block_merkle_root": "Raíz Merkle:",
"block_nav_next": "Siguiente >>",
"block_nav_prev": "<< Anterior",
"block_next": "Bloque Siguiente:",
"block_previous": "Bloque Anterior:",
"block_size": "Tamaño:",
"block_timestamp": "Fecha y Hora:",
"block_transactions": "Transacciones:",
"blockchain_syncing": "Sincronizando blockchain (%.1f%%)... Los saldos pueden ser inexactos.",
"cancel": "Cancelar",
"characters": "caracteres",
"clear": "Limpiar",
"clear_all_bans": "Limpiar Todos los Bloqueos",
"clear_anyway": "Limpiar de todos modos",
"clear_form_confirm": "¿Limpiar todos los campos del formulario?",
"clear_request": "Limpiar Solicitud",
"click_copy_address": "Clic para copiar dirección",
"click_copy_uri": "Clic para copiar URI",
"click_to_copy": "Clic para copiar",
"close": "Cerrar",
"conf_count": "%d conf",
"confirm_and_send": "Confirmar y Enviar",
"confirm_clear_ztx_title": "Confirmar limpieza del historial Z-Tx",
"confirm_clear_ztx_warning1": "Limpiar el historial de z-transacciones puede hacer que su saldo blindado se muestre como 0 hasta que se realice un reescaneo de la billetera.",
"confirm_clear_ztx_warning2": "Si esto sucede, deberá reimportar las claves privadas de su dirección z con el reescaneo habilitado para recuperar su saldo.",
"confirm_send": "Confirmar Envío",
"confirm_transaction": "Confirmar Transacción",
"confirmations": "Confirmaciones",
"confirmations_display": "%d confirmaciones | %s",
"confirmed": "Confirmada",
"connected": "Conectado",
"connected_peers": "Nodos Conectados",
"connecting": "Conectando...",
"console": "Consola",
"console_auto_scroll": "Auto-desplazamiento",
"console_available_commands": "Comandos disponibles:",
"console_capturing_output": "Capturando salida del daemon...",
"console_clear": "Limpiar",
"console_clear_console": "Limpiar Consola",
"console_cleared": "Consola limpiada",
"console_click_commands": "Clic en los comandos de arriba para insertarlos",
"console_click_insert": "Clic para insertar",
"console_click_insert_params": "Clic para insertar con parámetros",
"console_close": "Cerrar",
"console_commands": "Comandos",
"console_common_rpc": "Comandos RPC comunes:",
"console_completions": "Completaciones:",
"console_connected": "Conectado al daemon",
"console_copy_all": "Copiar Todo",
"console_copy_selected": "Copiar",
"console_daemon": "Daemon",
"console_daemon_error": "¡Error del daemon!",
"console_daemon_started": "Daemon iniciado",
"console_daemon_stopped": "Daemon detenido",
"console_disconnected": "Desconectado del daemon",
"console_errors": "Errores",
"console_filter_hint": "Filtrar salida...",
"console_help_clear": " clear - Limpiar la consola",
"console_help_getbalance": " getbalance - Mostrar saldo transparente",
"console_help_getblockcount": " getblockcount - Mostrar altura actual del bloque",
"console_help_getinfo": " getinfo - Mostrar información del nodo",
"console_help_getmininginfo": " getmininginfo - Mostrar estado de minería",
"console_help_getpeerinfo": " getpeerinfo - Mostrar nodos conectados",
"console_help_gettotalbalance": " gettotalbalance - Mostrar saldo total",
"console_help_help": " help - Mostrar este mensaje de ayuda",
"console_help_setgenerate": " setgenerate - Controlar minería",
"console_help_stop": " stop - Detener el daemon",
"console_line_count": "%zu líneas",
"console_new_lines": "%d nuevas líneas",
"console_no_daemon": "Sin daemon",
"console_not_connected": "Error: No conectado al daemon",
"console_rpc_reference": "Referencia de Comandos RPC",
"console_scanline": "Líneas de consola",
"console_search_commands": "Buscar comandos...",
"console_select_all": "Seleccionar Todo",
"console_show_daemon_output": "Mostrar salida del daemon",
"console_show_errors_only": "Mostrar solo errores",
"console_show_rpc_ref": "Mostrar referencia de comandos RPC",
"console_showing_lines": "Mostrando %zu de %zu líneas",
"console_starting_node": "Iniciando nodo...",
"console_status_error": "Error",
"console_status_running": "Ejecutando",
"console_status_starting": "Iniciando",
"console_status_stopped": "Detenido",
"console_status_stopping": "Deteniendo",
"console_status_unknown": "Desconocido",
"console_tab_completion": "Tab para completar",
"console_type_help": "Escribe 'help' para ver los comandos disponibles",
"console_welcome": "Bienvenido a la Consola de ObsidianDragon",
"console_zoom_in": "Acercar",
"console_zoom_out": "Alejar",
"copy": "Copiar",
"copy_address": "Copiar Dirección Completa",
"copy_error": "Copiar Error",
"copy_to_clipboard": "Copiar al Portapapeles",
"copy_txid": "Copiar TxID",
"copy_uri": "Copiar URI",
"current_price": "Precio Actual",
"custom_fees": "Comisiones personalizadas",
"dark": "Oscuro",
"date": "Fecha",
"date_label": "Fecha:",
"debug_logging": "REGISTRO DE DEPURACIÓN",
"delete": "Eliminar",
"difficulty": "Dificultad",
"disconnected": "Desconectado",
"dismiss": "Descartar",
"display": "Pantalla",
"dragonx_green": "DragonX (Verde)",
"edit": "Editar",
"error": "Error",
"error_format": "Error: %s",
"est_time_to_block": "Tiempo Est. al Bloque",
"exit": "Salir",
"explorer": "EXPLORADOR",
"export": "Exportar",
"export_csv": "Exportar CSV",
"export_keys_btn": "Exportar Claves",
"export_keys_danger": "PELIGRO: ¡Esto exportará TODAS las claves privadas de tu cartera! Cualquiera con acceso a este archivo puede robar tus fondos. Guárdalo de forma segura y elimínalo después de usar.",
"export_keys_include_t": "Incluir direcciones T (transparentes)",
"export_keys_include_z": "Incluir direcciones Z (protegidas)",
"export_keys_options": "Opciones de exportación:",
"export_keys_progress": "Exportando %d/%d...",
"export_keys_success": "Claves exportadas exitosamente",
"export_keys_title": "Exportar Todas las Claves Privadas",
"export_private_key": "Exportar Clave Privada",
"export_tx_count": "Exportar %zu transacciones a archivo CSV.",
"export_tx_file_fail": "Error al crear archivo CSV",
"export_tx_none": "No hay transacciones para exportar",
"export_tx_success": "Transacciones exportadas exitosamente",
"export_tx_title": "Exportar Transacciones a CSV",
"export_viewing_key": "Exportar Clave de Vista",
"failed_create_shielded": "Error al crear dirección protegida",
"failed_create_transparent": "Error al crear dirección transparente",
"favorite_address": "Marcar como favorito",
"fee": "Comisión",
"fee_high": "Alta",
"fee_label": "Comisión:",
"fee_low": "Baja",
"fee_normal": "Normal",
"fetch_prices": "Obtener precios",
"file": "Archivo",
"file_save_location": "El archivo se guardará en: ~/.config/ObsidianDragon/",
"font_scale": "Escala de fuente",
"from": "Desde",
"from_upper": "DESDE",
"full_details": "Detalles Completos",
"general": "General",
"go_to_receive": "Ir a Recibir",
"height": "Altura",
"help": "Ayuda",
"hide": "Ocultar",
"hide_address": "Ocultar dirección",
"hide_zero_balances": "Ocultar saldos 0",
"history": "Historial",
"immature_type": "Inmaduro",
"import": "Importar",
"import_key_btn": "Importar Clave(s)",
"import_key_formats": "Formatos de clave soportados:",
"import_key_full_rescan": "(0 = re-escaneo completo)",
"import_key_label": "Clave(s) Privada(s):",
"import_key_no_valid": "No se encontraron claves válidas en la entrada",
"import_key_progress": "Importando %d/%d...",
"import_key_rescan": "Re-escanear blockchain después de importar",
"import_key_start_height": "Altura inicial:",
"import_key_success": "Claves importadas exitosamente",
"import_key_t_format": "Claves privadas WIF de direcciones T",
"import_key_title": "Importar Clave Privada",
"import_key_tooltip": "Ingresa una o más claves privadas, una por línea.\nSoporta claves de direcciones z y t.\nLas líneas que empiezan con # se tratan como comentarios.",
"import_key_warning": "Advertencia: ¡Nunca compartas tus claves privadas! Importar claves de fuentes no confiables puede comprometer tu cartera.",
"import_key_z_format": "Claves de gasto de direcciones Z (secret-extended-key-...)",
"import_private_key": "Importar Clave Privada...",
"invalid_address": "Formato de dirección inválido",
"ip_address": "Dirección IP",
"keep": "Mantener",
"keep_daemon": "Mantener daemon activo",
"key_export_click_retrieve": "Haga clic para recuperar la clave de su billetera",
"key_export_fetching": "Obteniendo clave de la cartera...",
"key_export_private_key": "Clave Privada:",
"key_export_private_warning": "¡Mantén esta clave en SECRETO! Cualquiera con esta clave puede gastar tus fondos. Nunca la compartas en línea ni con personas no confiables.",
"key_export_reveal": "Revelar Clave",
"key_export_viewing_key": "Clave de Vista:",
"key_export_viewing_keys_zonly": "Las claves de visualización solo están disponibles para direcciones blindadas (z)",
"key_export_viewing_warning": "Esta clave de vista permite a otros ver tus transacciones entrantes y saldo, pero NO gastar tus fondos. Comparte solo con personas de confianza.",
"label": "Etiqueta:",
"language": "Idioma",
"light": "Claro",
"loading": "Cargando...",
"loading_addresses": "Cargando direcciones...",
"local_hashrate": "Tasa Hash Local",
"low_spec_mode": "Modo bajo rendimiento",
"market": "Mercado",
"market_12h": "12h",
"market_18h": "18h",
"market_24h": "24h",
"market_24h_volume": "VOLUMEN 24H",
"market_6h": "6h",
"market_attribution": "Datos de precios de NonKYC",
"market_btc_price": "PRECIO BTC",
"market_cap": "Cap. de Mercado",
"market_no_history": "No hay historial de precios disponible",
"market_no_price": "Sin datos de precio",
"market_now": "Ahora",
"market_pct_shielded": "%.0f%% Protegido",
"market_portfolio": "PORTAFOLIO",
"market_price_unavailable": "Datos de precio no disponibles",
"market_refresh_price": "Actualizar datos de precio",
"market_trade_on": "Operar en %s",
"mature": "Maduro",
"max": "Máximo",
"memo": "Memo (opcional, encriptado)",
"memo_label": "Memo:",
"memo_optional": "MEMO (OPCIONAL)",
"memo_upper": "MEMO",
"memo_z_only": "Nota: Los memos solo están disponibles al enviar a direcciones blindadas (z)",
"merge_description": "Fusiona múltiples UTXOs en una sola dirección protegida. Esto puede ayudar a reducir el tamaño de la cartera y mejorar la privacidad.",
"merge_funds": "Fusionar Fondos",
"merge_started": "Operación de fusión iniciada",
"merge_title": "Fusionar a Dirección",
"mine_when_idle": "Minar en reposo",
"mined": "minado",
"mined_filter": "Minado",
"mined_type": "Minado",
"mined_upper": "MINADO",
"miner_fee": "Tarifa de minero",
"mining": "Minería",
"mining_active": "Activo",
"mining_address_copied": "Dirección de minería copiada",
"mining_all_time": "Todo el Tiempo",
"mining_already_saved": "URL del pool ya guardada",
"mining_block_copied": "Hash de bloque copiado",
"mining_chart_1m_ago": "hace 1m",
"mining_chart_5m_ago": "hace 5m",
"mining_chart_now": "Ahora",
"mining_chart_start": "Inicio",
"mining_click": "Clic",
"mining_click_copy_address": "Clic para copiar dirección",
"mining_click_copy_block": "Clic para copiar hash de bloque",
"mining_click_copy_difficulty": "Clic para copiar dificultad",
"mining_connected": "Conectado",
"mining_connecting": "Conectando...",
"mining_control": "Control de Minería",
"mining_difficulty_copied": "Dificultad copiada",
"mining_est_block": "Bloque Est.",
"mining_est_daily": "Diario Est.",
"mining_filter_all": "Todos",
"mining_filter_tip_all": "Mostrar todas las ganancias",
"mining_filter_tip_pool": "Mostrar solo ganancias del pool",
"mining_filter_tip_solo": "Mostrar solo ganancias solo",
"mining_idle_off_tooltip": "Activar minería en reposo",
"mining_idle_on_tooltip": "Desactivar minería en reposo",
"mining_local_hashrate": "Hashrate Local",
"mining_mine": "Minar",
"mining_mining_addr": "Dir. Minería",
"mining_network": "Red",
"mining_no_blocks_yet": "Aún no se han encontrado bloques",
"mining_no_payouts_yet": "Aún no hay pagos del pool",
"mining_no_saved_addresses": "No hay direcciones guardadas",
"mining_no_saved_pools": "No hay pools guardados",
"mining_off": "La minería está APAGADA",
"mining_on": "La minería está ENCENDIDA",
"mining_open_in_explorer": "Abrir en explorador",
"mining_payout_address": "Dirección de Pago",
"mining_payout_tooltip": "Dirección para recibir recompensas de minería",
"mining_pool": "Pool",
"mining_pool_hashrate": "Hashrate del Pool",
"mining_pool_url": "URL del Pool",
"mining_recent_blocks": "BLOQUES RECIENTES",
"mining_recent_payouts": "PAGOS DE POOL RECIENTES",
"mining_remove": "Eliminar",
"mining_reset_defaults": "Restablecer Valores",
"mining_save_payout_address": "Guardar dirección de pago",
"mining_save_pool_url": "Guardar URL del pool",
"mining_saved_addresses": "Direcciones Guardadas:",
"mining_saved_pools": "Pools Guardados:",
"mining_shares": "Acciones",
"mining_show_chart": "Gráfico",
"mining_show_log": "Registro",
"mining_solo": "Solo",
"mining_starting": "Iniciando...",
"mining_starting_tooltip": "El minero está iniciando...",
"mining_statistics": "Estadísticas de Minería",
"mining_stop": "Detener",
"mining_stop_solo_for_pool": "Detener minería solo antes de iniciar minería en pool",
"mining_stop_solo_for_pool_settings": "Detener minería solo para cambiar configuración del pool",
"mining_stopping": "Deteniendo...",
"mining_stopping_tooltip": "El minero está deteniéndose...",
"mining_syncing_tooltip": "El blockchain está sincronizando...",
"mining_threads": "Hilos de Minería",
"mining_to_save": "para guardar",
"mining_today": "Hoy",
"mining_uptime": "Tiempo activo",
"mining_yesterday": "Ayer",
"network": "Red",
"network_fee": "COMISIÓN DE RED",
"network_hashrate": "Tasa de Hash de la Red",
"new": "+ Nuevo",
"new_shielded_created": "Nueva dirección protegida creada",
"new_t_address": "Nueva Dirección T",
"new_t_transparent": "Nueva dirección t (Transparente)",
"new_transparent_created": "Nueva dirección transparente creada",
"new_z_address": "Nueva Dirección Z",
"new_z_shielded": "Nueva dirección z (Blindada)",
"no_addresses": "No se encontraron direcciones. Cree una usando los botones de arriba.",
"no_addresses_available": "No hay direcciones disponibles",
"no_addresses_match": "No hay direcciones que coincidan con el filtro",
"no_addresses_with_balance": "No hay direcciones con saldo",
"no_matching": "No hay transacciones coincidentes",
"no_recent_receives": "No hay recepciones recientes",
"no_recent_sends": "No hay envíos recientes",
"no_transactions": "No se encontraron transacciones",
"node": "NODO",
"node_security": "NODO Y SEGURIDAD",
"noise": "Ruido",
"not_connected": "No conectado al daemon...",
"not_connected_to_daemon": "No conectado al daemon",
"notes": "Notas",
"notes_optional": "Notas (opcional):",
"output_filename": "Nombre del archivo:",
"overview": "Resumen",
"paste": "Pegar",
"paste_from_clipboard": "Pegar del Portapapeles",
"pay_from": "Pagar desde",
"payment_request": "SOLICITUD DE PAGO",
"payment_request_copied": "Solicitud de pago copiada",
"payment_uri_copied": "URI de pago copiada",
"peers": "Nodos",
"peers_avg_ping": "Ping Prom.",
"peers_ban_24h": "Bloquear Nodo 24h",
"peers_ban_score": "Puntuación: %d",
"peers_banned": "Bloqueados",
"peers_banned_count": "Bloqueados: %d",
"peers_best_block": "Mejor Bloque",
"peers_blockchain": "BLOCKCHAIN",
"peers_blocks": "Bloques",
"peers_blocks_left": "%d bloques restantes",
"peers_clear_all_bans": "Limpiar Todos los Bloqueos",
"peers_click_copy": "Clic para copiar",
"peers_connected": "Conectados",
"peers_connected_count": "Conectados: %d",
"peers_copy_ip": "Copiar IP",
"peers_dir_in": "Ent",
"peers_dir_out": "Sal",
"peers_hash_copied": "Hash copiado",
"peers_hashrate": "Tasa de hash",
"peers_in_out": "Ent/Sal",
"peers_longest": "Más Larga",
"peers_longest_chain": "Cadena Más Larga",
"peers_memory": "Memoria",
"peers_no_banned": "No hay nodos bloqueados",
"peers_no_connected": "No hay nodos conectados",
"peers_no_tls": "Sin TLS",
"peers_notarized": "Notarizado",
"peers_p2p_port": "Puerto P2P",
"peers_peer_label": "Peer: %s",
"peers_protocol": "Protocolo",
"peers_received": "Recibido",
"peers_refresh": "Actualizar",
"peers_refresh_tooltip": "Actualizar lista de nodos",
"peers_refreshing": "Actualizando...",
"peers_sent": "Enviado",
"peers_tt_id": "ID: %d",
"peers_tt_received": "Recibido: %s",
"peers_tt_sent": "Enviado: %s",
"peers_tt_services": "Servicios: %s",
"peers_tt_start_height": "Altura Inicial: %d",
"peers_tt_synced": "Sinc H/B: %d/%d",
"peers_tt_tls_cipher": "TLS: %s",
"peers_unban": "Desbloquear",
"peers_upper": "NODOS",
"peers_version": "Versión",
"pending": "Pendiente",
"ping": "Ping",
"price_chart": "Gráfico de Precios",
"qr_code": "Código QR",
"qr_failed": "Error al generar código QR",
"qr_title": "Código QR",
"qr_unavailable": "QR no disponible",
"ram_daemon_gb": "Daemon: %.1f GB (%s)",
"ram_daemon_mb": "Daemon: %.0f MB (%s)",
"ram_system_gb": "Sistema: %.1f / %.0f GB",
"ram_wallet_gb": "Billetera: %.1f GB",
"ram_wallet_mb": "Billetera: %.0f MB",
"receive": "Recibir",
"received": "recibido",
"received_filter": "Recibido",
"received_label": "Recibido",
"received_upper": "RECIBIDO",
"receiving_addresses": "Sus Direcciones de Recepción",
"recent_received": "RECIBIDOS RECIENTES",
"recent_sends": "ENVÍOS RECIENTES",
"recipient": "DESTINATARIO",
"recv_type": "Recibido",
"refresh": "Actualizar",
"refresh_now": "Actualizar Ahora",
"remove_favorite": "Quitar favorito",
"report_bug": "Reportar Error",
"request_amount": "Cantidad (opcional):",
"request_copy_uri": "Copiar URI",
"request_description": "Genera una solicitud de pago que otros pueden escanear o copiar. El código QR contiene tu dirección y cantidad/memo opcionales.",
"request_label": "Etiqueta (opcional):",
"request_memo": "Memo (opcional):",
"request_payment": "Solicitar Pago",
"request_payment_uri": "URI de Pago:",
"request_receive_address": "Dirección de Recepción:",
"request_select_address": "Seleccionar dirección...",
"request_shielded_addrs": "-- Direcciones Protegidas --",
"request_title": "Solicitar Pago",
"request_transparent_addrs": "-- Direcciones Transparentes --",
"request_uri_copied": "URI de pago copiada al portapapeles",
"rescan": "Re-escanear",
"reset_to_defaults": "Restablecer Valores",
"restore_address": "Restaurar dirección",
"review_send": "Revisar Envío",
"rpc_host": "Host RPC",
"rpc_pass": "Contraseña",
"rpc_port": "Puerto",
"rpc_user": "Usuario",
"save": "Guardar",
"save_settings": "Guardar Configuración",
"save_z_transactions": "Guardar Z-tx en lista",
"search_placeholder": "Buscar...",
"security": "SEGURIDAD",
"select_address": "Seleccionar dirección...",
"select_receiving_address": "Seleccionar dirección de recepción...",
"select_source_address": "Seleccionar dirección de origen...",
"send": "Enviar",
"send_amount": "Cantidad",
"send_amount_details": "DETALLES DE CANTIDAD",
"send_amount_upper": "CANTIDAD",
"send_clear_fields": "¿Limpiar todos los campos del formulario?",
"send_copy_error": "Copiar Error",
"send_dismiss": "Descartar",
"send_error_copied": "Error copiado al portapapeles",
"send_error_prefix": "Error: %s",
"send_exceeds_available": "Excede disponible (%.8f)",
"send_fee": "Comisión",
"send_fee_high": "Alta",
"send_fee_low": "Baja",
"send_fee_normal": "Normal",
"send_form_restored": "Formulario restaurado",
"send_from_this_address": "Enviar desde esta dirección",
"send_go_to_receive": "Ir a Recibir",
"send_keep": "Mantener",
"send_network_fee": "COMISIÓN DE RED",
"send_no_balance": "Sin saldo",
"send_no_recent": "No hay envíos recientes",
"send_recent_sends": "ENVÍOS RECIENTES",
"send_recipient": "DESTINATARIO",
"send_select_source": "Seleccionar dirección de origen...",
"send_sending_from": "ENVIANDO DESDE",
"send_submitting": "Enviando transacción...",
"send_switch_to_receive": "Cambia a Recibir para obtener tu dirección y empezar a recibir fondos.",
"send_to": "Enviar a",
"send_tooltip_enter_amount": "Ingresa una cantidad a enviar",
"send_tooltip_exceeds_balance": "La cantidad excede el saldo disponible",
"send_tooltip_in_progress": "Transacción ya en progreso",
"send_tooltip_invalid_address": "Ingresa una dirección de destinatario válida",
"send_tooltip_not_connected": "No conectado al daemon",
"send_tooltip_select_source": "Selecciona una dirección de origen primero",
"send_tooltip_syncing": "Espera a que se sincronice el blockchain",
"send_total": "Total",
"send_transaction": "Enviar Transacción",
"send_tx_failed": "Error en la transacción",
"send_tx_sent": "¡Transacción enviada!",
"send_tx_success": "¡Transacción enviada exitosamente!",
"send_txid_copied": "TxID copiado al portapapeles",
"send_txid_label": "TxID: %s",
"send_valid_shielded": "Dirección protegida válida",
"send_valid_transparent": "Dirección transparente válida",
"send_wallet_empty": "Tu cartera está vacía",
"send_yes_clear": "Sí, Limpiar",
"sending": "Enviando transacción",
"sending_from": "ENVIANDO DESDE",
"sent": "enviado",
"sent_filter": "Enviado",
"sent_type": "Enviado",
"sent_upper": "ENVIADO",
"settings": "Configuración",
"settings_about_text": "Una billetera de criptomonedas blindada para DragonX (DRGX), creada con Dear ImGui para una experiencia ligera y portátil.",
"settings_acrylic_level": "Nivel de acrílico:",
"settings_address_book": "Libreta de direcciones...",
"settings_auto_detected": "Autodetectado de DRAGONX.conf",
"settings_auto_lock": "BLOQUEO AUTOMÁTICO",
"settings_auto_shield_desc": "Mover automáticamente fondos transparentes a direcciones blindadas",
"settings_auto_shield_funds": "Blindar fondos transparentes automáticamente",
"settings_backup": "Respaldo...",
"settings_block_explorer_urls": "URLs del explorador de bloques",
"settings_builtin": "Integrado",
"settings_change_passphrase": "Cambiar contraseña",
"settings_change_pin": "Cambiar PIN",
"settings_clear_ztx": "Limpiar historial Z-Tx",
"settings_clear_ztx_desc": "Eliminar datos de transacciones blindadas almacenados localmente",
"settings_clear_ztx_long": "Limpiar historial guardado de Z-transacciones",
"settings_configure_explorer": "Configurar enlaces de explorador de bloques externo",
"settings_configure_rpc": "Configurar conexión al daemon dragonxd",
"settings_connection": "Conexión",
"settings_copyright": "Copyright 2024-2026 Desarrolladores de DragonX | Licencia GPLv3",
"settings_custom": "Personalizado",
"settings_data_dir": "Dir. de datos:",
"settings_debug_changed": "Categorías de depuración cambiadas — reinicie el daemon para aplicar",
"settings_debug_restart_note": "Los cambios surten efecto después de reiniciar el daemon.",
"settings_debug_select": "Seleccione categorías para habilitar el registro de depuración del daemon (flags -debug=).",
"settings_encrypt_first_pin": "Primero cifre la billetera para habilitar el PIN",
"settings_encrypt_wallet": "Cifrar billetera",
"settings_explorer_hint": "Las URLs deben incluir una barra final. Se añadirá el txid/dirección.",
"settings_export_all": "Exportar todo...",
"settings_export_csv": "Exportar CSV...",
"settings_export_key": "Exportar clave...",
"settings_gradient_bg": "Fondo degradado",
"settings_gradient_desc": "Reemplazar fondos con texturas por degradados suaves",
"settings_idle_after": "después de",
"settings_import_key": "Importar clave...",
"settings_language_note": "Nota: Parte del texto requiere reinicio para actualizarse",
"settings_lock_now": "Bloquear ahora",
"settings_locked": "Bloqueado",
"settings_merge_to_address": "Fusionar a dirección...",
"settings_noise_opacity": "Opacidad de ruido:",
"settings_not_encrypted": "Sin cifrar",
"settings_not_found": "No encontrado",
"settings_other": "Otros",
"settings_pin_active": "PIN",
"settings_privacy": "Privacidad",
"settings_quick_unlock_pin": "PIN de desbloqueo rápido",
"settings_reduce_transparency": "Reducir transparencia",
"settings_remove_encryption": "Quitar cifrado",
"settings_remove_pin": "Quitar PIN",
"settings_request_payment": "Solicitar pago...",
"settings_rescan_desc": "Reescanear la cadena de bloques en busca de transacciones faltantes",
"settings_restart_daemon": "Reiniciar daemon",
"settings_rpc_connection": "Conexión RPC",
"settings_rpc_note": "Nota: Los ajustes de conexión se detectan automáticamente desde DRAGONX.conf",
"settings_save_shielded_desc": "Almacena transacciones z-addr en un archivo local para visualización",
"settings_save_shielded_local": "Guardar historial de transacciones blindadas localmente",
"settings_set_pin": "Establecer PIN",
"settings_shield_mining": "Blindar minería...",
"settings_solid_colors_desc": "Usar colores sólidos en lugar de efectos de desenfoque (accesibilidad)",
"settings_tor_desc": "Enrutar todas las conexiones a través de Tor para mayor privacidad",
"settings_unlocked": "Desbloqueado",
"settings_use_tor_network": "Usar Tor para conexiones de red",
"settings_validate_address": "Validar dirección...",
"settings_visual_effects": "Efectos visuales",
"settings_wallet_file_size": "Tamaño del archivo de billetera: %s",
"settings_wallet_info": "Información de billetera",
"settings_wallet_location": "Ubicación de billetera: %s",
"settings_wallet_maintenance": "Mantenimiento de billetera",
"settings_wallet_not_found": "Archivo de billetera no encontrado",
"settings_wallet_size_label": "Tamaño de billetera:",
"setup_wizard": "Asistente de Configuración",
"share": "Compartir",
"shield_check_status": "Verificar Estado",
"shield_completed": "¡Operación completada exitosamente!",
"shield_description": "Protege tus recompensas de minería enviando salidas coinbase de direcciones transparentes a una dirección protegida. Esto mejora la privacidad ocultando tus ingresos de minería.",
"shield_from_address": "Dirección de Origen:",
"shield_funds": "Proteger Fondos",
"shield_in_progress": "Operación en progreso...",
"shield_max_utxos": "UTXOs máximos por operación",
"shield_merge_done": "¡Protección/fusión completada!",
"shield_operation_id": "ID de operación: %s",
"shield_select_z": "Seleccionar dirección z...",
"shield_started": "Operación de protección iniciada",
"shield_title": "Proteger Recompensas de Coinbase",
"shield_to_address": "Dirección Destino (Protegida):",
"shield_utxo_limit": "Límite UTXO:",
"shield_wildcard_hint": "Usa '*' para proteger desde todas las direcciones transparentes",
"shielded": "Blindada",
"shielded_to": "PROTEGIDA PARA",
"shielded_type": "Protegido",
"show": "Mostrar",
"show_hidden": "Mostrar ocultos (%d)",
"show_qr_code": "Mostrar Código QR",
"showing_transactions": "Mostrando %d–%d de %d transacciones (total: %zu)",
"simple_background": "Fondo simple",
"start_mining": "Iniciar Minería",
"status": "Estado",
"stop_external": "Detener daemon externo",
"stop_mining": "Detener Minería",
"submitting_transaction": "Enviando transacción...",
"success": "Éxito",
"summary": "Resumen",
"syncing": "Sincronizando...",
"t_addresses": "Direcciones T",
"test_connection": "Probar",
"theme": "Tema",
"theme_effects": "Efectos de tema",
"time_days_ago": "hace %d días",
"time_hours_ago": "hace %d horas",
"time_minutes_ago": "hace %d minutos",
"time_seconds_ago": "hace %d segundos",
"to": "Para",
"to_upper": "PARA",
"tools": "HERRAMIENTAS",
"total": "Total",
"transaction_id": "ID DE TRANSACCIÓN",
"transaction_sent": "Transacción enviada exitosamente",
"transaction_sent_msg": "¡Transacción enviada!",
"transaction_url": "URL de Transacción",
"transactions": "Transacciones",
"transactions_upper": "TRANSACCIONES",
"transparent": "Transparente",
"tt_addr_url": "URL base para ver direcciones en un explorador de bloques",
"tt_address_book": "Administrar direcciones guardadas para envío rápido",
"tt_auto_lock": "Bloquear billetera después de este tiempo de inactividad",
"tt_auto_shield": "Mover automáticamente el saldo transparente a direcciones blindadas para privacidad",
"tt_backup": "Crear una copia de seguridad de su wallet.dat",
"tt_block_explorer": "Abrir el explorador de bloques DragonX en su navegador",
"tt_blur": "Cantidad de desenfoque (0%% = apagado, 100%% = máximo)",
"tt_change_pass": "Cambiar la contraseña de cifrado de la billetera",
"tt_change_pin": "Cambiar su PIN de desbloqueo",
"tt_clear_ztx": "Eliminar historial de z-transacciones en caché local",
"tt_custom_fees": "Habilitar entrada manual de comisiones al enviar transacciones",
"tt_custom_theme": "Tema personalizado activo",
"tt_debug_collapse": "Colapsar opciones de registro de depuración",
"tt_debug_expand": "Expandir opciones de registro de depuración",
"tt_encrypt": "Cifrar wallet.dat con una contraseña",
"tt_export_all": "Exportar todas las claves privadas a un archivo",
"tt_export_csv": "Exportar historial de transacciones como hoja de cálculo CSV",
"tt_export_key": "Exportar la clave privada de la dirección seleccionada",
"tt_fetch_prices": "Obtener precios de mercado de DRGX desde la API de CoinGecko",
"tt_font_scale": "Escalar todo el texto y la interfaz (1.0x = predeterminado, hasta 1.5x).",
"tt_idle_delay": "Cuánto tiempo esperar antes de empezar a minar",
"tt_import_key": "Importar una clave privada (zkey o tkey) en esta billetera",
"tt_keep_daemon": "El daemon se detendrá cuando ejecute el asistente de configuración",
"tt_language": "Idioma de la interfaz de la billetera",
"tt_layout_hotkey": "Atajo: teclas de flecha izquierda/derecha para cambiar diseños de Balance",
"tt_lock": "Bloquear la billetera inmediatamente",
"tt_low_spec": "Desactivar todos los efectos visuales pesados\\nAtajo: Ctrl+Shift+Down",
"tt_merge": "Consolidar múltiples UTXOs en una dirección",
"tt_mine_idle": "Iniciar minería automáticamente cuando el\\nsistema esté inactivo (sin entrada de teclado/ratón)",
"tt_noise": "Intensidad de textura granulada (0%% = apagado, 100%% = máximo)",
"tt_open_dir": "Clic para abrir en explorador de archivos",
"tt_remove_encrypt": "Quitar cifrado y almacenar la billetera sin protección",
"tt_remove_pin": "Quitar PIN y requerir contraseña para desbloquear",
"tt_report_bug": "Reportar un problema en el rastreador del proyecto",
"tt_request_payment": "Generar una solicitud de pago con código QR",
"tt_rescan": "Reescanear la cadena de bloques en busca de transacciones faltantes",
"tt_reset_settings": "Recargar configuraciones desde disco (deshacer cambios no guardados)",
"tt_restart_daemon": "Reiniciar el daemon para aplicar cambios de registro de depuración",
"tt_rpc_host": "Nombre de host del daemon DragonX",
"tt_rpc_pass": "Contraseña de autenticación RPC",
"tt_rpc_port": "Puerto para conexiones RPC del daemon",
"tt_rpc_user": "Nombre de usuario de autenticación RPC",
"tt_save_settings": "Guardar todas las configuraciones en disco",
"tt_save_ztx": "Almacenar historial de transacciones de z-address localmente para carga más rápida",
"tt_scan_themes": "Buscar nuevos temas.\\nColoque carpetas de temas en:\\n%s",
"tt_scanline": "Efecto de líneas de escaneo CRT en la consola",
"tt_set_pin": "Establecer un PIN de 4-8 dígitos para desbloqueo rápido",
"tt_shield_mining": "Mover recompensas de minería transparentes a una dirección blindada",
"tt_simple_bg": "Usar un gradiente simple para el fondo\\nAtajo: Ctrl+Up",
"tt_simple_bg_alt": "Usar una versión degradada de la imagen de fondo del tema\\nAtajo: Ctrl+Up",
"tt_stop_external": "Se aplica al conectarse a un daemon\\niniciado fuera de esta billetera",
"tt_test_conn": "Verificar la conexión RPC al daemon",
"tt_theme_effects": "Brillo, resplandor, ciclo de tono por tema",
"tt_theme_hotkey": "Atajo: Ctrl+Izquierda/Derecha para cambiar temas",
"tt_tor": "Enrutar conexiones del daemon a través de la red Tor para anonimato",
"tt_tx_url": "URL base para ver transacciones en un explorador de bloques",
"tt_ui_opacity": "Opacidad de tarjetas y barra lateral (100%% = totalmente opaco, menor = más transparente)",
"tt_validate": "Comprobar si una dirección DragonX es válida",
"tt_verbose": "Registrar diagnósticos detallados de conexión,\\nestado del daemon e info de propietario de puerto\\nen la pestaña de Consola",
"tt_website": "Abrir el sitio web de DragonX",
"tt_window_opacity": "Opacidad del fondo (menor = escritorio visible a través de la ventana)",
"tt_wizard": "Volver a ejecutar el asistente de configuración inicial\\nEl daemon será reiniciado",
"tx_confirmations": "%d confirmaciones",
"tx_details_title": "Detalles de Transacción",
"tx_from_address": "Dirección Origen:",
"tx_id_label": "ID de Transacción:",
"tx_immature": "INMADURO",
"tx_mined": "MINADO",
"tx_received": "RECIBIDO",
"tx_sent": "ENVIADO",
"tx_to_address": "Dirección Destino:",
"tx_view_explorer": "Ver en Explorador",
"txs_count": "%d txs",
"type": "Tipo",
"ui_opacity": "Opacidad de UI",
"unban": "Desbanear",
"unconfirmed": "Sin confirmar",
"undo_clear": "Deshacer Limpieza",
"unknown": "Desconocido",
"use_embedded_daemon": "Usar dragonxd integrado",
"use_tor": "Usar Tor",
"validate_btn": "Validar",
"validate_description": "Ingresa una dirección DragonX para verificar si es válida y si pertenece a esta cartera.",
"validate_invalid": "INVÁLIDA",
"validate_is_mine": "Esta cartera es dueña de esta dirección",
"validate_not_mine": "No es propiedad de esta cartera",
"validate_ownership": "Propiedad:",
"validate_results": "Resultados:",
"validate_shielded_type": "Protegida (dirección z)",
"validate_status": "Estado:",
"validate_title": "Validar Dirección",
"validate_transparent_type": "Transparente (dirección t)",
"validate_type": "Tipo:",
"validate_valid": "VÁLIDA",
"validating": "Validando...",
"verbose_logging": "Registro detallado",
"version": "Versión",
"view": "Ver",
"view_details": "Ver Detalles",
"view_on_explorer": "Ver en Explorador",
"waiting_for_daemon": "Esperando conexión al daemon...",
"wallet": "CARTERA",
"wallet_empty": "Tu cartera está vacía",
"wallet_empty_hint": "Cambia a Recibir para obtener tu dirección y empezar a recibir fondos.",
"warning": "Advertencia",
"warning_upper": "¡ADVERTENCIA!",
"website": "Sitio Web",
"window_opacity": "Opacidad de ventana",
"yes_clear": "Sí, Limpiar",
"your_addresses": "Sus Direcciones",
"z_addresses": "Direcciones Z"
}
+789 -133
View File
@@ -1,139 +1,795 @@
{
"balance": "Solde",
"send": "Envoyer",
"receive": "Recevoir",
"transactions": "Transactions",
"mining": "Minage",
"peers": "Nœuds",
"market": "Marché",
"settings": "Paramètres",
"summary": "Résumé",
"shielded": "Protégé",
"transparent": "Transparent",
"total": "Total",
"unconfirmed": "Non confirmé",
"your_addresses": "Vos adresses",
"z_addresses": "Adresses-Z",
"t_addresses": "Adresses-T",
"no_addresses": "Aucune adresse trouvée. Créez-en une avec les boutons ci-dessus.",
"new_z_address": "Nouvelle adresse-Z",
"new_t_address": "Nouvelle adresse-T",
"type": "Type",
"address": "Adresse",
"copy_address": "Copier l'adresse complète",
"send_from_this_address": "Envoyer depuis cette adresse",
"export_private_key": "Exporter la clé privée",
"export_viewing_key": "Exporter la clé de visualisation",
"show_qr_code": "Afficher le QR code",
"not_connected": "Non connecté au démon...",
"pay_from": "Payer depuis",
"send_to": "Envoyer à",
"amount": "Montant",
"memo": "Mémo (optionnel, chiffré)",
"miner_fee": "Frais de mineur",
"fee": "Frais",
"send_transaction": "Envoyer la transaction",
"clear": "Effacer",
"select_address": "Sélectionner une adresse...",
"paste": "Coller",
"max": "Max",
"available": "Disponible",
"invalid_address": "Format d'adresse invalide",
"memo_z_only": "Note : les mémos ne sont disponibles qu'en envoyant vers des adresses protégées (z)",
"characters": "caractères",
"from": "De",
"to": "À",
"sending": "Envoi de la transaction",
"confirm_send": "Confirmer l'envoi",
"confirm_transaction": "Confirmer la transaction",
"confirm_and_send": "Confirmer et envoyer",
"cancel": "Annuler",
"receiving_addresses": "Vos adresses de réception",
"new_z_shielded": "Nouvelle adresse-z (protégée)",
"new_t_transparent": "Nouvelle adresse-t (transparente)",
"address_details": "Détails de l'adresse",
"view_on_explorer": "Voir sur l'explorateur",
"qr_code": "QR Code",
"request_payment": "Demander un paiement",
"date": "Date",
"status": "Statut",
"confirmations": "Confirmations",
"confirmed": "Confirmée",
"pending": "En attente",
"sent": "envoyé",
"received": "reçu",
"mined": "miné",
"mining_control": "Contrôle du minage",
"start_mining": "Démarrer le minage",
"stop_mining": "Arrêter le minage",
"mining_threads": "Threads de minage",
"mining_statistics": "Statistiques de minage",
"local_hashrate": "Hashrate local",
"network_hashrate": "Hashrate du réseau",
"difficulty": "Difficulté",
"est_time_to_block": "Temps est. avant bloc",
"mining_off": "Minage DÉSACTIVÉ",
"mining_on": "Minage ACTIVÉ",
"connected_peers": "Nœuds connectés",
"banned_peers": "Nœuds bannis",
"ip_address": "Adresse IP",
"version": "Version",
"height": "Hauteur",
"ping": "Ping",
"ban": "Bannir",
"unban": "Débannir",
"clear_all_bans": "Lever tous les bannissements",
"price_chart": "Graphique des prix",
"current_price": "Prix actuel",
"24h_change": "Variation 24h",
"24h_volume": "Volume 24h",
"market_cap": "Capitalisation",
"general": "Général",
"display": "Affichage",
"network": "Réseau",
"theme": "Thème",
"language": "Langue",
"dragonx_green": "DragonX (Vert)",
"dark": "Sombre",
"light": "Clair",
"allow_custom_fees": "Autoriser les frais personnalisés",
"use_embedded_daemon": "Utiliser le dragonxd intégré",
"save": "Enregistrer",
"close": "Fermer",
"file": "Fichier",
"edit": "Édition",
"view": "Affichage",
"help": "Aide",
"import_private_key": "Importer une clé privée...",
"backup_wallet": "Sauvegarder le portefeuille...",
"exit": "Quitter",
"about_dragonx": "À propos d'ObsidianDragon",
"refresh_now": "Actualiser maintenant",
"about": "À propos",
"import": "Importer",
"export": "Exporter",
"copy_to_clipboard": "Copier dans le presse-papiers",
"connected": "Connecté",
"disconnected": "Déconnecté",
"connecting": "Connexion...",
"syncing": "Synchronisation...",
"block": "Bloc",
"no_addresses_available": "Aucune adresse disponible",
"error": "Erreur",
"success": "Succès",
"warning": "Avertissement",
"about_block_explorer": "Explorateur de blocs",
"about_block_height": "Hauteur de bloc :",
"about_build_date": "Date de compilation :",
"about_build_type": "Type de build :",
"about_chain": "Chaîne :",
"about_connections": "Connexions :",
"about_credits": "Crédits",
"about_daemon": "Daemon :",
"about_debug": "Débogage",
"about_dragonx": "À propos d'ObsidianDragon",
"about_edition": "Édition ImGui",
"about_github": "GitHub",
"about_imgui": "ImGui :",
"about_license": "Licence",
"about_license_text": "Ce logiciel est publié sous la licence publique générale GNU v3 (GPLv3). Vous êtes libre d'utiliser, de modifier et de distribuer ce logiciel selon les termes de la licence.",
"about_peers_count": "%zu pairs",
"about_release": "Version",
"about_title": "À propos d'ObsidianDragon",
"about_version": "Version :",
"about_website": "Site web",
"acrylic": "Acrylique",
"add": "Ajouter",
"address": "Adresse",
"address_book_add": "Ajouter une adresse",
"address_book_add_new": "Ajouter",
"address_book_added": "Adresse ajoutée au carnet",
"address_book_count": "%zu adresses enregistrées",
"address_book_deleted": "Entrée supprimée",
"address_book_edit": "Modifier l'adresse",
"address_book_empty": "Aucune adresse enregistrée. Cliquez sur 'Ajouter' pour en créer une.",
"address_book_exists": "L'adresse existe déjà dans le carnet",
"address_book_title": "Carnet d'adresses",
"address_book_update_failed": "Échec de la mise à jour - l'adresse est peut-être en double",
"address_book_updated": "Adresse mise à jour",
"address_copied": "Adresse copiée dans le presse-papiers",
"address_details": "Détails de l'adresse",
"address_label": "Adresse :",
"address_upper": "ADRESSE",
"address_url": "URL de l'adresse",
"addresses_appear_here": "Vos adresses de réception apparaîtront ici une fois connecté.",
"advanced": "AVANCÉ",
"all_filter": "Tout",
"allow_custom_fees": "Autoriser les frais personnalisés",
"amount": "Montant",
"amount_details": "DÉTAILS DU MONTANT",
"amount_exceeds_balance": "Le montant dépasse le solde",
"transaction_sent": "Transaction envoyée avec succès"
"amount_label": "Montant :",
"appearance": "APPARENCE",
"auto_shield": "Auto-blindage du minage",
"available": "Disponible",
"backup_backing_up": "Sauvegarde en cours...",
"backup_create": "Créer une sauvegarde",
"backup_created": "Sauvegarde du portefeuille créée",
"backup_data": "SAUVEGARDE & DONNÉES",
"backup_description": "Créez une sauvegarde de votre fichier wallet.dat. Ce fichier contient toutes vos clés privées et l'historique des transactions. Conservez la sauvegarde dans un endroit sûr.",
"backup_destination": "Destination de sauvegarde :",
"backup_source": "Source : %s",
"backup_tip_external": "Stockez les sauvegardes sur des disques externes ou un stockage cloud",
"backup_tip_multiple": "Créez plusieurs sauvegardes à différents endroits",
"backup_tip_test": "Testez périodiquement la restauration à partir de la sauvegarde",
"backup_tips": "Conseils :",
"backup_title": "Sauvegarder le portefeuille",
"backup_wallet": "Sauvegarder le portefeuille...",
"backup_wallet_not_found": "Attention : wallet.dat introuvable à l'emplacement prévu",
"balance": "Solde",
"balance_layout": "Disposition du solde",
"ban": "Bannir",
"banned_peers": "Pairs bannis",
"block": "Bloc",
"block_bits": "Bits :",
"block_click_copy": "Cliquez pour copier",
"block_click_next": "Cliquez pour voir le bloc suivant",
"block_click_prev": "Cliquez pour voir le bloc précédent",
"block_explorer": "Explorateur de blocs",
"block_get_info": "Obtenir les infos du bloc",
"block_hash": "Hash du bloc :",
"block_hash_copied": "Hash de bloc copié",
"block_height": "Hauteur du bloc :",
"block_info_title": "Informations sur le bloc",
"block_merkle_root": "Racine de Merkle :",
"block_nav_next": "Suivant >>",
"block_nav_prev": "<< Précédent",
"block_next": "Bloc suivant :",
"block_previous": "Bloc précédent :",
"block_size": "Taille :",
"block_timestamp": "Horodatage :",
"block_transactions": "Transactions :",
"blockchain_syncing": "Synchronisation de la blockchain (%.1f%%)... Les soldes peuvent être inexacts.",
"cancel": "Annuler",
"characters": "caractères",
"clear": "Effacer",
"clear_all_bans": "Lever tous les bannissements",
"clear_anyway": "Effacer quand même",
"clear_form_confirm": "Effacer tous les champs du formulaire ?",
"clear_request": "Effacer la demande",
"click_copy_address": "Cliquez pour copier l'adresse",
"click_copy_uri": "Cliquez pour copier l'URI",
"click_to_copy": "Cliquez pour copier",
"close": "Fermer",
"conf_count": "%d conf.",
"confirm_and_send": "Confirmer & Envoyer",
"confirm_clear_ztx_title": "Confirmer l'effacement de l'historique Z-Tx",
"confirm_clear_ztx_warning1": "L'effacement de l'historique des z-transactions peut faire apparaître votre solde blindé à 0 jusqu'à ce qu'un rescan du portefeuille soit effectué.",
"confirm_clear_ztx_warning2": "Si cela se produit, vous devrez réimporter les clés privées de votre adresse z avec le rescan activé pour récupérer votre solde.",
"confirm_send": "Confirmer l'envoi",
"confirm_transaction": "Confirmer la transaction",
"confirmations": "Confirmations",
"confirmations_display": "%d confirmations | %s",
"confirmed": "Confirmé",
"connected": "Connecté",
"connected_peers": "Pairs connectés",
"connecting": "Connexion...",
"console": "Console",
"console_auto_scroll": "Défilement auto",
"console_available_commands": "Commandes disponibles :",
"console_capturing_output": "Capture de la sortie du daemon...",
"console_clear": "Effacer",
"console_clear_console": "Effacer la console",
"console_cleared": "Console effacée",
"console_click_commands": "Cliquez sur les commandes ci-dessus pour les insérer",
"console_click_insert": "Cliquez pour insérer",
"console_click_insert_params": "Cliquez pour insérer avec paramètres",
"console_close": "Fermer",
"console_commands": "Commandes",
"console_common_rpc": "Commandes RPC courantes :",
"console_completions": "Complétions :",
"console_connected": "Connecté au daemon",
"console_copy_all": "Tout copier",
"console_copy_selected": "Copier",
"console_daemon": "Daemon",
"console_daemon_error": "Erreur du daemon !",
"console_daemon_started": "Daemon démarré",
"console_daemon_stopped": "Daemon arrêté",
"console_disconnected": "Déconnecté du daemon",
"console_errors": "Erreurs",
"console_filter_hint": "Filtrer la sortie...",
"console_help_clear": " clear - Effacer la console",
"console_help_getbalance": " getbalance - Afficher le solde transparent",
"console_help_getblockcount": " getblockcount - Afficher la hauteur de bloc actuelle",
"console_help_getinfo": " getinfo - Afficher les infos du nœud",
"console_help_getmininginfo": " getmininginfo - Afficher le statut du minage",
"console_help_getpeerinfo": " getpeerinfo - Afficher les pairs connectés",
"console_help_gettotalbalance": " gettotalbalance - Afficher le solde total",
"console_help_help": " help - Afficher ce message d'aide",
"console_help_setgenerate": " setgenerate - Contrôler le minage",
"console_help_stop": " stop - Arrêter le daemon",
"console_line_count": "%zu lignes",
"console_new_lines": "%d nouvelles lignes",
"console_no_daemon": "Pas de daemon",
"console_not_connected": "Erreur : Non connecté au daemon",
"console_rpc_reference": "Référence des commandes RPC",
"console_scanline": "Scanline de la console",
"console_search_commands": "Rechercher des commandes...",
"console_select_all": "Tout sélectionner",
"console_show_daemon_output": "Afficher la sortie du daemon",
"console_show_errors_only": "Afficher uniquement les erreurs",
"console_show_rpc_ref": "Afficher la référence des commandes RPC",
"console_showing_lines": "Affichage de %zu sur %zu lignes",
"console_starting_node": "Démarrage du nœud...",
"console_status_error": "Erreur",
"console_status_running": "En cours",
"console_status_starting": "Démarrage",
"console_status_stopped": "Arrêté",
"console_status_stopping": "Arrêt",
"console_status_unknown": "Inconnu",
"console_tab_completion": "Tab pour compléter",
"console_type_help": "Tapez 'help' pour les commandes disponibles",
"console_welcome": "Bienvenue dans la console ObsidianDragon",
"console_zoom_in": "Agrandir",
"console_zoom_out": "Réduire",
"copy": "Copier",
"copy_address": "Copier l'adresse complète",
"copy_error": "Copier l'erreur",
"copy_to_clipboard": "Copier dans le presse-papiers",
"copy_txid": "Copier le TxID",
"copy_uri": "Copier l'URI",
"current_price": "Prix actuel",
"custom_fees": "Frais personnalisés",
"dark": "Sombre",
"date": "Date",
"date_label": "Date :",
"debug_logging": "JOURNALISATION DE DÉBOGAGE",
"delete": "Supprimer",
"difficulty": "Difficulté",
"disconnected": "Déconnecté",
"dismiss": "Ignorer",
"display": "Affichage",
"dragonx_green": "DragonX (Vert)",
"edit": "Modifier",
"error": "Erreur",
"error_format": "Erreur : %s",
"est_time_to_block": "Temps est. par bloc",
"exit": "Quitter",
"explorer": "EXPLORATEUR",
"export": "Exporter",
"export_csv": "Exporter en CSV",
"export_keys_btn": "Exporter les clés",
"export_keys_danger": "DANGER : Ceci exportera TOUTES les clés privées de votre portefeuille ! Toute personne ayant accès à ce fichier peut voler vos fonds. Conservez-le en sécurité et supprimez-le après utilisation.",
"export_keys_include_t": "Inclure les adresses T (transparentes)",
"export_keys_include_z": "Inclure les adresses Z (blindées)",
"export_keys_options": "Options d'exportation :",
"export_keys_progress": "Exportation %d/%d...",
"export_keys_success": "Clés exportées avec succès",
"export_keys_title": "Exporter toutes les clés privées",
"export_private_key": "Exporter la clé privée",
"export_tx_count": "Exporter %zu transactions en fichier CSV.",
"export_tx_file_fail": "Impossible de créer le fichier CSV",
"export_tx_none": "Aucune transaction à exporter",
"export_tx_success": "Transactions exportées avec succès",
"export_tx_title": "Exporter les transactions en CSV",
"export_viewing_key": "Exporter la clé de visualisation",
"failed_create_shielded": "Échec de la création de l'adresse blindée",
"failed_create_transparent": "Échec de la création de l'adresse transparente",
"favorite_address": "Ajouter aux favoris",
"fee": "Frais",
"fee_high": "Élevés",
"fee_label": "Frais :",
"fee_low": "Faibles",
"fee_normal": "Normal",
"fetch_prices": "Récupérer les prix",
"file": "Fichier",
"file_save_location": "Le fichier sera enregistré dans : ~/.config/ObsidianDragon/",
"font_scale": "Taille de police",
"from": "De",
"from_upper": "DE",
"full_details": "Tous les détails",
"general": "Général",
"go_to_receive": "Aller à Recevoir",
"height": "Hauteur",
"help": "Aide",
"hide": "Masquer",
"hide_address": "Masquer l'adresse",
"hide_zero_balances": "Masquer les soldes à 0",
"history": "Historique",
"immature_type": "Immature",
"import": "Importer",
"import_key_btn": "Importer clé(s)",
"import_key_formats": "Formats de clés pris en charge :",
"import_key_full_rescan": "(0 = rescan complet)",
"import_key_label": "Clé(s) privée(s) :",
"import_key_no_valid": "Aucune clé valide trouvée dans l'entrée",
"import_key_progress": "Importation %d/%d...",
"import_key_rescan": "Re-scanner la blockchain après l'importation",
"import_key_start_height": "Hauteur de départ :",
"import_key_success": "Clés importées avec succès",
"import_key_t_format": "Clés privées WIF d'adresses T",
"import_key_title": "Importer une clé privée",
"import_key_tooltip": "Entrez une ou plusieurs clés privées, une par ligne.\nPrend en charge les clés z-adresse et t-adresse.\nLes lignes commençant par # sont traitées comme des commentaires.",
"import_key_warning": "Attention : Ne partagez jamais vos clés privées ! L'importation de clés provenant de sources non fiables peut compromettre votre portefeuille.",
"import_key_z_format": "Clés de dépenses z-adresse (secret-extended-key-...)",
"import_private_key": "Importer une clé privée...",
"invalid_address": "Format d'adresse invalide",
"ip_address": "Adresse IP",
"keep": "Conserver",
"keep_daemon": "Garder le daemon en marche",
"key_export_click_retrieve": "Cliquez pour récupérer la clé de votre portefeuille",
"key_export_fetching": "Récupération de la clé depuis le portefeuille...",
"key_export_private_key": "Clé privée :",
"key_export_private_warning": "Gardez cette clé SECRÈTE ! Toute personne possédant cette clé peut dépenser vos fonds. Ne la partagez jamais en ligne ou avec des tiers non fiables.",
"key_export_reveal": "Révéler la clé",
"key_export_viewing_key": "Clé de visualisation :",
"key_export_viewing_keys_zonly": "Les clés de visualisation ne sont disponibles que pour les adresses blindées (z)",
"key_export_viewing_warning": "Cette clé de visualisation permet à d'autres de voir vos transactions entrantes et votre solde, mais PAS de dépenser vos fonds. Ne la partagez qu'avec des personnes de confiance.",
"label": "Libellé :",
"language": "Langue",
"light": "Clair",
"loading": "Chargement...",
"loading_addresses": "Chargement des adresses...",
"local_hashrate": "Hashrate local",
"low_spec_mode": "Mode économie",
"market": "Marché",
"market_12h": "12h",
"market_18h": "18h",
"market_24h": "24h",
"market_24h_volume": "VOLUME 24H",
"market_6h": "6h",
"market_attribution": "Données de prix de NonKYC",
"market_btc_price": "PRIX BTC",
"market_cap": "Capitalisation",
"market_no_history": "Aucun historique de prix disponible",
"market_no_price": "Pas de données de prix",
"market_now": "Maintenant",
"market_pct_shielded": "%.0f%% Blindé",
"market_portfolio": "PORTEFEUILLE",
"market_price_unavailable": "Données de prix indisponibles",
"market_refresh_price": "Actualiser les données de prix",
"market_trade_on": "Échanger sur %s",
"mature": "Mature",
"max": "Max",
"memo": "Mémo (optionnel, chiffré)",
"memo_label": "Mémo :",
"memo_optional": "MÉMO (OPTIONNEL)",
"memo_upper": "MÉMO",
"memo_z_only": "Note : Les mémos ne sont disponibles que lors de l'envoi vers des adresses blindées (z)",
"merge_description": "Fusionnez plusieurs UTXOs en une seule adresse blindée. Cela peut réduire la taille du portefeuille et améliorer la confidentialité.",
"merge_funds": "Fusionner les fonds",
"merge_started": "Opération de fusion démarrée",
"merge_title": "Fusionner vers une adresse",
"mine_when_idle": "Miner au repos",
"mined": "miné",
"mined_filter": "Miné",
"mined_type": "Miné",
"mined_upper": "MINÉ",
"miner_fee": "Frais de mineur",
"mining": "Minage",
"mining_active": "Actif",
"mining_address_copied": "Adresse de minage copiée",
"mining_all_time": "Tout le temps",
"mining_already_saved": "URL du pool déjà enregistrée",
"mining_block_copied": "Hash du bloc copié",
"mining_chart_1m_ago": "il y a 1m",
"mining_chart_5m_ago": "il y a 5m",
"mining_chart_now": "Maintenant",
"mining_chart_start": "Début",
"mining_click": "Cliquer",
"mining_click_copy_address": "Cliquez pour copier l'adresse",
"mining_click_copy_block": "Cliquez pour copier le hash du bloc",
"mining_click_copy_difficulty": "Cliquez pour copier la difficulté",
"mining_connected": "Connecté",
"mining_connecting": "Connexion...",
"mining_control": "Contrôle du minage",
"mining_difficulty_copied": "Difficulté copiée",
"mining_est_block": "Bloc est.",
"mining_est_daily": "Est. quotidien",
"mining_filter_all": "Tout",
"mining_filter_tip_all": "Afficher tous les gains",
"mining_filter_tip_pool": "Afficher uniquement les gains du pool",
"mining_filter_tip_solo": "Afficher uniquement les gains solo",
"mining_idle_off_tooltip": "Activer le minage au repos",
"mining_idle_on_tooltip": "Désactiver le minage au repos",
"mining_local_hashrate": "Hashrate local",
"mining_mine": "Miner",
"mining_mining_addr": "Adr. minage",
"mining_network": "Réseau",
"mining_no_blocks_yet": "Aucun bloc trouvé pour l'instant",
"mining_no_payouts_yet": "Aucun paiement de pool pour l'instant",
"mining_no_saved_addresses": "Aucune adresse enregistrée",
"mining_no_saved_pools": "Aucun pool enregistré",
"mining_off": "Le minage est DÉSACTIVÉ",
"mining_on": "Le minage est ACTIVÉ",
"mining_open_in_explorer": "Ouvrir dans l'explorateur",
"mining_payout_address": "Adresse de paiement",
"mining_payout_tooltip": "Adresse pour recevoir les récompenses de minage",
"mining_pool": "Pool",
"mining_pool_hashrate": "Hashrate du pool",
"mining_pool_url": "URL du pool",
"mining_recent_blocks": "BLOCS RÉCENTS",
"mining_recent_payouts": "PAIEMENTS DE POOL RÉCENTS",
"mining_remove": "Supprimer",
"mining_reset_defaults": "Réinitialiser les paramètres",
"mining_save_payout_address": "Enregistrer l'adresse de paiement",
"mining_save_pool_url": "Enregistrer l'URL du pool",
"mining_saved_addresses": "Adresses enregistrées :",
"mining_saved_pools": "Pools enregistrés :",
"mining_shares": "Parts",
"mining_show_chart": "Graphique",
"mining_show_log": "Journal",
"mining_solo": "Solo",
"mining_starting": "Démarrage...",
"mining_starting_tooltip": "Le mineur démarre...",
"mining_statistics": "Statistiques de minage",
"mining_stop": "Arrêter",
"mining_stop_solo_for_pool": "Arrêtez le minage solo avant de démarrer le minage en pool",
"mining_stop_solo_for_pool_settings": "Arrêtez le minage solo pour modifier les paramètres du pool",
"mining_stopping": "Arrêt...",
"mining_stopping_tooltip": "Le mineur s'arrête...",
"mining_syncing_tooltip": "La blockchain se synchronise...",
"mining_threads": "Threads de minage",
"mining_to_save": "pour enregistrer",
"mining_today": "Aujourd'hui",
"mining_uptime": "Temps de fonctionnement",
"mining_yesterday": "Hier",
"network": "Réseau",
"network_fee": "FRAIS RÉSEAU",
"network_hashrate": "Hashrate du réseau",
"new": "+ Nouveau",
"new_shielded_created": "Nouvelle adresse blindée créée",
"new_t_address": "Nouvelle adresse T",
"new_t_transparent": "Nouvelle adresse t (Transparente)",
"new_transparent_created": "Nouvelle adresse transparente créée",
"new_z_address": "Nouvelle adresse Z",
"new_z_shielded": "Nouvelle adresse z (Blindée)",
"no_addresses": "Aucune adresse trouvée. Créez-en une avec les boutons ci-dessus.",
"no_addresses_available": "Aucune adresse disponible",
"no_addresses_match": "Aucune adresse ne correspond au filtre",
"no_addresses_with_balance": "Aucune adresse avec solde",
"no_matching": "Aucune transaction correspondante",
"no_recent_receives": "Aucune réception récente",
"no_recent_sends": "Aucun envoi récent",
"no_transactions": "Aucune transaction trouvée",
"node": "NŒUD",
"node_security": "NŒUD & SÉCURITÉ",
"noise": "Bruit",
"not_connected": "Non connecté au daemon...",
"not_connected_to_daemon": "Non connecté au daemon",
"notes": "Notes",
"notes_optional": "Notes (optionnel) :",
"output_filename": "Nom du fichier de sortie :",
"overview": "Aperçu",
"paste": "Coller",
"paste_from_clipboard": "Coller depuis le presse-papiers",
"pay_from": "Payer depuis",
"payment_request": "DEMANDE DE PAIEMENT",
"payment_request_copied": "Demande de paiement copiée",
"payment_uri_copied": "URI de paiement copiée",
"peers": "Pairs",
"peers_avg_ping": "Ping moyen",
"peers_ban_24h": "Bannir le pair 24h",
"peers_ban_score": "Score de ban : %d",
"peers_banned": "Bannis",
"peers_banned_count": "Bannis : %d",
"peers_best_block": "Meilleur bloc",
"peers_blockchain": "BLOCKCHAIN",
"peers_blocks": "Blocs",
"peers_blocks_left": "%d blocs restants",
"peers_clear_all_bans": "Lever tous les bannissements",
"peers_click_copy": "Cliquez pour copier",
"peers_connected": "Connectés",
"peers_connected_count": "Connectés : %d",
"peers_copy_ip": "Copier l'IP",
"peers_dir_in": "Ent.",
"peers_dir_out": "Sort.",
"peers_hash_copied": "Hash copié",
"peers_hashrate": "Hashrate",
"peers_in_out": "Ent./Sort.",
"peers_longest": "Plus longue",
"peers_longest_chain": "Plus longue chaîne",
"peers_memory": "Mémoire",
"peers_no_banned": "Aucun pair banni",
"peers_no_connected": "Aucun pair connecté",
"peers_no_tls": "Pas de TLS",
"peers_notarized": "Notarisé",
"peers_p2p_port": "Port P2P",
"peers_peer_label": "Pair : %s",
"peers_protocol": "Protocole",
"peers_received": "Reçu",
"peers_refresh": "Actualiser",
"peers_refresh_tooltip": "Actualiser la liste des pairs",
"peers_refreshing": "Actualisation...",
"peers_sent": "Envoyé",
"peers_tt_id": "ID : %d",
"peers_tt_received": "Reçu : %s",
"peers_tt_sent": "Envoyé : %s",
"peers_tt_services": "Services : %s",
"peers_tt_start_height": "Hauteur de départ : %d",
"peers_tt_synced": "Synchronisé H/B : %d/%d",
"peers_tt_tls_cipher": "TLS : %s",
"peers_unban": "Débannir",
"peers_upper": "PAIRS",
"peers_version": "Version",
"pending": "En attente",
"ping": "Ping",
"price_chart": "Graphique des prix",
"qr_code": "Code QR",
"qr_failed": "Échec de la génération du code QR",
"qr_title": "Code QR",
"qr_unavailable": "QR indisponible",
"ram_daemon_gb": "Daemon : %.1f Go (%s)",
"ram_daemon_mb": "Daemon : %.0f Mo (%s)",
"ram_system_gb": "Système : %.1f / %.0f Go",
"ram_wallet_gb": "Portefeuille : %.1f Go",
"ram_wallet_mb": "Portefeuille : %.0f Mo",
"receive": "Recevoir",
"received": "reçu",
"received_filter": "Reçu",
"received_label": "Reçu",
"received_upper": "REÇU",
"receiving_addresses": "Vos adresses de réception",
"recent_received": "REÇUS RÉCENTS",
"recent_sends": "ENVOIS RÉCENTS",
"recipient": "DESTINATAIRE",
"recv_type": "Reçu",
"refresh": "Actualiser",
"refresh_now": "Actualiser maintenant",
"remove_favorite": "Retirer des favoris",
"report_bug": "Signaler un bug",
"request_amount": "Montant (optionnel) :",
"request_copy_uri": "Copier l'URI",
"request_description": "Générez une demande de paiement que d'autres peuvent scanner ou copier. Le code QR contient votre adresse et un montant/mémo optionnel.",
"request_label": "Libellé (optionnel) :",
"request_memo": "Mémo (optionnel) :",
"request_payment": "Demander un paiement",
"request_payment_uri": "URI de paiement :",
"request_receive_address": "Adresse de réception :",
"request_select_address": "Sélectionner une adresse...",
"request_shielded_addrs": "-- Adresses blindées --",
"request_title": "Demander un paiement",
"request_transparent_addrs": "-- Adresses transparentes --",
"request_uri_copied": "URI de paiement copiée dans le presse-papiers",
"rescan": "Re-scanner",
"reset_to_defaults": "Réinitialiser les paramètres",
"restore_address": "Restaurer l'adresse",
"review_send": "Vérifier l'envoi",
"rpc_host": "Hôte RPC",
"rpc_pass": "Mot de passe",
"rpc_port": "Port",
"rpc_user": "Nom d'utilisateur",
"save": "Enregistrer",
"save_settings": "Enregistrer les paramètres",
"save_z_transactions": "Enregistrer les Z-tx dans la liste",
"search_placeholder": "Rechercher...",
"security": "SÉCURITÉ",
"select_address": "Sélectionner une adresse...",
"select_receiving_address": "Sélectionner une adresse de réception...",
"select_source_address": "Sélectionner une adresse source...",
"send": "Envoyer",
"send_amount": "Montant",
"send_amount_details": "DÉTAILS DU MONTANT",
"send_amount_upper": "MONTANT",
"send_clear_fields": "Effacer tous les champs du formulaire ?",
"send_copy_error": "Copier l'erreur",
"send_dismiss": "Ignorer",
"send_error_copied": "Erreur copiée dans le presse-papiers",
"send_error_prefix": "Erreur : %s",
"send_exceeds_available": "Dépasse le disponible (%.8f)",
"send_fee": "Frais",
"send_fee_high": "Élevés",
"send_fee_low": "Faibles",
"send_fee_normal": "Normal",
"send_form_restored": "Formulaire restauré",
"send_from_this_address": "Envoyer depuis cette adresse",
"send_go_to_receive": "Aller à Recevoir",
"send_keep": "Conserver",
"send_network_fee": "FRAIS RÉSEAU",
"send_no_balance": "Pas de solde",
"send_no_recent": "Aucun envoi récent",
"send_recent_sends": "ENVOIS RÉCENTS",
"send_recipient": "DESTINATAIRE",
"send_select_source": "Sélectionner une adresse source...",
"send_sending_from": "ENVOI DEPUIS",
"send_submitting": "Soumission de la transaction...",
"send_switch_to_receive": "Passez à Recevoir pour obtenir votre adresse et commencer à recevoir des fonds.",
"send_to": "Envoyer à",
"send_tooltip_enter_amount": "Entrez un montant à envoyer",
"send_tooltip_exceeds_balance": "Le montant dépasse le solde disponible",
"send_tooltip_in_progress": "Transaction déjà en cours",
"send_tooltip_invalid_address": "Entrez une adresse de destinataire valide",
"send_tooltip_not_connected": "Non connecté au daemon",
"send_tooltip_select_source": "Sélectionnez d'abord une adresse source",
"send_tooltip_syncing": "Attendez la synchronisation de la blockchain",
"send_total": "Total",
"send_transaction": "Envoyer la transaction",
"send_tx_failed": "Transaction échouée",
"send_tx_sent": "Transaction envoyée !",
"send_tx_success": "Transaction envoyée avec succès !",
"send_txid_copied": "TxID copié dans le presse-papiers",
"send_txid_label": "TxID : %s",
"send_valid_shielded": "Adresse blindée valide",
"send_valid_transparent": "Adresse transparente valide",
"send_wallet_empty": "Votre portefeuille est vide",
"send_yes_clear": "Oui, effacer",
"sending": "Envoi de la transaction",
"sending_from": "ENVOI DEPUIS",
"sent": "envoyé",
"sent_filter": "Envoyé",
"sent_type": "Envoyé",
"sent_upper": "ENVOYÉ",
"settings": "Paramètres",
"settings_about_text": "Un portefeuille de cryptomonnaie blindé pour DragonX (DRGX), construit avec Dear ImGui pour une expérience légère et portable.",
"settings_acrylic_level": "Niveau acrylique :",
"settings_address_book": "Carnet d'adresses...",
"settings_auto_detected": "Détecté automatiquement depuis DRAGONX.conf",
"settings_auto_lock": "VERROUILLAGE AUTO",
"settings_auto_shield_desc": "Déplacer automatiquement les fonds transparents vers des adresses blindées",
"settings_auto_shield_funds": "Blindage automatique des fonds transparents",
"settings_backup": "Sauvegarde...",
"settings_block_explorer_urls": "URLs de l'explorateur de blocs",
"settings_builtin": "Intégré",
"settings_change_passphrase": "Changer la phrase secrète",
"settings_change_pin": "Changer le PIN",
"settings_clear_ztx": "Effacer l'historique Z-Tx",
"settings_clear_ztx_desc": "Supprimer les données de transactions blindées stockées localement",
"settings_clear_ztx_long": "Effacer l'historique sauvegardé des Z-transactions",
"settings_configure_explorer": "Configurer les liens vers l'explorateur de blocs externe",
"settings_configure_rpc": "Configurer la connexion au daemon dragonxd",
"settings_connection": "Connexion",
"settings_copyright": "Copyright 2024-2026 Développeurs DragonX | Licence GPLv3",
"settings_custom": "Personnalisé",
"settings_data_dir": "Rép. de données :",
"settings_debug_changed": "Catégories de débogage modifiées — redémarrez le daemon pour appliquer",
"settings_debug_restart_note": "Les modifications prennent effet après le redémarrage du daemon.",
"settings_debug_select": "Sélectionnez les catégories pour activer la journalisation de débogage du daemon (flags -debug=).",
"settings_encrypt_first_pin": "Chiffrez d'abord le portefeuille pour activer le PIN",
"settings_encrypt_wallet": "Chiffrer le portefeuille",
"settings_explorer_hint": "Les URLs doivent inclure une barre oblique finale. Le txid/adresse sera ajouté.",
"settings_export_all": "Tout exporter...",
"settings_export_csv": "Exporter CSV...",
"settings_export_key": "Exporter la clé...",
"settings_gradient_bg": "Fond dégradé",
"settings_gradient_desc": "Remplacer les arrière-plans texturés par des dégradés lisses",
"settings_idle_after": "après",
"settings_import_key": "Importer la clé...",
"settings_language_note": "Remarque : Certains textes nécessitent un redémarrage pour se mettre à jour",
"settings_lock_now": "Verrouiller maintenant",
"settings_locked": "Verrouillé",
"settings_merge_to_address": "Fusionner vers l'adresse...",
"settings_noise_opacity": "Opacité du bruit :",
"settings_not_encrypted": "Non chiffré",
"settings_not_found": "Non trouvé",
"settings_other": "Autres",
"settings_pin_active": "PIN",
"settings_privacy": "Confidentialité",
"settings_quick_unlock_pin": "PIN de déverrouillage rapide",
"settings_reduce_transparency": "Réduire la transparence",
"settings_remove_encryption": "Supprimer le chiffrement",
"settings_remove_pin": "Supprimer le PIN",
"settings_request_payment": "Demander un paiement...",
"settings_rescan_desc": "Rescanner la blockchain pour les transactions manquantes",
"settings_restart_daemon": "Redémarrer le daemon",
"settings_rpc_connection": "Connexion RPC",
"settings_rpc_note": "Remarque : Les paramètres de connexion sont généralement détectés automatiquement depuis DRAGONX.conf",
"settings_save_shielded_desc": "Stocke les transactions z-addr dans un fichier local pour consultation",
"settings_save_shielded_local": "Enregistrer l'historique des transactions blindées localement",
"settings_set_pin": "Définir le PIN",
"settings_shield_mining": "Blindage minage...",
"settings_solid_colors_desc": "Utiliser des couleurs unies au lieu des effets de flou (accessibilité)",
"settings_tor_desc": "Acheminer toutes les connexions via Tor pour une confidentialité renforcée",
"settings_unlocked": "Déverrouillé",
"settings_use_tor_network": "Utiliser Tor pour les connexions réseau",
"settings_validate_address": "Valider l'adresse...",
"settings_visual_effects": "Effets visuels",
"settings_wallet_file_size": "Taille du fichier portefeuille : %s",
"settings_wallet_info": "Informations du portefeuille",
"settings_wallet_location": "Emplacement du portefeuille : %s",
"settings_wallet_maintenance": "Maintenance du portefeuille",
"settings_wallet_not_found": "Fichier portefeuille introuvable",
"settings_wallet_size_label": "Taille du portefeuille :",
"setup_wizard": "Assistant de configuration",
"share": "Partager",
"shield_check_status": "Vérifier le statut",
"shield_completed": "Opération terminée avec succès !",
"shield_description": "Blindez vos récompenses de minage en envoyant les sorties coinbase des adresses transparentes vers une adresse blindée. Cela améliore la confidentialité en masquant vos revenus de minage.",
"shield_from_address": "Depuis l'adresse :",
"shield_funds": "Blinder les fonds",
"shield_in_progress": "Opération en cours...",
"shield_max_utxos": "UTXOs max par opération",
"shield_merge_done": "Blindage/fusion terminé !",
"shield_operation_id": "ID d'opération : %s",
"shield_select_z": "Sélectionner une z-adresse...",
"shield_started": "Opération de blindage démarrée",
"shield_title": "Blinder les récompenses coinbase",
"shield_to_address": "Vers l'adresse (blindée) :",
"shield_utxo_limit": "Limite UTXO :",
"shield_wildcard_hint": "Utilisez '*' pour blinder depuis toutes les adresses transparentes",
"shielded": "Blindé",
"shielded_to": "BLINDÉ VERS",
"shielded_type": "Blindé",
"show": "Afficher",
"show_hidden": "Afficher masqués (%d)",
"show_qr_code": "Afficher le code QR",
"showing_transactions": "Affichage %d–%d sur %d transactions (total : %zu)",
"simple_background": "Arrière-plan simple",
"start_mining": "Démarrer le minage",
"status": "Statut",
"stop_external": "Arrêter le daemon externe",
"stop_mining": "Arrêter le minage",
"submitting_transaction": "Soumission de la transaction...",
"success": "Succès",
"summary": "Résumé",
"syncing": "Synchronisation...",
"t_addresses": "Adresses T",
"test_connection": "Tester",
"theme": "Thème",
"theme_effects": "Effets de thème",
"time_days_ago": "il y a %d jours",
"time_hours_ago": "il y a %d heures",
"time_minutes_ago": "il y a %d minutes",
"time_seconds_ago": "il y a %d secondes",
"to": "À",
"to_upper": "À",
"tools": "OUTILS",
"total": "Total",
"transaction_id": "ID DE TRANSACTION",
"transaction_sent": "Transaction envoyée avec succès",
"transaction_sent_msg": "Transaction envoyée !",
"transaction_url": "URL de transaction",
"transactions": "Transactions",
"transactions_upper": "TRANSACTIONS",
"transparent": "Transparent",
"tt_addr_url": "URL de base pour consulter les adresses dans un explorateur de blocs",
"tt_address_book": "Gérer les adresses enregistrées pour un envoi rapide",
"tt_auto_lock": "Verrouiller le portefeuille après cette durée d'inactivité",
"tt_auto_shield": "Déplacer automatiquement le solde transparent vers des adresses blindées pour la confidentialité",
"tt_backup": "Créer une sauvegarde de votre wallet.dat",
"tt_block_explorer": "Ouvrir l'explorateur de blocs DragonX dans votre navigateur",
"tt_blur": "Quantité de flou (0%% = désactivé, 100%% = maximum)",
"tt_change_pass": "Changer la phrase secrète de chiffrement du portefeuille",
"tt_change_pin": "Changer votre PIN de déverrouillage",
"tt_clear_ztx": "Supprimer l'historique des z-transactions mis en cache localement",
"tt_custom_fees": "Activer la saisie manuelle des frais lors de l'envoi de transactions",
"tt_custom_theme": "Thème personnalisé actif",
"tt_debug_collapse": "Réduire les options de journalisation de débogage",
"tt_debug_expand": "Développer les options de journalisation de débogage",
"tt_encrypt": "Chiffrer wallet.dat avec une phrase secrète",
"tt_export_all": "Exporter toutes les clés privées dans un fichier",
"tt_export_csv": "Exporter l'historique des transactions en feuille de calcul CSV",
"tt_export_key": "Exporter la clé privée de l'adresse sélectionnée",
"tt_fetch_prices": "Récupérer les prix du marché DRGX depuis l'API CoinGecko",
"tt_font_scale": "Mettre à l'échelle tout le texte et l'interface (1.0x = par défaut, jusqu'à 1.5x).",
"tt_idle_delay": "Combien de temps attendre avant de commencer le minage",
"tt_import_key": "Importer une clé privée (zkey ou tkey) dans ce portefeuille",
"tt_keep_daemon": "Le daemon s'arrêtera lors de l'exécution de l'assistant de configuration",
"tt_language": "Langue de l'interface du portefeuille",
"tt_layout_hotkey": "Raccourci : touches fléchées gauche/droite pour changer les dispositions de Balance",
"tt_lock": "Verrouiller le portefeuille immédiatement",
"tt_low_spec": "Désactiver tous les effets visuels lourds\\nRaccourci : Ctrl+Shift+Down",
"tt_merge": "Consolider plusieurs UTXOs vers une adresse",
"tt_mine_idle": "Démarrer le minage automatiquement quand le\\nsystème est inactif (aucune entrée clavier/souris)",
"tt_noise": "Intensité de texture grainée (0%% = désactivé, 100%% = maximum)",
"tt_open_dir": "Cliquer pour ouvrir dans l'explorateur de fichiers",
"tt_remove_encrypt": "Supprimer le chiffrement et stocker le portefeuille sans protection",
"tt_remove_pin": "Supprimer le PIN et exiger la phrase secrète pour déverrouiller",
"tt_report_bug": "Signaler un problème dans le suivi de projet",
"tt_request_payment": "Générer une demande de paiement avec code QR",
"tt_rescan": "Rescanner la blockchain pour les transactions manquantes",
"tt_reset_settings": "Recharger les paramètres depuis le disque (annuler les modifications non enregistrées)",
"tt_restart_daemon": "Redémarrer le daemon pour appliquer les modifications de journalisation de débogage",
"tt_rpc_host": "Nom d'hôte du daemon DragonX",
"tt_rpc_pass": "Mot de passe d'authentification RPC",
"tt_rpc_port": "Port pour les connexions RPC du daemon",
"tt_rpc_user": "Nom d'utilisateur d'authentification RPC",
"tt_save_settings": "Enregistrer tous les paramètres sur le disque",
"tt_save_ztx": "Stocker l'historique des transactions z-address localement pour un chargement plus rapide",
"tt_scan_themes": "Rechercher de nouveaux thèmes.\\nPlacez les dossiers de thèmes dans :\\n%s",
"tt_scanline": "Effet de lignes de balayage CRT dans la console",
"tt_set_pin": "Définir un PIN de 4-8 chiffres pour un déverrouillage rapide",
"tt_shield_mining": "Déplacer les récompenses de minage transparentes vers une adresse blindée",
"tt_simple_bg": "Utiliser un dégradé simple pour l'arrière-plan\\nRaccourci : Ctrl+Up",
"tt_simple_bg_alt": "Utiliser une version dégradée de l'image d'arrière-plan du thème\\nRaccourci : Ctrl+Up",
"tt_stop_external": "S'applique lors de la connexion à un daemon\\ndémarré en dehors de ce portefeuille",
"tt_test_conn": "Vérifier la connexion RPC au daemon",
"tt_theme_effects": "Scintillement, lueur, cycle de teinte par thème",
"tt_theme_hotkey": "Raccourci : Ctrl+Gauche/Droite pour changer de thème",
"tt_tor": "Acheminer les connexions du daemon via le réseau Tor pour l'anonymat",
"tt_tx_url": "URL de base pour consulter les transactions dans un explorateur de blocs",
"tt_ui_opacity": "Opacité des cartes et de la barre latérale (100%% = entièrement opaque, plus bas = plus transparent)",
"tt_validate": "Vérifier si une adresse DragonX est valide",
"tt_verbose": "Journaliser les diagnostics de connexion détaillés,\\nl'état du daemon et les informations de propriétaire de port\\ndans l'onglet Console",
"tt_website": "Ouvrir le site web DragonX",
"tt_window_opacity": "Opacité de l'arrière-plan (plus bas = bureau visible à travers la fenêtre)",
"tt_wizard": "Relancer l'assistant de configuration initiale\\nLe daemon sera redémarré",
"tx_confirmations": "%d confirmations",
"tx_details_title": "Détails de la transaction",
"tx_from_address": "Adresse d'origine :",
"tx_id_label": "ID de transaction :",
"tx_immature": "IMMATURE",
"tx_mined": "MINÉ",
"tx_received": "REÇU",
"tx_sent": "ENVOYÉ",
"tx_to_address": "Adresse de destination :",
"tx_view_explorer": "Voir dans l'explorateur",
"txs_count": "%d txs",
"type": "Type",
"ui_opacity": "Opacité de l'interface",
"unban": "Débannir",
"unconfirmed": "Non confirmé",
"undo_clear": "Annuler l'effacement",
"unknown": "Inconnu",
"use_embedded_daemon": "Utiliser le dragonxd intégré",
"use_tor": "Utiliser Tor",
"validate_btn": "Valider",
"validate_description": "Entrez une adresse DragonX pour vérifier si elle est valide et si elle appartient à ce portefeuille.",
"validate_invalid": "INVALIDE",
"validate_is_mine": "Ce portefeuille possède cette adresse",
"validate_not_mine": "N'appartient pas à ce portefeuille",
"validate_ownership": "Propriété :",
"validate_results": "Résultats :",
"validate_shielded_type": "Blindée (z-adresse)",
"validate_status": "Statut :",
"validate_title": "Valider l'adresse",
"validate_transparent_type": "Transparente (t-adresse)",
"validate_type": "Type :",
"validate_valid": "VALIDE",
"validating": "Validation...",
"verbose_logging": "Journalisation détaillée",
"version": "Version",
"view": "Afficher",
"view_details": "Voir les détails",
"view_on_explorer": "Voir dans l'explorateur",
"waiting_for_daemon": "En attente de la connexion au daemon...",
"wallet": "PORTEFEUILLE",
"wallet_empty": "Votre portefeuille est vide",
"wallet_empty_hint": "Passez à Recevoir pour obtenir votre adresse et commencer à recevoir des fonds.",
"warning": "Attention",
"warning_upper": "ATTENTION !",
"website": "Site web",
"window_opacity": "Opacité de la fenêtre",
"yes_clear": "Oui, effacer",
"your_addresses": "Vos adresses",
"z_addresses": "Adresses Z"
}
+790 -134
View File
@@ -1,139 +1,795 @@
{
"balance": "残高",
"send": "送金",
"receive": "受取",
"transactions": "取引履歴",
"mining": "マイニング",
"peers": "ノード",
"market": "マーケット",
"settings": "設定",
"summary": "概要",
"shielded": "シールド",
"transparent": "トランスパレント",
"total": "合計",
"unconfirmed": "未確認",
"your_addresses": "アドレス一覧",
"z_addresses": "Z-アドレス",
"t_addresses": "T-アドレス",
"no_addresses": "アドレスが見つかりません。上のボタンで作成してください。",
"new_z_address": "新規 Z-アドレス",
"new_t_address": "新規 T-アドレス",
"type": "タイプ",
"address": "アドレス",
"copy_address": "アドレスをコピー",
"send_from_this_address": "このアドレスから送金",
"export_private_key": "秘密鍵をエクスポート",
"export_viewing_key": "閲覧鍵をエクスポート",
"show_qr_code": "QRコードを表示",
"not_connected": "デーモンに未接続...",
"pay_from": "支払元",
"send_to": "送金先",
"amount": "金額",
"memo": "メモ(任意、暗号化)",
"miner_fee": "マイナー手数料",
"fee": "手数料",
"send_transaction": "送金する",
"clear": "クリア",
"select_address": "アドレスを選択...",
"paste": "貼り付け",
"max": "最大",
"available": "利用可能",
"invalid_address": "無効なアドレス形式",
"memo_z_only": "注:メモはシールド(z)アドレスへの送金時のみ利用可能です",
"characters": "文字",
"from": "送金元",
"to": "送金先",
"sending": "送金中",
"confirm_send": "送金確認",
"confirm_transaction": "取引確認",
"confirm_and_send": "確認して送金",
"cancel": "キャンセル",
"receiving_addresses": "受取アドレス",
"new_z_shielded": "新規 z-アドレス(シールド)",
"new_t_transparent": "新規 t-アドレス(トランスパレント)",
"address_details": "アドレス詳細",
"view_on_explorer": "エクスプローラーで表示",
"qr_code": "QRコード",
"request_payment": "支払いを要求",
"date": "日付",
"status": "ステータス",
"confirmations": "確認数",
"confirmed": "確認済み",
"pending": "保留中",
"sent": "送金済",
"received": "受取済",
"mined": "採掘済",
"mining_control": "マイニング制御",
"start_mining": "マイニング開始",
"stop_mining": "マイニング停止",
"mining_threads": "マイニングスレッド",
"mining_statistics": "マイニング統計",
"local_hashrate": "ローカルハッシュレート",
"network_hashrate": "ネットワークハッシュレート",
"difficulty": "難易度",
"est_time_to_block": "推定ブロック発見時間",
"mining_off": "マイニング停止中",
"mining_on": "マイニング稼働中",
"connected_peers": "接続中のノード",
"banned_peers": "ブロック済みノード",
"ip_address": "IPアドレス",
"version": "バージョン",
"height": "ブロック高",
"ping": "Ping",
"ban": "ブロック",
"unban": "ブロック解除",
"clear_all_bans": "すべてのブロックを解除",
"price_chart": "価格チャート",
"current_price": "現在価格",
"24h_change": "24時間変動",
"24h_volume": "24時間取引量",
"market_cap": "時価総額",
"general": "一般",
"display": "表示",
"network": "ネットワーク",
"theme": "テーマ",
"language": "言語",
"dragonx_green": "DragonX(グリーン)",
"dark": "ダーク",
"light": "ライト",
"allow_custom_fees": "カスタム手数料を許可",
"use_embedded_daemon": "内蔵 dragonxd を使用",
"save": "保存",
"close": "閉じる",
"file": "ファイル",
"edit": "編集",
"view": "表示",
"help": "ヘルプ",
"import_private_key": "秘密鍵をインポート...",
"backup_wallet": "ウォレットをバックアップ...",
"exit": "終了",
"24h_volume": "24時間出来高",
"about": "概要",
"about_block_explorer": "ブロックエクスプローラー",
"about_block_height": "ブロック高:",
"about_build_date": "ビルド日:",
"about_build_type": "ビルドタイプ:",
"about_chain": "チェーン:",
"about_connections": "接続数:",
"about_credits": "クレジット",
"about_daemon": "デーモン:",
"about_debug": "デバッグ",
"about_dragonx": "ObsidianDragonについて",
"refresh_now": "今すぐ更新",
"about": "このアプリについて",
"import": "インポート",
"export": "エクスポート",
"copy_to_clipboard": "クリップボードにコピー",
"connected": "接続済み",
"disconnected": "切断",
"connecting": "接続中...",
"syncing": "同期中...",
"block": "ブロック",
"no_addresses_available": "利用可能なアドレスがありません",
"error": "エラー",
"success": "成功",
"warning": "警告",
"about_edition": "ImGui エディション",
"about_github": "GitHub",
"about_imgui": "ImGui:",
"about_license": "ライセンス",
"about_license_text": "本ソフトウェアはGNU General Public License v3 (GPLv3)の下で公開されています。ライセンス条項に従い、自由に使用、変更、配布できます。",
"about_peers_count": "%zu ピア",
"about_release": "リリース",
"about_title": "ObsidianDragonについて",
"about_version": "バージョン:",
"about_website": "ウェブサイト",
"acrylic": "アクリル",
"add": "追加",
"address": "アドレス",
"address_book_add": "アドレスを追加",
"address_book_add_new": "新規追加",
"address_book_added": "アドレスをアドレス帳に追加しました",
"address_book_count": "%zu 件のアドレスを保存済み",
"address_book_deleted": "エントリを削除しました",
"address_book_edit": "アドレスを編集",
"address_book_empty": "保存されたアドレスがありません。「新規追加」をクリックして追加してください。",
"address_book_exists": "アドレスは既にアドレス帳に存在します",
"address_book_title": "アドレス帳",
"address_book_update_failed": "更新に失敗しました — アドレスが重複している可能性があります",
"address_book_updated": "アドレスを更新しました",
"address_copied": "アドレスをクリップボードにコピーしました",
"address_details": "アドレス詳細",
"address_label": "アドレス:",
"address_upper": "アドレス",
"address_url": "アドレスURL",
"addresses_appear_here": "接続後、受信アドレスがここに表示されます。",
"advanced": "詳細設定",
"all_filter": "すべて",
"allow_custom_fees": "カスタム手数料を許可",
"amount": "金額",
"amount_details": "金額の詳細",
"amount_exceeds_balance": "金額が残高を超えています",
"transaction_sent": "送金が完了しました"
"amount_label": "金額:",
"appearance": "外観",
"auto_shield": "マイニング自動シールド",
"available": "利用可能",
"backup_backing_up": "バックアップ中...",
"backup_create": "バックアップを作成",
"backup_created": "ウォレットのバックアップを作成しました",
"backup_data": "バックアップとデータ",
"backup_description": "wallet.datファイルのバックアップを作成します。このファイルにはすべての秘密鍵と取引履歴が含まれています。バックアップは安全な場所に保管してください。",
"backup_destination": "バックアップ先:",
"backup_source": "ソース:%s",
"backup_tip_external": "外部ドライブまたはクラウドストレージにバックアップを保存",
"backup_tip_multiple": "異なる場所に複数のバックアップを作成",
"backup_tip_test": "定期的にバックアップからの復元をテスト",
"backup_tips": "ヒント:",
"backup_title": "ウォレットのバックアップ",
"backup_wallet": "ウォレットをバックアップ...",
"backup_wallet_not_found": "警告:予想される場所にwallet.datが見つかりません",
"balance": "残高",
"balance_layout": "残高レイアウト",
"ban": "ブロック",
"banned_peers": "ブロック済みピア",
"block": "ブロック",
"block_bits": "ビット:",
"block_click_copy": "クリックしてコピー",
"block_click_next": "クリックして次のブロックを表示",
"block_click_prev": "クリックして前のブロックを表示",
"block_explorer": "ブロックエクスプローラー",
"block_get_info": "ブロック情報を取得",
"block_hash": "ブロックハッシュ:",
"block_hash_copied": "ブロックハッシュがコピーされました",
"block_height": "ブロック高:",
"block_info_title": "ブロック情報",
"block_merkle_root": "マークルルート:",
"block_nav_next": "次へ >>",
"block_nav_prev": "<< 前へ",
"block_next": "次のブロック:",
"block_previous": "前のブロック:",
"block_size": "サイズ:",
"block_timestamp": "タイムスタンプ:",
"block_transactions": "トランザクション:",
"blockchain_syncing": "ブロックチェーン同期中 (%.1f%%)... 残高が不正確な場合があります。",
"cancel": "キャンセル",
"characters": "文字",
"clear": "クリア",
"clear_all_bans": "すべてのブロックを解除",
"clear_anyway": "それでもクリア",
"clear_form_confirm": "すべてのフォームフィールドをクリアしますか?",
"clear_request": "リクエストをクリア",
"click_copy_address": "クリックしてアドレスをコピー",
"click_copy_uri": "クリックしてURIをコピー",
"click_to_copy": "クリックしてコピー",
"close": "閉じる",
"conf_count": "%d 確認",
"confirm_and_send": "確認して送金",
"confirm_clear_ztx_title": "Z-Tx 履歴クリアの確認",
"confirm_clear_ztx_warning1": "z-トランザクション履歴をクリアすると、ウォレットの再スキャンが実行されるまでシールド残高が0と表示される場合があります。",
"confirm_clear_ztx_warning2": "これが発生した場合、残高を回復するにはz-アドレスの秘密鍵を再スキャンを有効にして再インポートする必要があります。",
"confirm_send": "送金を確認",
"confirm_transaction": "取引を確認",
"confirmations": "確認数",
"confirmations_display": "%d 確認 | %s",
"confirmed": "確認済み",
"connected": "接続済み",
"connected_peers": "接続中のピア",
"connecting": "接続中...",
"console": "コンソール",
"console_auto_scroll": "自動スクロール",
"console_available_commands": "利用可能なコマンド:",
"console_capturing_output": "デーモン出力をキャプチャ中...",
"console_clear": "クリア",
"console_clear_console": "コンソールをクリア",
"console_cleared": "コンソールをクリアしました",
"console_click_commands": "上のコマンドをクリックして挿入",
"console_click_insert": "クリックして挿入",
"console_click_insert_params": "クリックしてパラメータ付きで挿入",
"console_close": "閉じる",
"console_commands": "コマンド",
"console_common_rpc": "一般的なRPCコマンド:",
"console_completions": "補完:",
"console_connected": "デーモンに接続済み",
"console_copy_all": "すべてコピー",
"console_copy_selected": "コピー",
"console_daemon": "デーモン",
"console_daemon_error": "デーモンエラー!",
"console_daemon_started": "デーモンが起動しました",
"console_daemon_stopped": "デーモンが停止しました",
"console_disconnected": "デーモンから切断されました",
"console_errors": "エラー",
"console_filter_hint": "出力をフィルタ...",
"console_help_clear": " clear - コンソールをクリア",
"console_help_getbalance": " getbalance - 透明残高を表示",
"console_help_getblockcount": " getblockcount - 現在のブロック高を表示",
"console_help_getinfo": " getinfo - ノード情報を表示",
"console_help_getmininginfo": " getmininginfo - マイニング状況を表示",
"console_help_getpeerinfo": " getpeerinfo - 接続中のピアを表示",
"console_help_gettotalbalance": " gettotalbalance - 合計残高を表示",
"console_help_help": " help - このヘルプを表示",
"console_help_setgenerate": " setgenerate - マイニングを制御",
"console_help_stop": " stop - デーモンを停止",
"console_line_count": "%zu 行",
"console_new_lines": "%d 新しい行",
"console_no_daemon": "デーモンなし",
"console_not_connected": "エラー:デーモンに接続されていません",
"console_rpc_reference": "RPCコマンドリファレンス",
"console_scanline": "コンソールスキャンライン",
"console_search_commands": "コマンドを検索...",
"console_select_all": "すべて選択",
"console_show_daemon_output": "デーモン出力を表示",
"console_show_errors_only": "エラーのみ表示",
"console_show_rpc_ref": "RPCコマンドリファレンスを表示",
"console_showing_lines": "%zu / %zu 行を表示中",
"console_starting_node": "ノードを起動中...",
"console_status_error": "エラー",
"console_status_running": "実行中",
"console_status_starting": "起動中",
"console_status_stopped": "停止済み",
"console_status_stopping": "停止中",
"console_status_unknown": "不明",
"console_tab_completion": "Tabで補完",
"console_type_help": "'help'と入力して利用可能なコマンドを表示",
"console_welcome": "ObsidianDragonコンソールへようこそ",
"console_zoom_in": "拡大",
"console_zoom_out": "縮小",
"copy": "コピー",
"copy_address": "完全なアドレスをコピー",
"copy_error": "エラーをコピー",
"copy_to_clipboard": "クリップボードにコピー",
"copy_txid": "TxIDをコピー",
"copy_uri": "URIをコピー",
"current_price": "現在の価格",
"custom_fees": "カスタム手数料",
"dark": "ダーク",
"date": "日付",
"date_label": "日付:",
"debug_logging": "デバッグログ",
"delete": "削除",
"difficulty": "難易度",
"disconnected": "切断済み",
"dismiss": "閉じる",
"display": "表示",
"dragonx_green": "DragonX(グリーン)",
"edit": "編集",
"error": "エラー",
"error_format": "エラー:%s",
"est_time_to_block": "予測ブロック時間",
"exit": "終了",
"explorer": "エクスプローラー",
"export": "エクスポート",
"export_csv": "CSVエクスポート",
"export_keys_btn": "鍵をエクスポート",
"export_keys_danger": "危険:ウォレットからすべての秘密鍵がエクスポートされます!このファイルにアクセスできる人は誰でもあなたの資金を盗めます。安全に保管し、使用後は削除してください。",
"export_keys_include_t": "Tアドレスを含める(透明)",
"export_keys_include_z": "Zアドレスを含める(シールド)",
"export_keys_options": "エクスポートオプション:",
"export_keys_progress": "エクスポート中 %d/%d...",
"export_keys_success": "鍵のエクスポートに成功しました",
"export_keys_title": "すべての秘密鍵をエクスポート",
"export_private_key": "秘密鍵をエクスポート",
"export_tx_count": "%zu件の取引をCSVファイルにエクスポート。",
"export_tx_file_fail": "CSVファイルの作成に失敗しました",
"export_tx_none": "エクスポートする取引がありません",
"export_tx_success": "取引のエクスポートに成功しました",
"export_tx_title": "取引をCSVにエクスポート",
"export_viewing_key": "閲覧鍵をエクスポート",
"failed_create_shielded": "シールドアドレスの作成に失敗しました",
"failed_create_transparent": "透明アドレスの作成に失敗しました",
"favorite_address": "お気に入りに追加",
"fee": "手数料",
"fee_high": "高い",
"fee_label": "手数料:",
"fee_low": "低い",
"fee_normal": "通常",
"fetch_prices": "価格を取得",
"file": "ファイル",
"file_save_location": "ファイルの保存先:~/.config/ObsidianDragon/",
"font_scale": "フォントサイズ",
"from": "送信元",
"from_upper": "送信元",
"full_details": "詳細情報",
"general": "一般",
"go_to_receive": "受信へ移動",
"height": "高さ",
"help": "ヘルプ",
"hide": "非表示",
"hide_address": "アドレスを非表示",
"hide_zero_balances": "残高0を非表示",
"history": "履歴",
"immature_type": "未成熟",
"import": "インポート",
"import_key_btn": "鍵をインポート",
"import_key_formats": "サポートされる鍵形式:",
"import_key_full_rescan": "(0 = 完全再スキャン)",
"import_key_label": "秘密鍵:",
"import_key_no_valid": "入力に有効な鍵が見つかりません",
"import_key_progress": "インポート中 %d/%d...",
"import_key_rescan": "インポート後にブロックチェーンを再スキャン",
"import_key_start_height": "開始高:",
"import_key_success": "鍵のインポートに成功しました",
"import_key_t_format": "TアドレスWIF秘密鍵",
"import_key_title": "秘密鍵をインポート",
"import_key_tooltip": "1行に1つずつ秘密鍵を入力してください。\nzアドレスとtアドレスの鍵の両方に対応しています。\n#で始まる行はコメントとして扱われます。",
"import_key_warning": "警告:秘密鍵を決して共有しないでください!信頼できないソースからの鍵のインポートはウォレットを危険にさらす可能性があります。",
"import_key_z_format": "Zアドレス支出鍵 (secret-extended-key-...)",
"import_private_key": "秘密鍵をインポート...",
"invalid_address": "無効なアドレス形式",
"ip_address": "IPアドレス",
"keep": "保持",
"keep_daemon": "デーモンを実行し続ける",
"key_export_click_retrieve": "クリックしてウォレットからキーを取得",
"key_export_fetching": "ウォレットから鍵を取得中...",
"key_export_private_key": "秘密鍵:",
"key_export_private_warning": "この鍵は秘密にしてください!この鍵を持つ人は誰でもあなたの資金を使えます。オンラインや信頼できない相手と共有しないでください。",
"key_export_reveal": "鍵を表示",
"key_export_viewing_key": "閲覧鍵:",
"key_export_viewing_keys_zonly": "ビューイングキーはシールド (z) アドレスでのみ利用可能です",
"key_export_viewing_warning": "この閲覧鍵を使うと、他者があなたの受信取引と残高を見ることができますが、資金を使うことはできません。信頼できる相手とのみ共有してください。",
"label": "ラベル:",
"language": "言語",
"light": "ライト",
"loading": "読み込み中...",
"loading_addresses": "アドレスを読み込み中...",
"local_hashrate": "ローカルハッシュレート",
"low_spec_mode": "省電力モード",
"market": "市場",
"market_12h": "12時間",
"market_18h": "18時間",
"market_24h": "24時間",
"market_24h_volume": "24時間出来高",
"market_6h": "6時間",
"market_attribution": "価格データ:NonKYC提供",
"market_btc_price": "BTC価格",
"market_cap": "時価総額",
"market_no_history": "価格履歴がありません",
"market_no_price": "価格データなし",
"market_now": "現在",
"market_pct_shielded": "%.0f%% シールド済み",
"market_portfolio": "ポートフォリオ",
"market_price_unavailable": "価格データが利用できません",
"market_refresh_price": "価格データを更新",
"market_trade_on": "%s で取引",
"mature": "成熟済み",
"max": "最大",
"memo": "メモ(任意、暗号化)",
"memo_label": "メモ:",
"memo_optional": "メモ(任意)",
"memo_upper": "メモ",
"memo_z_only": "注:メモはシールド (z) アドレスへの送金時のみ利用可能です",
"merge_description": "複数のUTXOを単一のシールドアドレスに統合します。ウォレットサイズの縮小とプライバシーの向上に役立ちます。",
"merge_funds": "資金を統合",
"merge_started": "統合操作を開始しました",
"merge_title": "アドレスに統合",
"mine_when_idle": "アイドル時にマイニング",
"mined": "採掘済み",
"mined_filter": "採掘済み",
"mined_type": "採掘済み",
"mined_upper": "採掘済み",
"miner_fee": "マイナー手数料",
"mining": "マイニング",
"mining_active": "アクティブ",
"mining_address_copied": "マイニングアドレスをコピーしました",
"mining_all_time": "全期間",
"mining_already_saved": "プールURLは既に保存済みです",
"mining_block_copied": "ブロックハッシュをコピーしました",
"mining_chart_1m_ago": "1分前",
"mining_chart_5m_ago": "5分前",
"mining_chart_now": "現在",
"mining_chart_start": "開始",
"mining_click": "クリック",
"mining_click_copy_address": "クリックしてアドレスをコピー",
"mining_click_copy_block": "クリックしてブロックハッシュをコピー",
"mining_click_copy_difficulty": "クリックして難易度をコピー",
"mining_connected": "接続済み",
"mining_connecting": "接続中...",
"mining_control": "マイニング制御",
"mining_difficulty_copied": "難易度をコピーしました",
"mining_est_block": "予測ブロック",
"mining_est_daily": "予測日収",
"mining_filter_all": "すべて",
"mining_filter_tip_all": "すべての収益を表示",
"mining_filter_tip_pool": "プール収益のみ表示",
"mining_filter_tip_solo": "ソロ収益のみ表示",
"mining_idle_off_tooltip": "アイドルマイニングを有効にする",
"mining_idle_on_tooltip": "アイドルマイニングを無効にする",
"mining_local_hashrate": "ローカルハッシュレート",
"mining_mine": "マイニング",
"mining_mining_addr": "マイニングアドレス",
"mining_network": "ネットワーク",
"mining_no_blocks_yet": "まだブロックが見つかっていません",
"mining_no_payouts_yet": "まだプール支払いがありません",
"mining_no_saved_addresses": "保存されたアドレスがありません",
"mining_no_saved_pools": "保存されたプールがありません",
"mining_off": "マイニングはオフです",
"mining_on": "マイニングはオンです",
"mining_open_in_explorer": "エクスプローラーで開く",
"mining_payout_address": "支払いアドレス",
"mining_payout_tooltip": "マイニング報酬の受取アドレス",
"mining_pool": "プール",
"mining_pool_hashrate": "プールハッシュレート",
"mining_pool_url": "プールURL",
"mining_recent_blocks": "最近のブロック",
"mining_recent_payouts": "最近のプール支払い",
"mining_remove": "削除",
"mining_reset_defaults": "デフォルトにリセット",
"mining_save_payout_address": "支払いアドレスを保存",
"mining_save_pool_url": "プールURLを保存",
"mining_saved_addresses": "保存済みアドレス:",
"mining_saved_pools": "保存済みプール:",
"mining_shares": "シェア",
"mining_show_chart": "チャート",
"mining_show_log": "ログ",
"mining_solo": "ソロ",
"mining_starting": "起動中...",
"mining_starting_tooltip": "マイナーを起動中...",
"mining_statistics": "マイニング統計",
"mining_stop": "停止",
"mining_stop_solo_for_pool": "プールマイニングを開始する前にソロマイニングを停止してください",
"mining_stop_solo_for_pool_settings": "プール設定を変更するにはソロマイニングを停止してください",
"mining_stopping": "停止中...",
"mining_stopping_tooltip": "マイナーを停止中...",
"mining_syncing_tooltip": "ブロックチェーン同期中...",
"mining_threads": "マイニングスレッド",
"mining_to_save": "保存する",
"mining_today": "今日",
"mining_uptime": "稼働時間",
"mining_yesterday": "昨日",
"network": "ネットワーク",
"network_fee": "ネットワーク手数料",
"network_hashrate": "ネットワークハッシュレート",
"new": "+ 新規",
"new_shielded_created": "新しいシールドアドレスを作成しました",
"new_t_address": "新しいTアドレス",
"new_t_transparent": "新しいtアドレス(透明)",
"new_transparent_created": "新しい透明アドレスを作成しました",
"new_z_address": "新しいZアドレス",
"new_z_shielded": "新しいzアドレス(シールド)",
"no_addresses": "アドレスが見つかりません。上のボタンを使用して作成してください。",
"no_addresses_available": "利用可能なアドレスがありません",
"no_addresses_match": "フィルタに一致するアドレスがありません",
"no_addresses_with_balance": "残高のあるアドレスがありません",
"no_matching": "一致する取引がありません",
"no_recent_receives": "最近の受信がありません",
"no_recent_sends": "最近の送信がありません",
"no_transactions": "取引が見つかりません",
"node": "ノード",
"node_security": "ノードとセキュリティ",
"noise": "ノイズ",
"not_connected": "デーモンに未接続...",
"not_connected_to_daemon": "デーモンに未接続",
"notes": "メモ",
"notes_optional": "メモ(任意):",
"output_filename": "出力ファイル名:",
"overview": "概要",
"paste": "貼り付け",
"paste_from_clipboard": "クリップボードから貼り付け",
"pay_from": "支払い元",
"payment_request": "支払い請求",
"payment_request_copied": "支払い請求をコピーしました",
"payment_uri_copied": "支払いURIをコピーしました",
"peers": "ピア",
"peers_avg_ping": "平均Ping",
"peers_ban_24h": "ピアを24時間ブロック",
"peers_ban_score": "ブロックスコア:%d",
"peers_banned": "ブロック済み",
"peers_banned_count": "ブロック済み:%d",
"peers_best_block": "最良ブロック",
"peers_blockchain": "ブロックチェーン",
"peers_blocks": "ブロック",
"peers_blocks_left": "残り %d ブロック",
"peers_clear_all_bans": "すべてのブロックを解除",
"peers_click_copy": "クリックしてコピー",
"peers_connected": "接続済み",
"peers_connected_count": "接続済み:%d",
"peers_copy_ip": "IPをコピー",
"peers_dir_in": "入",
"peers_dir_out": "出",
"peers_hash_copied": "ハッシュをコピーしました",
"peers_hashrate": "ハッシュレート",
"peers_in_out": "入/出",
"peers_longest": "最長",
"peers_longest_chain": "最長チェーン",
"peers_memory": "メモリ",
"peers_no_banned": "ブロック済みピアなし",
"peers_no_connected": "接続済みピアなし",
"peers_no_tls": "TLSなし",
"peers_notarized": "公証済み",
"peers_p2p_port": "P2Pポート",
"peers_peer_label": "ピア:%s",
"peers_protocol": "プロトコル",
"peers_received": "受信",
"peers_refresh": "更新",
"peers_refresh_tooltip": "ピアリストを更新",
"peers_refreshing": "更新中...",
"peers_sent": "送信",
"peers_tt_id": "ID:%d",
"peers_tt_received": "受信:%s",
"peers_tt_sent": "送信:%s",
"peers_tt_services": "サービス:%s",
"peers_tt_start_height": "開始高:%d",
"peers_tt_synced": "同期済み H/B:%d/%d",
"peers_tt_tls_cipher": "TLS:%s",
"peers_unban": "ブロック解除",
"peers_upper": "ピア",
"peers_version": "バージョン",
"pending": "保留中",
"ping": "Ping",
"price_chart": "価格チャート",
"qr_code": "QRコード",
"qr_failed": "QRコードの生成に失敗しました",
"qr_title": "QRコード",
"qr_unavailable": "QR利用不可",
"ram_daemon_gb": "デーモン:%.1f GB (%s)",
"ram_daemon_mb": "デーモン:%.0f MB (%s)",
"ram_system_gb": "システム:%.1f / %.0f GB",
"ram_wallet_gb": "ウォレット:%.1f GB",
"ram_wallet_mb": "ウォレット:%.0f MB",
"receive": "受信",
"received": "受信済み",
"received_filter": "受信済み",
"received_label": "受信済み",
"received_upper": "受信済み",
"receiving_addresses": "あなたの受信アドレス",
"recent_received": "最近の受信",
"recent_sends": "最近の送信",
"recipient": "受取人",
"recv_type": "受信",
"refresh": "更新",
"refresh_now": "今すぐ更新",
"remove_favorite": "お気に入りを削除",
"report_bug": "バグを報告",
"request_amount": "金額(任意):",
"request_copy_uri": "URIをコピー",
"request_description": "他の人がスキャンまたはコピーできる支払い請求を生成します。QRコードにはアドレスとオプションの金額/メモが含まれます。",
"request_label": "ラベル(任意):",
"request_memo": "メモ(任意):",
"request_payment": "支払いを請求",
"request_payment_uri": "支払いURI:",
"request_receive_address": "受信アドレス:",
"request_select_address": "アドレスを選択...",
"request_shielded_addrs": "-- シールドアドレス --",
"request_title": "支払いを請求",
"request_transparent_addrs": "-- 透明アドレス --",
"request_uri_copied": "支払いURIをクリップボードにコピーしました",
"rescan": "再スキャン",
"reset_to_defaults": "デフォルトにリセット",
"restore_address": "アドレスを復元",
"review_send": "送金を確認",
"rpc_host": "RPCホスト",
"rpc_pass": "パスワード",
"rpc_port": "ポート",
"rpc_user": "ユーザー名",
"save": "保存",
"save_settings": "設定を保存",
"save_z_transactions": "Z取引を取引リストに保存",
"search_placeholder": "検索...",
"security": "セキュリティ",
"select_address": "アドレスを選択...",
"select_receiving_address": "受信アドレスを選択...",
"select_source_address": "送信元アドレスを選択...",
"send": "送金",
"send_amount": "金額",
"send_amount_details": "金額の詳細",
"send_amount_upper": "金額",
"send_clear_fields": "すべてのフォームフィールドをクリアしますか?",
"send_copy_error": "エラーをコピー",
"send_dismiss": "閉じる",
"send_error_copied": "エラーをクリップボードにコピーしました",
"send_error_prefix": "エラー:%s",
"send_exceeds_available": "利用可能額を超過 (%.8f)",
"send_fee": "手数料",
"send_fee_high": "高い",
"send_fee_low": "低い",
"send_fee_normal": "通常",
"send_form_restored": "フォームが復元されました",
"send_from_this_address": "このアドレスから送金",
"send_go_to_receive": "受信へ移動",
"send_keep": "保持",
"send_network_fee": "ネットワーク手数料",
"send_no_balance": "残高なし",
"send_no_recent": "最近の送信なし",
"send_recent_sends": "最近の送信",
"send_recipient": "受取人",
"send_select_source": "送信元アドレスを選択...",
"send_sending_from": "送信元",
"send_submitting": "取引を送信中...",
"send_switch_to_receive": "受信に切り替えてアドレスを取得し、資金の受け取りを開始してください。",
"send_to": "送金先",
"send_tooltip_enter_amount": "送金額を入力してください",
"send_tooltip_exceeds_balance": "金額が利用可能残高を超えています",
"send_tooltip_in_progress": "取引は既に進行中です",
"send_tooltip_invalid_address": "有効な受取人アドレスを入力してください",
"send_tooltip_not_connected": "デーモンに未接続",
"send_tooltip_select_source": "まず送信元アドレスを選択してください",
"send_tooltip_syncing": "ブロックチェーンの同期をお待ちください",
"send_total": "合計",
"send_transaction": "取引を送信",
"send_tx_failed": "取引に失敗しました",
"send_tx_sent": "取引を送信しました!",
"send_tx_success": "取引の送信に成功しました!",
"send_txid_copied": "TxIDをクリップボードにコピーしました",
"send_txid_label": "TxID:%s",
"send_valid_shielded": "有効なシールドアドレス",
"send_valid_transparent": "有効な透明アドレス",
"send_wallet_empty": "ウォレットは空です",
"send_yes_clear": "はい、クリア",
"sending": "取引を送信中",
"sending_from": "送信元",
"sent": "送信済み",
"sent_filter": "送信済み",
"sent_type": "送信済み",
"sent_upper": "送信済み",
"settings": "設定",
"settings_about_text": "DragonX (DRGX) 用のシールド暗号通貨ウォレット。Dear ImGui で構築された軽量でポータブルな体験。",
"settings_acrylic_level": "アクリルレベル:",
"settings_address_book": "アドレス帳...",
"settings_auto_detected": "DRAGONX.conf から自動検出",
"settings_auto_lock": "オートロック",
"settings_auto_shield_desc": "透明資金を自動的にシールドアドレスに移動",
"settings_auto_shield_funds": "透明資金を自動シールド",
"settings_backup": "バックアップ...",
"settings_block_explorer_urls": "ブロックエクスプローラーURL",
"settings_builtin": "内蔵",
"settings_change_passphrase": "パスフレーズを変更",
"settings_change_pin": "PIN を変更",
"settings_clear_ztx": "Z-Tx 履歴をクリア",
"settings_clear_ztx_desc": "ローカルに保存されたシールドトランザクションデータを削除",
"settings_clear_ztx_long": "保存済みZ-トランザクション履歴をクリア",
"settings_configure_explorer": "外部ブロックエクスプローラーリンクを設定",
"settings_configure_rpc": "dragonxd デーモンへの接続を設定",
"settings_connection": "接続",
"settings_copyright": "Copyright 2024-2026 DragonX 開発者 | GPLv3 ライセンス",
"settings_custom": "カスタム",
"settings_data_dir": "データディレクトリ:",
"settings_debug_changed": "デバッグカテゴリが変更されました — デーモンを再起動して適用",
"settings_debug_restart_note": "変更はデーモンの再起動後に有効になります。",
"settings_debug_select": "デーモンのデバッグログを有効にするカテゴリを選択(-debug= フラグ)。",
"settings_encrypt_first_pin": "PIN を有効にするには、まずウォレットを暗号化してください",
"settings_encrypt_wallet": "ウォレットを暗号化",
"settings_explorer_hint": "URLには末尾のスラッシュを含めてください。txid/アドレスが追加されます。",
"settings_export_all": "すべてエクスポート...",
"settings_export_csv": "CSV エクスポート...",
"settings_export_key": "鍵をエクスポート...",
"settings_gradient_bg": "グラデーション背景",
"settings_gradient_desc": "テクスチャ背景を滑らかなグラデーションに置換",
"settings_idle_after": "経過後",
"settings_import_key": "鍵をインポート...",
"settings_language_note": "注意:一部のテキストは更新に再起動が必要です",
"settings_lock_now": "今すぐロック",
"settings_locked": "ロック済み",
"settings_merge_to_address": "アドレスにマージ...",
"settings_noise_opacity": "ノイズ不透明度:",
"settings_not_encrypted": "暗号化されていません",
"settings_not_found": "見つかりません",
"settings_other": "その他",
"settings_pin_active": "PIN",
"settings_privacy": "プライバシー",
"settings_quick_unlock_pin": "クイックアンロック PIN",
"settings_reduce_transparency": "透明度を下げる",
"settings_remove_encryption": "暗号化を解除",
"settings_remove_pin": "PIN を削除",
"settings_request_payment": "支払い請求...",
"settings_rescan_desc": "欠落したトランザクションのためにブロックチェーンを再スキャン",
"settings_restart_daemon": "デーモンを再起動",
"settings_rpc_connection": "RPC 接続",
"settings_rpc_note": "注意:接続設定は通常 DRAGONX.conf から自動検出されます",
"settings_save_shielded_desc": "z-addr トランザクションをローカルファイルに保存して表示",
"settings_save_shielded_local": "シールドトランザクション履歴をローカルに保存",
"settings_set_pin": "PIN を設定",
"settings_shield_mining": "マイニングシールド...",
"settings_solid_colors_desc": "ぼかし効果の代わりに単色を使用(アクセシビリティ)",
"settings_tor_desc": "プライバシー向上のため全接続を Tor 経由にする",
"settings_unlocked": "ロック解除",
"settings_use_tor_network": "ネットワーク接続に Tor を使用",
"settings_validate_address": "アドレス検証...",
"settings_visual_effects": "視覚効果",
"settings_wallet_file_size": "ウォレットファイルサイズ:%s",
"settings_wallet_info": "ウォレット情報",
"settings_wallet_location": "ウォレットの場所:%s",
"settings_wallet_maintenance": "ウォレットメンテナンス",
"settings_wallet_not_found": "ウォレットファイルが見つかりません",
"settings_wallet_size_label": "ウォレットサイズ:",
"setup_wizard": "セットアップウィザード",
"share": "共有",
"shield_check_status": "ステータスを確認",
"shield_completed": "操作が正常に完了しました!",
"shield_description": "透明アドレスのcoinbase出力をシールドアドレスに送信して、マイニング報酬をシールドします。マイニング収入を隠すことでプライバシーが向上します。",
"shield_from_address": "送信元アドレス:",
"shield_funds": "資金をシールド",
"shield_in_progress": "操作進行中...",
"shield_max_utxos": "1回の操作あたりの最大UTXO数",
"shield_merge_done": "シールド/統合が完了しました!",
"shield_operation_id": "オペレーション ID:%s",
"shield_select_z": "zアドレスを選択...",
"shield_started": "シールド操作を開始しました",
"shield_title": "Coinbase報酬をシールド",
"shield_to_address": "送信先アドレス(シールド):",
"shield_utxo_limit": "UTXO制限:",
"shield_wildcard_hint": "'*' を使用してすべての透明アドレスからシールド",
"shielded": "シールド",
"shielded_to": "シールド先",
"shielded_type": "シールド",
"show": "表示",
"show_hidden": "非表示を表示 (%d)",
"show_qr_code": "QRコードを表示",
"showing_transactions": "%d–%d / %d 件の取引を表示中(合計:%zu)",
"simple_background": "シンプル背景",
"start_mining": "マイニング開始",
"status": "ステータス",
"stop_external": "外部デーモンを停止",
"stop_mining": "マイニング停止",
"submitting_transaction": "取引を送信中...",
"success": "成功",
"summary": "概要",
"syncing": "同期中...",
"t_addresses": "Tアドレス",
"test_connection": "テスト",
"theme": "テーマ",
"theme_effects": "テーマ効果",
"time_days_ago": "%d日前",
"time_hours_ago": "%d時間前",
"time_minutes_ago": "%d分前",
"time_seconds_ago": "%d秒前",
"to": "宛先",
"to_upper": "宛先",
"tools": "ツール",
"total": "合計",
"transaction_id": "取引ID",
"transaction_sent": "取引の送信に成功しました",
"transaction_sent_msg": "取引を送信しました!",
"transaction_url": "取引URL",
"transactions": "取引",
"transactions_upper": "取引",
"transparent": "透明",
"tt_addr_url": "ブロックエクスプローラーでアドレスを表示するためのベース URL",
"tt_address_book": "クイック送信用の保存済みアドレスを管理",
"tt_auto_lock": "この無操作時間後にウォレットをロック",
"tt_auto_shield": "プライバシーのため透明残高を自動的にシールドアドレスに移動",
"tt_backup": "wallet.dat のバックアップを作成",
"tt_block_explorer": "ブラウザで DragonX ブロックエクスプローラーを開く",
"tt_blur": "ぼかし量(0%% = オフ、100%% = 最大)",
"tt_change_pass": "ウォレットの暗号化パスフレーズを変更",
"tt_change_pin": "アンロック PIN を変更",
"tt_clear_ztx": "ローカルにキャッシュされた z-トランザクション履歴を削除",
"tt_custom_fees": "トランザクション送信時に手動手数料入力を有効化",
"tt_custom_theme": "カスタムテーマがアクティブ",
"tt_debug_collapse": "デバッグログオプションを折りたたむ",
"tt_debug_expand": "デバッグログオプションを展開",
"tt_encrypt": "パスフレーズで wallet.dat を暗号化",
"tt_export_all": "すべての秘密鍵をファイルにエクスポート",
"tt_export_csv": "トランザクション履歴を CSV スプレッドシートとしてエクスポート",
"tt_export_key": "選択したアドレスの秘密鍵をエクスポート",
"tt_fetch_prices": "CoinGecko API から DRGX の市場価格を取得",
"tt_font_scale": "すべてのテキストと UI をスケーリング(1.0x = デフォルト、最大 1.5x)。",
"tt_idle_delay": "マイニング開始前の待機時間",
"tt_import_key": "このウォレットに秘密鍵(zkey または tkey)をインポート",
"tt_keep_daemon": "セットアップウィザード実行時にデーモンは停止します",
"tt_language": "ウォレット UI のインターフェース言語",
"tt_layout_hotkey": "ホットキー:左右矢印キーでバランスレイアウトを切り替え",
"tt_lock": "ウォレットを即座にロック",
"tt_low_spec": "すべての重い視覚効果を無効化\\nホットキー:Ctrl+Shift+Down",
"tt_merge": "複数の UTXO を一つのアドレスに統合",
"tt_mine_idle": "システムがアイドル状態(キーボード/マウス入力なし)\\nのとき自動的にマイニングを開始",
"tt_noise": "グレインテクスチャ強度(0%% = オフ、100%% = 最大)",
"tt_open_dir": "クリックしてファイルエクスプローラーで開く",
"tt_remove_encrypt": "暗号化を解除してウォレットを保護なしで保存",
"tt_remove_pin": "PIN を削除しアンロックにパスフレーズを要求",
"tt_report_bug": "プロジェクトトラッカーで問題を報告",
"tt_request_payment": "QR コード付きの支払い請求を生成",
"tt_rescan": "欠落したトランザクションのためにブロックチェーンを再スキャン",
"tt_reset_settings": "ディスクから設定を再読み込み(未保存の変更を元に戻す)",
"tt_restart_daemon": "デバッグログ変更を適用するためにデーモンを再起動",
"tt_rpc_host": "DragonX デーモンのホスト名",
"tt_rpc_pass": "RPC 認証パスワード",
"tt_rpc_port": "デーモン RPC 接続用ポート",
"tt_rpc_user": "RPC 認証ユーザー名",
"tt_save_settings": "すべての設定をディスクに保存",
"tt_save_ztx": "z-address トランザクション履歴をローカルに保存して高速読み込み",
"tt_scan_themes": "新しいテーマをスキャン。\\nテーマフォルダーをここに配置:\\n%s",
"tt_scanline": "コンソールでの CRT スキャンライン効果",
"tt_set_pin": "クイックアンロック用の 4-8 桁 PIN を設定",
"tt_shield_mining": "透明マイニング報酬をシールドアドレスに移動",
"tt_simple_bg": "背景にシンプルなグラデーションを使用\\nホットキー:Ctrl+Up",
"tt_simple_bg_alt": "テーマ背景画像のグラデーション版を使用\\nホットキー:Ctrl+Up",
"tt_stop_external": "このウォレット外で起動された\\nデーモンに接続する場合に適用",
"tt_test_conn": "デーモンへの RPC 接続を確認",
"tt_theme_effects": "テーマごとのシマー、グロー、色相サイクル",
"tt_theme_hotkey": "ホットキー:Ctrl+左/右でテーマを切り替え",
"tt_tor": "匿名性のためにデーモン接続を Tor ネットワーク経由でルーティング",
"tt_tx_url": "ブロックエクスプローラーでトランザクションを表示するためのベース URL",
"tt_ui_opacity": "カードとサイドバーの不透明度(100%% = 完全不透明、低い = より透過)",
"tt_validate": "DragonX アドレスが有効かどうかを確認",
"tt_verbose": "詳細な接続診断、デーモン状態、\\nポート所有者情報をコンソールタブに記録",
"tt_website": "DragonX ウェブサイトを開く",
"tt_window_opacity": "背景の不透明度(低い = デスクトップがウィンドウ越しに見える)",
"tt_wizard": "初期セットアップウィザードを再実行\\nデーモンは再起動されます",
"tx_confirmations": "%d 確認",
"tx_details_title": "取引の詳細",
"tx_from_address": "送信元アドレス:",
"tx_id_label": "取引ID:",
"tx_immature": "未成熟",
"tx_mined": "採掘済み",
"tx_received": "受信済み",
"tx_sent": "送信済み",
"tx_to_address": "送信先アドレス:",
"tx_view_explorer": "エクスプローラーで表示",
"txs_count": "%d 件",
"type": "タイプ",
"ui_opacity": "UI透明度",
"unban": "ブロック解除",
"unconfirmed": "未確認",
"undo_clear": "クリアを元に戻す",
"unknown": "不明",
"use_embedded_daemon": "内蔵dragonxdを使用",
"use_tor": "Torを使用",
"validate_btn": "検証",
"validate_description": "DragonXアドレスを入力して、有効かどうか、そしてこのウォレットに属しているかどうかを確認します。",
"validate_invalid": "無効",
"validate_is_mine": "このウォレットがこのアドレスを所有しています",
"validate_not_mine": "このウォレットに属していません",
"validate_ownership": "所有者:",
"validate_results": "結果:",
"validate_shielded_type": "シールド(zアドレス)",
"validate_status": "ステータス:",
"validate_title": "アドレスを検証",
"validate_transparent_type": "透明(tアドレス)",
"validate_type": "タイプ:",
"validate_valid": "有効",
"validating": "検証中...",
"verbose_logging": "詳細ログ",
"version": "バージョン",
"view": "表示",
"view_details": "詳細を表示",
"view_on_explorer": "エクスプローラーで表示",
"waiting_for_daemon": "デーモン接続を待機中...",
"wallet": "ウォレット",
"wallet_empty": "ウォレットは空です",
"wallet_empty_hint": "受信に切り替えてアドレスを取得し、資金の受け取りを開始してください。",
"warning": "警告",
"warning_upper": "警告!",
"website": "ウェブサイト",
"window_opacity": "ウィンドウ透明度",
"yes_clear": "はい、クリア",
"your_addresses": "あなたのアドレス",
"z_addresses": "Zアドレス"
}
+789 -133
View File
@@ -1,139 +1,795 @@
{
"balance": "잔액",
"send": "보내기",
"receive": "받기",
"transactions": "거래 내역",
"mining": "채굴",
"peers": "노드",
"market": "시장",
"settings": "설정",
"summary": "요약",
"shielded": "차폐됨",
"transparent": "투명",
"total": "합계",
"unconfirmed": "미확인",
"your_addresses": "내 주소",
"z_addresses": "Z-주소",
"t_addresses": "T-주소",
"no_addresses": "주소를 찾을 수 없습니다. 위의 버튼을 사용하여 생성하세요.",
"new_z_address": "새 Z-주소",
"new_t_address": "새 T-주소",
"type": "유형",
"address": "주소",
"copy_address": "전체 주소 복사",
"send_from_this_address": "이 주소에서 보내기",
"export_private_key": "개인키 내보내기",
"export_viewing_key": "조회키 내보내기",
"show_qr_code": "QR 코드 표시",
"not_connected": "데몬에 연결되지 않음...",
"pay_from": "출금 주소",
"send_to": "받는 주소",
"amount": "금액",
"memo": "메모 (선택사항, 암호화됨)",
"miner_fee": "채굴자 수수료",
"fee": "수수료",
"send_transaction": "거래 보내기",
"clear": "지우기",
"select_address": "주소 선택...",
"paste": "붙여넣기",
"max": "최대",
"available": "사용 가능",
"invalid_address": "잘못된 주소 형식",
"memo_z_only": "참고: 메모는 차폐(z) 주소로 보낼 때만 사용할 수 있습니다",
"characters": "글자",
"from": "보낸 사람",
"to": "받는 사람",
"sending": "거래 전송 중",
"confirm_send": "보내기 확인",
"confirm_transaction": "거래 확인",
"confirm_and_send": "확인 및 보내기",
"cancel": "취소",
"receiving_addresses": "수신 주소",
"new_z_shielded": "새 z-주소 (차폐)",
"new_t_transparent": "새 t-주소 (투명)",
"address_details": "주소 상세",
"view_on_explorer": "탐색기에서 보기",
"qr_code": "QR 코드",
"request_payment": "결제 요청",
"date": "날짜",
"status": "상태",
"confirmations": "확인 수",
"confirmed": "확인됨",
"pending": "대기 중",
"sent": "보냄",
"received": "받음",
"mined": "채굴됨",
"mining_control": "채굴 제어",
"start_mining": "채굴 시작",
"stop_mining": "채굴 중지",
"mining_threads": "채굴 스레드",
"mining_statistics": "채굴 통계",
"local_hashrate": "로컬 해시레이트",
"network_hashrate": "네트워크 해시레이트",
"difficulty": "난이도",
"est_time_to_block": "예상 블록 발견 시간",
"mining_off": "채굴 꺼짐",
"mining_on": "채굴 켜짐",
"connected_peers": "연결된 노드",
"banned_peers": "차단된 노드",
"ip_address": "IP 주소",
"version": "버전",
"height": "블록 높이",
"ping": "핑",
"ban": "차단",
"unban": "차단 해제",
"clear_all_bans": "모든 차단 해제",
"price_chart": "가격 차트",
"current_price": "현재 가격",
"24h_change": "24시간 변동",
"24h_volume": "24시간 거래량",
"market_cap": "시가총액",
"general": "일반",
"display": "화면",
"network": "네트워크",
"theme": "테마",
"language": "언어",
"dragonx_green": "DragonX (녹색)",
"dark": "다크",
"light": "라이트",
"allow_custom_fees": "사용자 수수료 허용",
"use_embedded_daemon": "내장 dragonxd 사용",
"save": "저장",
"close": "닫기",
"file": "파일",
"edit": "편집",
"view": "보기",
"help": "도움말",
"import_private_key": "개인키 가져오기...",
"backup_wallet": "지갑 백업...",
"exit": "종료",
"about_dragonx": "ObsidianDragon 정보",
"refresh_now": "지금 새로고침",
"about": "정보",
"import": "가져오기",
"export": "내보내기",
"copy_to_clipboard": "클립보드에 복사",
"connected": "연결됨",
"disconnected": "연결 끊김",
"connecting": "연결 중...",
"syncing": "동기화 중...",
"block": "블록",
"no_addresses_available": "사용 가능한 주소 없음",
"error": "오류",
"success": "성공",
"warning": "경고",
"about_block_explorer": "블록 탐색기",
"about_block_height": "블록 높이:",
"about_build_date": "빌드 날짜:",
"about_build_type": "빌드 유형:",
"about_chain": "체인:",
"about_connections": "연결:",
"about_credits": "크레딧",
"about_daemon": "데몬:",
"about_debug": "디버그",
"about_dragonx": "ObsidianDragon 정보",
"about_edition": "ImGui 에디션",
"about_github": "GitHub",
"about_imgui": "ImGui:",
"about_license": "라이선스",
"about_license_text": "본 소프트웨어는 GNU General Public License v3 (GPLv3) 하에 배포됩니다. 라이선스 조건에 따라 자유롭게 사용, 수정 및 배포할 수 있습니다.",
"about_peers_count": "%zu 피어",
"about_release": "릴리스",
"about_title": "ObsidianDragon 정보",
"about_version": "버전:",
"about_website": "웹사이트",
"acrylic": "아크릴",
"add": "추가",
"address": "주소",
"address_book_add": "주소 추가",
"address_book_add_new": "새로 추가",
"address_book_added": "주소록에 주소를 추가했습니다",
"address_book_count": "저장된 주소 %zu개",
"address_book_deleted": "항목이 삭제되었습니다",
"address_book_edit": "주소 편집",
"address_book_empty": "저장된 주소가 없습니다. '새로 추가'를 클릭하여 추가하세요.",
"address_book_exists": "주소가 이미 주소록에 있습니다",
"address_book_title": "주소록",
"address_book_update_failed": "업데이트 실패 — 주소가 중복될 수 있습니다",
"address_book_updated": "주소가 업데이트되었습니다",
"address_copied": "주소가 클립보드에 복사되었습니다",
"address_details": "주소 상세",
"address_label": "주소:",
"address_upper": "주소",
"address_url": "주소 URL",
"addresses_appear_here": "연결 후 수신 주소가 여기에 표시됩니다.",
"advanced": "고급 설정",
"all_filter": "전체",
"allow_custom_fees": "사용자 정의 수수료 허용",
"amount": "금액",
"amount_details": "금액 상세",
"amount_exceeds_balance": "금액이 잔액을 초과합니다",
"transaction_sent": "거래가 성공적으로 전송되었습니다"
"amount_label": "금액:",
"appearance": "외관",
"auto_shield": "채굴 자동 차폐",
"available": "사용 가능",
"backup_backing_up": "백업 중...",
"backup_create": "백업 생성",
"backup_created": "지갑 백업이 생성되었습니다",
"backup_data": "백업 및 데이터",
"backup_description": "wallet.dat 파일의 백업을 생성합니다. 이 파일에는 모든 개인 키와 거래 내역이 포함되어 있습니다. 백업을 안전한 곳에 보관하세요.",
"backup_destination": "백업 위치:",
"backup_source": "소스: %s",
"backup_tip_external": "외장 드라이브 또는 클라우드 스토리지에 백업 저장",
"backup_tip_multiple": "서로 다른 위치에 여러 백업 생성",
"backup_tip_test": "정기적으로 백업 복원 테스트",
"backup_tips": "팁:",
"backup_title": "지갑 백업",
"backup_wallet": "지갑 백업...",
"backup_wallet_not_found": "경고: 예상 위치에서 wallet.dat를 찾을 수 없습니다",
"balance": "잔액",
"balance_layout": "잔액 레이아웃",
"ban": "차단",
"banned_peers": "차단된 피어",
"block": "블록",
"block_bits": "비트:",
"block_click_copy": "복사하려면 클릭",
"block_click_next": "클릭하여 다음 블록 보기",
"block_click_prev": "클릭하여 이전 블록 보기",
"block_explorer": "블록 탐색기",
"block_get_info": "블록 정보 조회",
"block_hash": "블록 해시:",
"block_hash_copied": "블록 해시 복사됨",
"block_height": "블록 높이:",
"block_info_title": "블록 정보",
"block_merkle_root": "머클 루트:",
"block_nav_next": "다음 >>",
"block_nav_prev": "<< 이전",
"block_next": "다음 블록:",
"block_previous": "이전 블록:",
"block_size": "크기:",
"block_timestamp": "타임스탬프:",
"block_transactions": "트랜잭션:",
"blockchain_syncing": "블록체인 동기화 중 (%.1f%%)... 잔액이 정확하지 않을 수 있습니다.",
"cancel": "취소",
"characters": "문자",
"clear": "지우기",
"clear_all_bans": "모든 차단 해제",
"clear_anyway": "그래도 삭제",
"clear_form_confirm": "모든 양식 필드를 지우시겠습니까?",
"clear_request": "요청 지우기",
"click_copy_address": "클릭하여 주소 복사",
"click_copy_uri": "클릭하여 URI 복사",
"click_to_copy": "복사하려면 클릭",
"close": "닫기",
"conf_count": "%d 확인",
"confirm_and_send": "확인 후 전송",
"confirm_clear_ztx_title": "Z-Tx 기록 삭제 확인",
"confirm_clear_ztx_warning1": "z-트랜잭션 기록을 삭제하면 지갑 재스캔이 수행될 때까지 차폐 잔액이 0으로 표시될 수 있습니다.",
"confirm_clear_ztx_warning2": "이런 경우, 잔액을 복구하려면 재스캔을 활성화하여 z-주소 개인키를 다시 가져와야 합니다.",
"confirm_send": "전송 확인",
"confirm_transaction": "거래 확인",
"confirmations": "확인 수",
"confirmations_display": "%d 확인 | %s",
"confirmed": "확인됨",
"connected": "연결됨",
"connected_peers": "연결된 피어",
"connecting": "연결 중...",
"console": "콘솔",
"console_auto_scroll": "자동 스크롤",
"console_available_commands": "사용 가능한 명령어:",
"console_capturing_output": "데몬 출력 캡처 중...",
"console_clear": "지우기",
"console_clear_console": "콘솔 지우기",
"console_cleared": "콘솔이 지워졌습니다",
"console_click_commands": "위의 명령어를 클릭하여 삽입",
"console_click_insert": "클릭하여 삽입",
"console_click_insert_params": "클릭하여 매개변수와 함께 삽입",
"console_close": "닫기",
"console_commands": "명령어",
"console_common_rpc": "일반 RPC 명령어:",
"console_completions": "자동 완성:",
"console_connected": "데몬에 연결됨",
"console_copy_all": "모두 복사",
"console_copy_selected": "복사",
"console_daemon": "데몬",
"console_daemon_error": "데몬 오류!",
"console_daemon_started": "데몬이 시작되었습니다",
"console_daemon_stopped": "데몬이 중지되었습니다",
"console_disconnected": "데몬 연결이 끊어졌습니다",
"console_errors": "오류",
"console_filter_hint": "출력 필터...",
"console_help_clear": " clear - 콘솔 지우기",
"console_help_getbalance": " getbalance - 투명 잔액 표시",
"console_help_getblockcount": " getblockcount - 현재 블록 높이 표시",
"console_help_getinfo": " getinfo - 노드 정보 표시",
"console_help_getmininginfo": " getmininginfo - 채굴 상태 표시",
"console_help_getpeerinfo": " getpeerinfo - 연결된 피어 표시",
"console_help_gettotalbalance": " gettotalbalance - 총 잔액 표시",
"console_help_help": " help - 도움말 표시",
"console_help_setgenerate": " setgenerate - 채굴 제어",
"console_help_stop": " stop - 데몬 중지",
"console_line_count": "%zu줄",
"console_new_lines": "%d 새 줄",
"console_no_daemon": "데몬 없음",
"console_not_connected": "오류: 데몬에 연결되지 않았습니다",
"console_rpc_reference": "RPC 명령어 참조",
"console_scanline": "콘솔 스캔라인",
"console_search_commands": "명령어 검색...",
"console_select_all": "모두 선택",
"console_show_daemon_output": "데몬 출력 표시",
"console_show_errors_only": "오류만 표시",
"console_show_rpc_ref": "RPC 명령어 참조 표시",
"console_showing_lines": "%zu / %zu줄 표시 중",
"console_starting_node": "노드 시작 중...",
"console_status_error": "오류",
"console_status_running": "실행 중",
"console_status_starting": "시작 중",
"console_status_stopped": "중지됨",
"console_status_stopping": "중지 중",
"console_status_unknown": "알 수 없음",
"console_tab_completion": "Tab으로 자동 완성",
"console_type_help": "'help'를 입력하여 사용 가능한 명령어 보기",
"console_welcome": "ObsidianDragon 콘솔에 오신 것을 환영합니다",
"console_zoom_in": "확대",
"console_zoom_out": "축소",
"copy": "복사",
"copy_address": "전체 주소 복사",
"copy_error": "오류 복사",
"copy_to_clipboard": "클립보드에 복사",
"copy_txid": "TxID 복사",
"copy_uri": "URI 복사",
"current_price": "현재 가격",
"custom_fees": "사용자 정의 수수료",
"dark": "다크",
"date": "날짜",
"date_label": "날짜:",
"debug_logging": "디버그 로깅",
"delete": "삭제",
"difficulty": "난이도",
"disconnected": "연결 끊김",
"dismiss": "닫기",
"display": "디스플레이",
"dragonx_green": "DragonX(그린)",
"edit": "편집",
"error": "오류",
"error_format": "오류: %s",
"est_time_to_block": "예상 블록 시간",
"exit": "종료",
"explorer": "탐색기",
"export": "내보내기",
"export_csv": "CSV 내보내기",
"export_keys_btn": "키 내보내기",
"export_keys_danger": "위험: 지갑의 모든 개인 키가 내보내집니다! 이 파일에 접근할 수 있는 사람은 누구나 자금을 훔칠 수 있습니다. 안전하게 보관하고 사용 후 삭제하세요.",
"export_keys_include_t": "T 주소 포함 (투명)",
"export_keys_include_z": "Z 주소 포함 (차폐)",
"export_keys_options": "내보내기 옵션:",
"export_keys_progress": "내보내는 중 %d/%d...",
"export_keys_success": "키 내보내기 성공",
"export_keys_title": "모든 개인 키 내보내기",
"export_private_key": "개인 키 내보내기",
"export_tx_count": "%zu건의 거래를 CSV 파일로 내보냈습니다.",
"export_tx_file_fail": "CSV 파일 생성 실패",
"export_tx_none": "내보낼 거래가 없습니다",
"export_tx_success": "거래 내보내기 성공",
"export_tx_title": "거래를 CSV로 내보내기",
"export_viewing_key": "조회 키 내보내기",
"failed_create_shielded": "차폐 주소 생성 실패",
"failed_create_transparent": "투명 주소 생성 실패",
"favorite_address": "즐겨찾기에 추가",
"fee": "수수료",
"fee_high": "높음",
"fee_label": "수수료:",
"fee_low": "낮음",
"fee_normal": "보통",
"fetch_prices": "가격 조회",
"file": "파일",
"file_save_location": "파일 저장 위치: ~/.config/ObsidianDragon/",
"font_scale": "글꼴 크기",
"from": "보낸 곳",
"from_upper": "보낸 곳",
"full_details": "전체 세부 정보",
"general": "일반",
"go_to_receive": "수신으로 이동",
"height": "높이",
"help": "도움말",
"hide": "숨기기",
"hide_address": "주소 숨기기",
"hide_zero_balances": "잔액 0 숨기기",
"history": "내역",
"immature_type": "미성숙",
"import": "가져오기",
"import_key_btn": "키 가져오기",
"import_key_formats": "지원되는 키 형식:",
"import_key_full_rescan": "(0 = 전체 재스캔)",
"import_key_label": "개인 키:",
"import_key_no_valid": "입력에서 유효한 키를 찾을 수 없습니다",
"import_key_progress": "가져오는 중 %d/%d...",
"import_key_rescan": "가져오기 후 블록체인 재스캔",
"import_key_start_height": "시작 높이:",
"import_key_success": "키 가져오기 성공",
"import_key_t_format": "T 주소 WIF 개인 키",
"import_key_title": "개인 키 가져오기",
"import_key_tooltip": "한 줄에 하나의 개인 키를 입력하세요.\nz 주소와 t 주소 키 모두 지원됩니다.\n#으로 시작하는 줄은 주석으로 처리됩니다.",
"import_key_warning": "경고: 개인 키를 절대 공유하지 마세요! 신뢰할 수 없는 소스의 키를 가져오면 지갑이 위험해질 수 있습니다.",
"import_key_z_format": "Z 주소 지출 키 (secret-extended-key-...)",
"import_private_key": "개인 키 가져오기...",
"invalid_address": "잘못된 주소 형식",
"ip_address": "IP 주소",
"keep": "유지",
"keep_daemon": "데몬 계속 실행",
"key_export_click_retrieve": "지갑에서 키를 가져오려면 클릭",
"key_export_fetching": "지갑에서 키를 가져오는 중...",
"key_export_private_key": "개인 키:",
"key_export_private_warning": "이 키를 비밀로 유지하세요! 이 키를 가진 사람은 누구나 자금을 사용할 수 있습니다. 온라인이나 신뢰할 수 없는 사람과 공유하지 마세요.",
"key_export_reveal": "키 표시",
"key_export_viewing_key": "조회 키:",
"key_export_viewing_keys_zonly": "보기 키는 차폐 (z) 주소에만 사용할 수 있습니다",
"key_export_viewing_warning": "이 조회 키를 사용하면 다른 사람이 수신 거래와 잔액을 볼 수 있지만 자금을 사용할 수는 없습니다. 신뢰할 수 있는 사람에게만 공유하세요.",
"label": "라벨:",
"language": "언어",
"light": "라이트",
"loading": "로딩 중...",
"loading_addresses": "주소 로딩 중...",
"local_hashrate": "로컬 해시레이트",
"low_spec_mode": "저사양 모드",
"market": "시장",
"market_12h": "12시간",
"market_18h": "18시간",
"market_24h": "24시간",
"market_24h_volume": "24시간 거래량",
"market_6h": "6시간",
"market_attribution": "가격 데이터: NonKYC 제공",
"market_btc_price": "BTC 가격",
"market_cap": "시가총액",
"market_no_history": "가격 내역 없음",
"market_no_price": "가격 데이터 없음",
"market_now": "현재",
"market_pct_shielded": "%.0f%% 차폐됨",
"market_portfolio": "포트폴리오",
"market_price_unavailable": "가격 데이터를 사용할 수 없습니다",
"market_refresh_price": "가격 데이터 새로고침",
"market_trade_on": "%s에서 거래",
"mature": "성숙됨",
"max": "최대",
"memo": "메모 (선택, 암호화)",
"memo_label": "메모:",
"memo_optional": "메모 (선택)",
"memo_upper": "메모",
"memo_z_only": "참고: 메모는 차폐 (z) 주소로 전송할 때만 사용할 수 있습니다",
"merge_description": "여러 UTXO를 단일 차폐 주소로 통합합니다. 지갑 크기를 줄이고 프라이버시를 향상시킵니다.",
"merge_funds": "자금 통합",
"merge_started": "통합 작업이 시작되었습니다",
"merge_title": "주소로 통합",
"mine_when_idle": "유휴 시 채굴",
"mined": "채굴됨",
"mined_filter": "채굴됨",
"mined_type": "채굴됨",
"mined_upper": "채굴됨",
"miner_fee": "채굴 수수료",
"mining": "채굴",
"mining_active": "활성",
"mining_address_copied": "채굴 주소가 복사되었습니다",
"mining_all_time": "전체 기간",
"mining_already_saved": "풀 URL이 이미 저장되어 있습니다",
"mining_block_copied": "블록 해시가 복사되었습니다",
"mining_chart_1m_ago": "1분 전",
"mining_chart_5m_ago": "5분 전",
"mining_chart_now": "현재",
"mining_chart_start": "시작",
"mining_click": "클릭",
"mining_click_copy_address": "클릭하여 주소 복사",
"mining_click_copy_block": "클릭하여 블록 해시 복사",
"mining_click_copy_difficulty": "클릭하여 난이도 복사",
"mining_connected": "연결됨",
"mining_connecting": "연결 중...",
"mining_control": "채굴 제어",
"mining_difficulty_copied": "난이도가 복사되었습니다",
"mining_est_block": "예상 블록",
"mining_est_daily": "예상 일일 수익",
"mining_filter_all": "전체",
"mining_filter_tip_all": "모든 수익 표시",
"mining_filter_tip_pool": "풀 수익만 표시",
"mining_filter_tip_solo": "솔로 수익만 표시",
"mining_idle_off_tooltip": "유휴 채굴 활성화",
"mining_idle_on_tooltip": "유휴 채굴 비활성화",
"mining_local_hashrate": "로컬 해시레이트",
"mining_mine": "채굴",
"mining_mining_addr": "채굴 주소",
"mining_network": "네트워크",
"mining_no_blocks_yet": "아직 블록을 찾지 못했습니다",
"mining_no_payouts_yet": "아직 풀 지급이 없습니다",
"mining_no_saved_addresses": "저장된 주소 없음",
"mining_no_saved_pools": "저장된 풀 없음",
"mining_off": "채굴이 꺼져 있습니다",
"mining_on": "채굴이 켜져 있습니다",
"mining_open_in_explorer": "탐색기에서 열기",
"mining_payout_address": "지급 주소",
"mining_payout_tooltip": "채굴 보상 수신 주소",
"mining_pool": "풀",
"mining_pool_hashrate": "풀 해시레이트",
"mining_pool_url": "풀 URL",
"mining_recent_blocks": "최근 블록",
"mining_recent_payouts": "최근 풀 지급",
"mining_remove": "제거",
"mining_reset_defaults": "기본값으로 재설정",
"mining_save_payout_address": "지급 주소 저장",
"mining_save_pool_url": "풀 URL 저장",
"mining_saved_addresses": "저장된 주소:",
"mining_saved_pools": "저장된 풀:",
"mining_shares": "셰어",
"mining_show_chart": "차트",
"mining_show_log": "로그",
"mining_solo": "솔로",
"mining_starting": "시작 중...",
"mining_starting_tooltip": "채굴기 시작 중...",
"mining_statistics": "채굴 통계",
"mining_stop": "중지",
"mining_stop_solo_for_pool": "풀 채굴을 시작하려면 솔로 채굴을 먼저 중지하세요",
"mining_stop_solo_for_pool_settings": "풀 설정을 변경하려면 솔로 채굴을 중지하세요",
"mining_stopping": "중지 중...",
"mining_stopping_tooltip": "채굴기 중지 중...",
"mining_syncing_tooltip": "블록체인 동기화 중...",
"mining_threads": "채굴 스레드",
"mining_to_save": "저장하려면",
"mining_today": "오늘",
"mining_uptime": "가동 시간",
"mining_yesterday": "어제",
"network": "네트워크",
"network_fee": "네트워크 수수료",
"network_hashrate": "네트워크 해시레이트",
"new": "+ 새로 만들기",
"new_shielded_created": "새 차폐 주소가 생성되었습니다",
"new_t_address": "새 T 주소",
"new_t_transparent": "새 t 주소 (투명)",
"new_transparent_created": "새 투명 주소가 생성되었습니다",
"new_z_address": "새 Z 주소",
"new_z_shielded": "새 z 주소 (차폐)",
"no_addresses": "주소가 없습니다. 위의 버튼을 사용하여 생성하세요.",
"no_addresses_available": "사용 가능한 주소 없음",
"no_addresses_match": "필터와 일치하는 주소가 없습니다",
"no_addresses_with_balance": "잔액이 있는 주소가 없습니다",
"no_matching": "일치하는 거래가 없습니다",
"no_recent_receives": "최근 수신 내역 없음",
"no_recent_sends": "최근 전송 내역 없음",
"no_transactions": "거래 내역이 없습니다",
"node": "노드",
"node_security": "노드 및 보안",
"noise": "노이즈",
"not_connected": "데몬에 연결되지 않음...",
"not_connected_to_daemon": "데몬에 연결되지 않음",
"notes": "메모",
"notes_optional": "메모 (선택):",
"output_filename": "출력 파일명:",
"overview": "개요",
"paste": "붙여넣기",
"paste_from_clipboard": "클립보드에서 붙여넣기",
"pay_from": "보낼 곳",
"payment_request": "결제 요청",
"payment_request_copied": "결제 요청이 복사되었습니다",
"payment_uri_copied": "결제 URI가 복사되었습니다",
"peers": "피어",
"peers_avg_ping": "평균 Ping",
"peers_ban_24h": "피어 24시간 차단",
"peers_ban_score": "차단 점수: %d",
"peers_banned": "차단됨",
"peers_banned_count": "차단됨: %d",
"peers_best_block": "최고 블록",
"peers_blockchain": "블록체인",
"peers_blocks": "블록",
"peers_blocks_left": "남은 블록: %d",
"peers_clear_all_bans": "모든 차단 해제",
"peers_click_copy": "클릭하여 복사",
"peers_connected": "연결됨",
"peers_connected_count": "연결됨: %d",
"peers_copy_ip": "IP 복사",
"peers_dir_in": "수신",
"peers_dir_out": "송신",
"peers_hash_copied": "해시가 복사되었습니다",
"peers_hashrate": "해시레이트",
"peers_in_out": "수신/송신",
"peers_longest": "최장",
"peers_longest_chain": "최장 체인",
"peers_memory": "메모리",
"peers_no_banned": "차단된 피어 없음",
"peers_no_connected": "연결된 피어 없음",
"peers_no_tls": "TLS 없음",
"peers_notarized": "공증됨",
"peers_p2p_port": "P2P 포트",
"peers_peer_label": "피어: %s",
"peers_protocol": "프로토콜",
"peers_received": "수신됨",
"peers_refresh": "새로고침",
"peers_refresh_tooltip": "피어 목록 새로고침",
"peers_refreshing": "새로고침 중...",
"peers_sent": "전송됨",
"peers_tt_id": "ID: %d",
"peers_tt_received": "수신: %s",
"peers_tt_sent": "전송: %s",
"peers_tt_services": "서비스: %s",
"peers_tt_start_height": "시작 높이: %d",
"peers_tt_synced": "동기화 H/B: %d/%d",
"peers_tt_tls_cipher": "TLS: %s",
"peers_unban": "차단 해제",
"peers_upper": "피어",
"peers_version": "버전",
"pending": "대기 중",
"ping": "Ping",
"price_chart": "가격 차트",
"qr_code": "QR 코드",
"qr_failed": "QR 코드 생성 실패",
"qr_title": "QR 코드",
"qr_unavailable": "QR 사용 불가",
"ram_daemon_gb": "데몬: %.1f GB (%s)",
"ram_daemon_mb": "데몬: %.0f MB (%s)",
"ram_system_gb": "시스템: %.1f / %.0f GB",
"ram_wallet_gb": "지갑: %.1f GB",
"ram_wallet_mb": "지갑: %.0f MB",
"receive": "수신",
"received": "수신됨",
"received_filter": "수신됨",
"received_label": "수신됨",
"received_upper": "수신됨",
"receiving_addresses": "수신 주소",
"recent_received": "최근 수신",
"recent_sends": "최근 전송",
"recipient": "수신자",
"recv_type": "수신",
"refresh": "새로고침",
"refresh_now": "지금 새로고침",
"remove_favorite": "즐겨찾기 제거",
"report_bug": "버그 신고",
"request_amount": "금액 (선택):",
"request_copy_uri": "URI 복사",
"request_description": "다른 사람이 스캔하거나 복사할 수 있는 결제 요청을 생성합니다. QR 코드에는 주소와 선택적 금액/메모가 포함됩니다.",
"request_label": "라벨 (선택):",
"request_memo": "메모 (선택):",
"request_payment": "결제 요청",
"request_payment_uri": "결제 URI:",
"request_receive_address": "수신 주소:",
"request_select_address": "주소 선택...",
"request_shielded_addrs": "-- 차폐 주소 --",
"request_title": "결제 요청",
"request_transparent_addrs": "-- 투명 주소 --",
"request_uri_copied": "결제 URI가 클립보드에 복사되었습니다",
"rescan": "재스캔",
"reset_to_defaults": "기본값으로 재설정",
"restore_address": "주소 복원",
"review_send": "전송 검토",
"rpc_host": "RPC 호스트",
"rpc_pass": "비밀번호",
"rpc_port": "포트",
"rpc_user": "사용자명",
"save": "저장",
"save_settings": "설정 저장",
"save_z_transactions": "Z 거래를 거래 목록에 저장",
"search_placeholder": "검색...",
"security": "보안",
"select_address": "주소 선택...",
"select_receiving_address": "수신 주소 선택...",
"select_source_address": "보낼 주소 선택...",
"send": "전송",
"send_amount": "금액",
"send_amount_details": "금액 상세",
"send_amount_upper": "금액",
"send_clear_fields": "모든 양식 필드를 지우시겠습니까?",
"send_copy_error": "오류 복사",
"send_dismiss": "닫기",
"send_error_copied": "오류가 클립보드에 복사되었습니다",
"send_error_prefix": "오류: %s",
"send_exceeds_available": "사용 가능 금액 초과 (%.8f)",
"send_fee": "수수료",
"send_fee_high": "높음",
"send_fee_low": "낮음",
"send_fee_normal": "보통",
"send_form_restored": "양식이 복원되었습니다",
"send_from_this_address": "이 주소에서 전송",
"send_go_to_receive": "수신으로 이동",
"send_keep": "유지",
"send_network_fee": "네트워크 수수료",
"send_no_balance": "잔액 없음",
"send_no_recent": "최근 전송 없음",
"send_recent_sends": "최근 전송",
"send_recipient": "수신자",
"send_select_source": "보낼 주소 선택...",
"send_sending_from": "보내는 곳",
"send_submitting": "거래 제출 중...",
"send_switch_to_receive": "수신으로 전환하여 주소를 받고 자금 수신을 시작하세요.",
"send_to": "받는 곳",
"send_tooltip_enter_amount": "전송할 금액을 입력하세요",
"send_tooltip_exceeds_balance": "금액이 사용 가능 잔액을 초과합니다",
"send_tooltip_in_progress": "거래가 이미 진행 중입니다",
"send_tooltip_invalid_address": "유효한 수신자 주소를 입력하세요",
"send_tooltip_not_connected": "데몬에 연결되지 않음",
"send_tooltip_select_source": "먼저 보낼 주소를 선택하세요",
"send_tooltip_syncing": "블록체인 동기화를 기다려 주세요",
"send_total": "합계",
"send_transaction": "거래 전송",
"send_tx_failed": "거래 실패",
"send_tx_sent": "거래가 전송되었습니다!",
"send_tx_success": "거래 전송 성공!",
"send_txid_copied": "TxID가 클립보드에 복사되었습니다",
"send_txid_label": "TxID: %s",
"send_valid_shielded": "유효한 차폐 주소",
"send_valid_transparent": "유효한 투명 주소",
"send_wallet_empty": "지갑이 비어 있습니다",
"send_yes_clear": "예, 지우기",
"sending": "거래 전송 중",
"sending_from": "보내는 곳",
"sent": "전송됨",
"sent_filter": "전송됨",
"sent_type": "전송됨",
"sent_upper": "전송됨",
"settings": "설정",
"settings_about_text": "DragonX (DRGX)용 차폐 암호화폐 지갑으로, Dear ImGui로 제작되어 가볍고 휴대 가능합니다.",
"settings_acrylic_level": "아크릴 레벨:",
"settings_address_book": "주소록...",
"settings_auto_detected": "DRAGONX.conf에서 자동 감지",
"settings_auto_lock": "자동 잠금",
"settings_auto_shield_desc": "투명 자금을 자동으로 차폐 주소로 이동",
"settings_auto_shield_funds": "투명 자금 자동 차폐",
"settings_backup": "백업...",
"settings_block_explorer_urls": "블록 탐색기 URL",
"settings_builtin": "내장",
"settings_change_passphrase": "비밀번호 변경",
"settings_change_pin": "PIN 변경",
"settings_clear_ztx": "Z-Tx 기록 삭제",
"settings_clear_ztx_desc": "로컬에 저장된 차폐 거래 데이터 삭제",
"settings_clear_ztx_long": "저장된 Z-트랜잭션 기록 삭제",
"settings_configure_explorer": "외부 블록 탐색기 링크 구성",
"settings_configure_rpc": "dragonxd 데몬 연결 구성",
"settings_connection": "연결",
"settings_copyright": "Copyright 2024-2026 DragonX 개발자 | GPLv3 라이선스",
"settings_custom": "사용자 지정",
"settings_data_dir": "데이터 디렉터리:",
"settings_debug_changed": "디버그 카테고리가 변경되었습니다 — 데몬을 재시작하여 적용",
"settings_debug_restart_note": "변경 사항은 데몬을 다시 시작한 후에 적용됩니다.",
"settings_debug_select": "데몬 디버그 로깅을 활성화할 카테고리를 선택하세요 (-debug= 플래그).",
"settings_encrypt_first_pin": "PIN을 활성화하려면 먼저 지갑을 암호화하세요",
"settings_encrypt_wallet": "지갑 암호화",
"settings_explorer_hint": "URL에 후행 슬래시를 포함해야 합니다. txid/주소가 추가됩니다.",
"settings_export_all": "모두 내보내기...",
"settings_export_csv": "CSV 내보내기...",
"settings_export_key": "키 내보내기...",
"settings_gradient_bg": "그라데이션 배경",
"settings_gradient_desc": "텍스처 배경을 부드러운 그라데이션으로 교체",
"settings_idle_after": "후",
"settings_import_key": "키 가져오기...",
"settings_language_note": "참고: 일부 텍스트는 업데이트하려면 다시 시작해야 합니다",
"settings_lock_now": "지금 잠금",
"settings_locked": "잠김",
"settings_merge_to_address": "주소로 병합...",
"settings_noise_opacity": "노이즈 불투명도:",
"settings_not_encrypted": "암호화되지 않음",
"settings_not_found": "찾을 수 없음",
"settings_other": "기타",
"settings_pin_active": "PIN",
"settings_privacy": "개인 정보",
"settings_quick_unlock_pin": "빠른 잠금 해제 PIN",
"settings_reduce_transparency": "투명도 줄이기",
"settings_remove_encryption": "암호화 제거",
"settings_remove_pin": "PIN 제거",
"settings_request_payment": "결제 요청...",
"settings_rescan_desc": "누락된 거래를 찾기 위해 블록체인 재스캔",
"settings_restart_daemon": "데몬 재시작",
"settings_rpc_connection": "RPC 연결",
"settings_rpc_note": "참고: 연결 설정은 보통 DRAGONX.conf에서 자동 감지됩니다",
"settings_save_shielded_desc": "z-addr 거래를 로컬 파일에 저장하여 조회",
"settings_save_shielded_local": "차폐 거래 기록을 로컬에 저장",
"settings_set_pin": "PIN 설정",
"settings_shield_mining": "채굴 차폐...",
"settings_solid_colors_desc": "블러 효과 대신 단색 사용 (접근성)",
"settings_tor_desc": "향상된 개인 정보 보호를 위해 모든 연결을 Tor를 통해 라우팅",
"settings_unlocked": "잠금 해제",
"settings_use_tor_network": "네트워크 연결에 Tor 사용",
"settings_validate_address": "주소 확인...",
"settings_visual_effects": "시각 효과",
"settings_wallet_file_size": "지갑 파일 크기: %s",
"settings_wallet_info": "지갑 정보",
"settings_wallet_location": "지갑 위치: %s",
"settings_wallet_maintenance": "지갑 유지보수",
"settings_wallet_not_found": "지갑 파일을 찾을 수 없음",
"settings_wallet_size_label": "지갑 크기:",
"setup_wizard": "설정 마법사",
"share": "공유",
"shield_check_status": "상태 확인",
"shield_completed": "작업이 성공적으로 완료되었습니다!",
"shield_description": "투명 주소의 코인베이스 출력을 차폐 주소로 전송하여 채굴 보상을 차폐합니다. 채굴 수입을 숨겨 프라이버시가 향상됩니다.",
"shield_from_address": "보내는 주소:",
"shield_funds": "자금 차폐",
"shield_in_progress": "작업 진행 중...",
"shield_max_utxos": "작업당 최대 UTXO 수",
"shield_merge_done": "차폐/통합이 완료되었습니다!",
"shield_operation_id": "작업 ID: %s",
"shield_select_z": "z 주소 선택...",
"shield_started": "차폐 작업이 시작되었습니다",
"shield_title": "코인베이스 보상 차폐",
"shield_to_address": "받는 주소 (차폐):",
"shield_utxo_limit": "UTXO 제한:",
"shield_wildcard_hint": "'*'를 사용하여 모든 투명 주소에서 차폐",
"shielded": "차폐",
"shielded_to": "차폐 대상",
"shielded_type": "차폐",
"show": "표시",
"show_hidden": "숨겨진 항목 표시 (%d)",
"show_qr_code": "QR 코드 표시",
"showing_transactions": "%d–%d / %d건의 거래 표시 중 (총: %zu)",
"simple_background": "단순 배경",
"start_mining": "채굴 시작",
"status": "상태",
"stop_external": "외부 데몬 중지",
"stop_mining": "채굴 중지",
"submitting_transaction": "거래 제출 중...",
"success": "성공",
"summary": "요약",
"syncing": "동기화 중...",
"t_addresses": "T 주소",
"test_connection": "테스트",
"theme": "테마",
"theme_effects": "테마 효과",
"time_days_ago": "%d일 전",
"time_hours_ago": "%d시간 전",
"time_minutes_ago": "%d분 전",
"time_seconds_ago": "%d초 전",
"to": "받는 곳",
"to_upper": "받는 곳",
"tools": "도구",
"total": "합계",
"transaction_id": "거래 ID",
"transaction_sent": "거래 전송 성공",
"transaction_sent_msg": "거래가 전송되었습니다!",
"transaction_url": "거래 URL",
"transactions": "거래",
"transactions_upper": "거래",
"transparent": "투명",
"tt_addr_url": "블록 탐색기에서 주소를 보기 위한 기본 URL",
"tt_address_book": "빠른 전송을 위해 저장된 주소 관리",
"tt_auto_lock": "이 비활성 시간 후 지갑 잠금",
"tt_auto_shield": "개인 정보 보호를 위해 투명 잔액을 자동으로 차폐 주소로 이동",
"tt_backup": "wallet.dat 백업 만들기",
"tt_block_explorer": "브라우저에서 DragonX 블록 탐색기 열기",
"tt_blur": "블러 양 (0%% = 끔, 100%% = 최대)",
"tt_change_pass": "지갑 암호화 비밀번호 변경",
"tt_change_pin": "잠금 해제 PIN 변경",
"tt_clear_ztx": "로컬에 캐시된 z-트랜잭션 기록 삭제",
"tt_custom_fees": "거래 전송 시 수동 수수료 입력 활성화",
"tt_custom_theme": "사용자 지정 테마 활성화됨",
"tt_debug_collapse": "디버그 로깅 옵션 접기",
"tt_debug_expand": "디버그 로깅 옵션 펼치기",
"tt_encrypt": "비밀번호로 wallet.dat 암호화",
"tt_export_all": "모든 개인키를 파일로 내보내기",
"tt_export_csv": "거래 내역을 CSV 스프레드시트로 내보내기",
"tt_export_key": "선택한 주소의 개인키 내보내기",
"tt_fetch_prices": "CoinGecko API에서 DRGX 시장 가격 가져오기",
"tt_font_scale": "모든 텍스트 및 UI 크기 조정 (1.0x = 기본, 최대 1.5x).",
"tt_idle_delay": "채굴 시작 전 대기 시간",
"tt_import_key": "이 지갑에 개인키 (zkey 또는 tkey) 가져오기",
"tt_keep_daemon": "설정 마법사를 실행하면 데몬이 여전히 중지됩니다",
"tt_language": "지갑 UI 인터페이스 언어",
"tt_layout_hotkey": "단축키: 좌/우 화살표 키로 잔액 레이아웃 전환",
"tt_lock": "지갑 즉시 잠금",
"tt_low_spec": "모든 고부하 시각 효과 비활성화\\n단축키: Ctrl+Shift+Down",
"tt_merge": "여러 UTXO를 하나의 주소로 통합",
"tt_mine_idle": "시스템이 유휴 상태(키보드/마우스 입력 없음)일 때\\n자동으로 채굴 시작",
"tt_noise": "그레인 텍스처 강도 (0%% = 끔, 100%% = 최대)",
"tt_open_dir": "파일 탐색기에서 열려면 클릭",
"tt_remove_encrypt": "암호화를 제거하고 지갑을 보호 없이 저장",
"tt_remove_pin": "PIN을 제거하고 잠금 해제 시 비밀번호 요구",
"tt_report_bug": "프로젝트 트래커에서 문제 보고",
"tt_request_payment": "QR 코드가 포함된 결제 요청 생성",
"tt_rescan": "누락된 거래를 찾기 위해 블록체인 재스캔",
"tt_reset_settings": "디스크에서 설정 다시 로드 (저장되지 않은 변경 사항 취소)",
"tt_restart_daemon": "디버그 로깅 변경 사항을 적용하기 위해 데몬 재시작",
"tt_rpc_host": "DragonX 데몬 호스트 이름",
"tt_rpc_pass": "RPC 인증 비밀번호",
"tt_rpc_port": "데몬 RPC 연결 포트",
"tt_rpc_user": "RPC 인증 사용자 이름",
"tt_save_settings": "모든 설정을 디스크에 저장",
"tt_save_ztx": "z-address 거래 기록을 로컬에 저장하여 빠른 로딩",
"tt_scan_themes": "새 테마 검색.\\n테마 폴더를 여기에 배치:\\n%s",
"tt_scanline": "콘솔에서 CRT 스캔라인 효과",
"tt_set_pin": "빠른 잠금 해제를 위한 4-8자리 PIN 설정",
"tt_shield_mining": "투명 채굴 보상을 차폐 주소로 이동",
"tt_simple_bg": "배경에 단순 그라데이션 사용\\n단축키: Ctrl+Up",
"tt_simple_bg_alt": "테마 배경 이미지의 그라데이션 버전 사용\\n단축키: Ctrl+Up",
"tt_stop_external": "이 지갑 외부에서 시작된\\n데몬에 연결할 때 적용",
"tt_test_conn": "데몬에 대한 RPC 연결 확인",
"tt_theme_effects": "테마별 반짝임, 글로우, 색조 순환",
"tt_theme_hotkey": "단축키: Ctrl+왼쪽/오른쪽으로 테마 전환",
"tt_tor": "익명성을 위해 데몬 연결을 Tor 네트워크를 통해 라우팅",
"tt_tx_url": "블록 탐색기에서 거래를 보기 위한 기본 URL",
"tt_ui_opacity": "카드 및 사이드바 불투명도 (100%% = 완전 불투명, 낮을수록 더 투명)",
"tt_validate": "DragonX 주소가 유효한지 확인",
"tt_verbose": "콘솔 탭에 상세 연결 진단,\\n데몬 상태 및 포트 소유자 정보 기록",
"tt_website": "DragonX 웹사이트 열기",
"tt_window_opacity": "배경 불투명도 (낮을수록 = 창을 통해 바탕 화면이 보임)",
"tt_wizard": "초기 설정 마법사 다시 실행\\n데몬이 재시작됩니다",
"tx_confirmations": "%d 확인",
"tx_details_title": "거래 상세",
"tx_from_address": "보낸 주소:",
"tx_id_label": "거래 ID:",
"tx_immature": "미성숙",
"tx_mined": "채굴됨",
"tx_received": "수신됨",
"tx_sent": "전송됨",
"tx_to_address": "받는 주소:",
"tx_view_explorer": "탐색기에서 보기",
"txs_count": "%d건",
"type": "유형",
"ui_opacity": "UI 투명도",
"unban": "차단 해제",
"unconfirmed": "미확인",
"undo_clear": "지우기 취소",
"unknown": "알 수 없음",
"use_embedded_daemon": "내장 dragonxd 사용",
"use_tor": "Tor 사용",
"validate_btn": "검증",
"validate_description": "DragonX 주소를 입력하여 유효한지 그리고 이 지갑에 속하는지 확인합니다.",
"validate_invalid": "유효하지 않음",
"validate_is_mine": "이 지갑이 이 주소를 소유합니다",
"validate_not_mine": "이 지갑에 속하지 않음",
"validate_ownership": "소유자:",
"validate_results": "결과:",
"validate_shielded_type": "차폐 (z 주소)",
"validate_status": "상태:",
"validate_title": "주소 검증",
"validate_transparent_type": "투명 (t 주소)",
"validate_type": "유형:",
"validate_valid": "유효함",
"validating": "검증 중...",
"verbose_logging": "상세 로깅",
"version": "버전",
"view": "보기",
"view_details": "상세 보기",
"view_on_explorer": "탐색기에서 보기",
"waiting_for_daemon": "데몬 연결 대기 중...",
"wallet": "지갑",
"wallet_empty": "지갑이 비어 있습니다",
"wallet_empty_hint": "수신으로 전환하여 주소를 받고 자금 수신을 시작하세요.",
"warning": "경고",
"warning_upper": "경고!",
"website": "웹사이트",
"window_opacity": "창 투명도",
"yes_clear": "예, 지우기",
"your_addresses": "내 주소",
"z_addresses": "Z 주소"
}
+789 -133
View File
@@ -1,139 +1,795 @@
{
"balance": "Saldo",
"send": "Enviar",
"receive": "Receber",
"transactions": "Transações",
"mining": "Mineração",
"peers": "Nós",
"market": "Mercado",
"settings": "Configurações",
"summary": "Resumo",
"shielded": "Protegido",
"transparent": "Transparente",
"total": "Total",
"unconfirmed": "Não confirmado",
"your_addresses": "Seus endereços",
"z_addresses": "Endereços-Z",
"t_addresses": "Endereços-T",
"no_addresses": "Nenhum endereço encontrado. Crie um usando os botões acima.",
"new_z_address": "Novo endereço-Z",
"new_t_address": "Novo endereço-T",
"type": "Tipo",
"address": "Endereço",
"copy_address": "Copiar endereço completo",
"send_from_this_address": "Enviar deste endereço",
"export_private_key": "Exportar chave privada",
"export_viewing_key": "Exportar chave de visualização",
"show_qr_code": "Mostrar código QR",
"not_connected": "Não conectado ao daemon...",
"pay_from": "Pagar de",
"send_to": "Enviar para",
"amount": "Valor",
"memo": "Memo (opcional, criptografado)",
"miner_fee": "Taxa do minerador",
"fee": "Taxa",
"send_transaction": "Enviar transação",
"clear": "Limpar",
"select_address": "Selecionar endereço...",
"paste": "Colar",
"max": "Máx.",
"available": "Disponível",
"invalid_address": "Formato de endereço inválido",
"memo_z_only": "Nota: memos só estão disponíveis ao enviar para endereços protegidos (z)",
"characters": "caracteres",
"from": "De",
"to": "Para",
"sending": "Enviando transação",
"confirm_send": "Confirmar envio",
"confirm_transaction": "Confirmar transação",
"confirm_and_send": "Confirmar e enviar",
"cancel": "Cancelar",
"receiving_addresses": "Seus endereços de recebimento",
"new_z_shielded": "Novo endereço-z (protegido)",
"new_t_transparent": "Novo endereço-t (transparente)",
"address_details": "Detalhes do endereço",
"view_on_explorer": "Ver no explorador",
"qr_code": "Código QR",
"request_payment": "Solicitar pagamento",
"date": "Data",
"status": "Status",
"confirmations": "Confirmações",
"confirmed": "Confirmada",
"pending": "Pendente",
"sent": "enviado",
"received": "recebido",
"mined": "minerado",
"mining_control": "Controle de mineração",
"start_mining": "Iniciar mineração",
"stop_mining": "Parar mineração",
"mining_threads": "Threads de mineração",
"mining_statistics": "Estatísticas de mineração",
"local_hashrate": "Hashrate local",
"network_hashrate": "Hashrate da rede",
"difficulty": "Dificuldade",
"est_time_to_block": "Tempo est. até o bloco",
"mining_off": "Mineração DESLIGADA",
"mining_on": "Mineração LIGADA",
"connected_peers": "Nós conectados",
"banned_peers": "Nós banidos",
"ip_address": "Endereço IP",
"version": "Versão",
"height": "Altura",
"ping": "Ping",
"ban": "Banir",
"unban": "Desbanir",
"clear_all_bans": "Remover todos os banimentos",
"price_chart": "Gráfico de preço",
"current_price": "Preço atual",
"24h_change": "Variação 24h",
"24h_volume": "Volume 24h",
"market_cap": "Cap. de mercado",
"general": "Geral",
"display": "Exibição",
"network": "Rede",
"theme": "Tema",
"language": "Idioma",
"dragonx_green": "DragonX (Verde)",
"dark": "Escuro",
"light": "Claro",
"allow_custom_fees": "Permitir taxas personalizadas",
"use_embedded_daemon": "Usar dragonxd embutido",
"save": "Salvar",
"close": "Fechar",
"file": "Arquivo",
"edit": "Editar",
"view": "Exibir",
"help": "Ajuda",
"import_private_key": "Importar chave privada...",
"backup_wallet": "Fazer backup da carteira...",
"exit": "Sair",
"about_dragonx": "Sobre ObsidianDragon",
"refresh_now": "Atualizar agora",
"about": "Sobre",
"import": "Importar",
"export": "Exportar",
"copy_to_clipboard": "Copiar para área de transferência",
"connected": "Conectado",
"disconnected": "Desconectado",
"connecting": "Conectando...",
"syncing": "Sincronizando...",
"block": "Bloco",
"no_addresses_available": "Nenhum endereço disponível",
"error": "Erro",
"success": "Sucesso",
"warning": "Aviso",
"about_block_explorer": "Explorador de Blocos",
"about_block_height": "Altura do Bloco:",
"about_build_date": "Data de Compilação:",
"about_build_type": "Tipo de Build:",
"about_chain": "Chain:",
"about_connections": "Conexões:",
"about_credits": "Créditos",
"about_daemon": "Daemon:",
"about_debug": "Depuração",
"about_dragonx": "Sobre o ObsidianDragon",
"about_edition": "Edição ImGui",
"about_github": "GitHub",
"about_imgui": "ImGui:",
"about_license": "Licença",
"about_license_text": "Este software é disponibilizado sob a Licença Pública Geral GNU v3 (GPLv3). Você é livre para usar, modificar e distribuir este software sob os termos da licença.",
"about_peers_count": "%zu pares",
"about_release": "Versão",
"about_title": "Sobre o ObsidianDragon",
"about_version": "Versão:",
"about_website": "Website",
"acrylic": "Acrílico",
"add": "Adicionar",
"address": "Endereço",
"address_book_add": "Adicionar Endereço",
"address_book_add_new": "Adicionar Novo",
"address_book_added": "Endereço adicionado ao livro",
"address_book_count": "%zu endereços salvos",
"address_book_deleted": "Entrada excluída",
"address_book_edit": "Editar Endereço",
"address_book_empty": "Nenhum endereço salvo. Clique em 'Adicionar Novo' para criar um.",
"address_book_exists": "Endereço já existe no livro",
"address_book_title": "Livro de Endereços",
"address_book_update_failed": "Falha na atualização - endereço pode ser duplicado",
"address_book_updated": "Endereço atualizado",
"address_copied": "Endereço copiado para a área de transferência",
"address_details": "Detalhes do Endereço",
"address_label": "Endereço:",
"address_upper": "ENDEREÇO",
"address_url": "URL do Endereço",
"addresses_appear_here": "Seus endereços de recebimento aparecerão aqui após a conexão.",
"advanced": "AVANÇADO",
"all_filter": "Todos",
"allow_custom_fees": "Permitir taxas personalizadas",
"amount": "Valor",
"amount_details": "DETALHES DO VALOR",
"amount_exceeds_balance": "Valor excede o saldo",
"transaction_sent": "Transação enviada com sucesso"
"amount_label": "Valor:",
"appearance": "APARÊNCIA",
"auto_shield": "Auto-blindar mineração",
"available": "Disponível",
"backup_backing_up": "Fazendo backup...",
"backup_create": "Criar Backup",
"backup_created": "Backup da carteira criado",
"backup_data": "BACKUP & DADOS",
"backup_description": "Crie um backup do seu arquivo wallet.dat. Este arquivo contém todas as suas chaves privadas e histórico de transações. Guarde o backup em um local seguro.",
"backup_destination": "Destino do backup:",
"backup_source": "Origem: %s",
"backup_tip_external": "Armazene backups em unidades externas ou armazenamento em nuvem",
"backup_tip_multiple": "Crie múltiplos backups em diferentes locais",
"backup_tip_test": "Teste a restauração do backup periodicamente",
"backup_tips": "Dicas:",
"backup_title": "Backup da Carteira",
"backup_wallet": "Fazer Backup da Carteira...",
"backup_wallet_not_found": "Aviso: wallet.dat não encontrado no local esperado",
"balance": "Saldo",
"balance_layout": "Layout do Saldo",
"ban": "Banir",
"banned_peers": "Pares Banidos",
"block": "Bloco",
"block_bits": "Bits:",
"block_click_copy": "Clique para copiar",
"block_click_next": "Clique para ver o próximo bloco",
"block_click_prev": "Clique para ver o bloco anterior",
"block_explorer": "Explorador de Blocos",
"block_get_info": "Obter Info do Bloco",
"block_hash": "Hash do Bloco:",
"block_hash_copied": "Hash do bloco copiado",
"block_height": "Altura do Bloco:",
"block_info_title": "Informações do Bloco",
"block_merkle_root": "Raiz Merkle:",
"block_nav_next": "Próximo >>",
"block_nav_prev": "<< Anterior",
"block_next": "Próximo Bloco:",
"block_previous": "Bloco Anterior:",
"block_size": "Tamanho:",
"block_timestamp": "Carimbo de Data:",
"block_transactions": "Transações:",
"blockchain_syncing": "Blockchain sincronizando (%.1f%%)... Os saldos podem ser imprecisos.",
"cancel": "Cancelar",
"characters": "caracteres",
"clear": "Limpar",
"clear_all_bans": "Remover Todos os Banimentos",
"clear_anyway": "Limpar mesmo assim",
"clear_form_confirm": "Limpar todos os campos do formulário?",
"clear_request": "Limpar Solicitação",
"click_copy_address": "Clique para copiar o endereço",
"click_copy_uri": "Clique para copiar a URI",
"click_to_copy": "Clique para copiar",
"close": "Fechar",
"conf_count": "%d conf.",
"confirm_and_send": "Confirmar & Enviar",
"confirm_clear_ztx_title": "Confirmar limpeza do histórico Z-Tx",
"confirm_clear_ztx_warning1": "Limpar o histórico de z-transações pode fazer com que seu saldo blindado apareça como 0 até que um reescaneamento da carteira seja realizado.",
"confirm_clear_ztx_warning2": "Se isso acontecer, você precisará reimportar as chaves privadas do seu endereço z com reescaneamento habilitado para recuperar seu saldo.",
"confirm_send": "Confirmar Envio",
"confirm_transaction": "Confirmar Transação",
"confirmations": "Confirmações",
"confirmations_display": "%d confirmações | %s",
"confirmed": "Confirmado",
"connected": "Conectado",
"connected_peers": "Pares Conectados",
"connecting": "Conectando...",
"console": "Console",
"console_auto_scroll": "Rolagem automática",
"console_available_commands": "Comandos disponíveis:",
"console_capturing_output": "Capturando saída do daemon...",
"console_clear": "Limpar",
"console_clear_console": "Limpar Console",
"console_cleared": "Console limpo",
"console_click_commands": "Clique nos comandos acima para inseri-los",
"console_click_insert": "Clique para inserir",
"console_click_insert_params": "Clique para inserir com parâmetros",
"console_close": "Fechar",
"console_commands": "Comandos",
"console_common_rpc": "Comandos RPC comuns:",
"console_completions": "Completações:",
"console_connected": "Conectado ao daemon",
"console_copy_all": "Copiar Tudo",
"console_copy_selected": "Copiar",
"console_daemon": "Daemon",
"console_daemon_error": "Erro do daemon!",
"console_daemon_started": "Daemon iniciado",
"console_daemon_stopped": "Daemon parado",
"console_disconnected": "Desconectado do daemon",
"console_errors": "Erros",
"console_filter_hint": "Filtrar saída...",
"console_help_clear": " clear - Limpar o console",
"console_help_getbalance": " getbalance - Mostrar saldo transparente",
"console_help_getblockcount": " getblockcount - Mostrar altura atual do bloco",
"console_help_getinfo": " getinfo - Mostrar informações do nó",
"console_help_getmininginfo": " getmininginfo - Mostrar status da mineração",
"console_help_getpeerinfo": " getpeerinfo - Mostrar pares conectados",
"console_help_gettotalbalance": " gettotalbalance - Mostrar saldo total",
"console_help_help": " help - Mostrar esta mensagem de ajuda",
"console_help_setgenerate": " setgenerate - Controlar mineração",
"console_help_stop": " stop - Parar o daemon",
"console_line_count": "%zu linhas",
"console_new_lines": "%d novas linhas",
"console_no_daemon": "Sem daemon",
"console_not_connected": "Erro: Não conectado ao daemon",
"console_rpc_reference": "Referência de Comandos RPC",
"console_scanline": "Scanline do console",
"console_search_commands": "Pesquisar comandos...",
"console_select_all": "Selecionar Tudo",
"console_show_daemon_output": "Mostrar saída do daemon",
"console_show_errors_only": "Mostrar apenas erros",
"console_show_rpc_ref": "Mostrar referência de comandos RPC",
"console_showing_lines": "Mostrando %zu de %zu linhas",
"console_starting_node": "Iniciando nó...",
"console_status_error": "Erro",
"console_status_running": "Em execução",
"console_status_starting": "Iniciando",
"console_status_stopped": "Parado",
"console_status_stopping": "Parando",
"console_status_unknown": "Desconhecido",
"console_tab_completion": "Tab para completar",
"console_type_help": "Digite 'help' para comandos disponíveis",
"console_welcome": "Bem-vindo ao Console ObsidianDragon",
"console_zoom_in": "Aumentar zoom",
"console_zoom_out": "Diminuir zoom",
"copy": "Copiar",
"copy_address": "Copiar Endereço Completo",
"copy_error": "Copiar Erro",
"copy_to_clipboard": "Copiar para Área de Transferência",
"copy_txid": "Copiar TxID",
"copy_uri": "Copiar URI",
"current_price": "Preço Atual",
"custom_fees": "Taxas personalizadas",
"dark": "Escuro",
"date": "Data",
"date_label": "Data:",
"debug_logging": "REGISTRO DE DEPURAÇÃO",
"delete": "Excluir",
"difficulty": "Dificuldade",
"disconnected": "Desconectado",
"dismiss": "Dispensar",
"display": "Exibição",
"dragonx_green": "DragonX (Verde)",
"edit": "Editar",
"error": "Erro",
"error_format": "Erro: %s",
"est_time_to_block": "Tempo Est. por Bloco",
"exit": "Sair",
"explorer": "EXPLORADOR",
"export": "Exportar",
"export_csv": "Exportar CSV",
"export_keys_btn": "Exportar Chaves",
"export_keys_danger": "PERIGO: Isto exportará TODAS as chaves privadas da sua carteira! Qualquer pessoa com acesso a este arquivo pode roubar seus fundos. Guarde com segurança e exclua após o uso.",
"export_keys_include_t": "Incluir endereços T (transparentes)",
"export_keys_include_z": "Incluir endereços Z (blindados)",
"export_keys_options": "Opções de exportação:",
"export_keys_progress": "Exportando %d/%d...",
"export_keys_success": "Chaves exportadas com sucesso",
"export_keys_title": "Exportar Todas as Chaves Privadas",
"export_private_key": "Exportar Chave Privada",
"export_tx_count": "Exportar %zu transações para arquivo CSV.",
"export_tx_file_fail": "Falha ao criar arquivo CSV",
"export_tx_none": "Nenhuma transação para exportar",
"export_tx_success": "Transações exportadas com sucesso",
"export_tx_title": "Exportar Transações para CSV",
"export_viewing_key": "Exportar Chave de Visualização",
"failed_create_shielded": "Falha ao criar endereço blindado",
"failed_create_transparent": "Falha ao criar endereço transparente",
"favorite_address": "Adicionar aos favoritos",
"fee": "Taxa",
"fee_high": "Alta",
"fee_label": "Taxa:",
"fee_low": "Baixa",
"fee_normal": "Normal",
"fetch_prices": "Buscar preços",
"file": "Arquivo",
"file_save_location": "O arquivo será salvo em: ~/.config/ObsidianDragon/",
"font_scale": "Escala da Fonte",
"from": "De",
"from_upper": "DE",
"full_details": "Detalhes Completos",
"general": "Geral",
"go_to_receive": "Ir para Receber",
"height": "Altura",
"help": "Ajuda",
"hide": "Ocultar",
"hide_address": "Ocultar endereço",
"hide_zero_balances": "Ocultar saldos zero",
"history": "Histórico",
"immature_type": "Imaturo",
"import": "Importar",
"import_key_btn": "Importar Chave(s)",
"import_key_formats": "Formatos de chave suportados:",
"import_key_full_rescan": "(0 = rescan completo)",
"import_key_label": "Chave(s) Privada(s):",
"import_key_no_valid": "Nenhuma chave válida encontrada na entrada",
"import_key_progress": "Importando %d/%d...",
"import_key_rescan": "Reescanear blockchain após importação",
"import_key_start_height": "Altura inicial:",
"import_key_success": "Chaves importadas com sucesso",
"import_key_t_format": "Chaves privadas WIF de endereços T",
"import_key_title": "Importar Chave Privada",
"import_key_tooltip": "Digite uma ou mais chaves privadas, uma por linha.\nSuporta chaves de z-endereço e t-endereço.\nLinhas começando com # são tratadas como comentários.",
"import_key_warning": "Aviso: Nunca compartilhe suas chaves privadas! Importar chaves de fontes não confiáveis pode comprometer sua carteira.",
"import_key_z_format": "Chaves de gasto de z-endereço (secret-extended-key-...)",
"import_private_key": "Importar Chave Privada...",
"invalid_address": "Formato de endereço inválido",
"ip_address": "Endereço IP",
"keep": "Manter",
"keep_daemon": "Manter daemon em execução",
"key_export_click_retrieve": "Clique para recuperar a chave da sua carteira",
"key_export_fetching": "Buscando chave da carteira...",
"key_export_private_key": "Chave Privada:",
"key_export_private_warning": "Mantenha esta chave em SEGREDO! Qualquer pessoa com esta chave pode gastar seus fundos. Nunca a compartilhe online ou com terceiros não confiáveis.",
"key_export_reveal": "Revelar Chave",
"key_export_viewing_key": "Chave de Visualização:",
"key_export_viewing_keys_zonly": "As chaves de visualização estão disponíveis apenas para endereços blindados (z)",
"key_export_viewing_warning": "Esta chave de visualização permite que outros vejam suas transações recebidas e saldo, mas NÃO gastem seus fundos. Compartilhe apenas com partes confiáveis.",
"label": "Rótulo:",
"language": "Idioma",
"light": "Claro",
"loading": "Carregando...",
"loading_addresses": "Carregando endereços...",
"local_hashrate": "Hashrate Local",
"low_spec_mode": "Modo econômico",
"market": "Mercado",
"market_12h": "12h",
"market_18h": "18h",
"market_24h": "24h",
"market_24h_volume": "VOLUME 24H",
"market_6h": "6h",
"market_attribution": "Dados de preço do NonKYC",
"market_btc_price": "PREÇO BTC",
"market_cap": "Capitalização",
"market_no_history": "Nenhum histórico de preços disponível",
"market_no_price": "Sem dados de preço",
"market_now": "Agora",
"market_pct_shielded": "%.0f%% Blindado",
"market_portfolio": "PORTFÓLIO",
"market_price_unavailable": "Dados de preço indisponíveis",
"market_refresh_price": "Atualizar dados de preço",
"market_trade_on": "Negociar no %s",
"mature": "Maduro",
"max": "Máx",
"memo": "Memo (opcional, criptografado)",
"memo_label": "Memo:",
"memo_optional": "MEMO (OPCIONAL)",
"memo_upper": "MEMO",
"memo_z_only": "Nota: Memos só estão disponíveis ao enviar para endereços blindados (z)",
"merge_description": "Fundir múltiplos UTXOs em um único endereço blindado. Isso pode ajudar a reduzir o tamanho da carteira e melhorar a privacidade.",
"merge_funds": "Fundir Fundos",
"merge_started": "Operação de fusão iniciada",
"merge_title": "Fundir para Endereço",
"mine_when_idle": "Minerar quando ocioso",
"mined": "minerado",
"mined_filter": "Minerado",
"mined_type": "Minerado",
"mined_upper": "MINERADO",
"miner_fee": "Taxa de Minerador",
"mining": "Mineração",
"mining_active": "Ativo",
"mining_address_copied": "Endereço de mineração copiado",
"mining_all_time": "Todo o Tempo",
"mining_already_saved": "URL do pool já salva",
"mining_block_copied": "Hash do bloco copiado",
"mining_chart_1m_ago": "1m atrás",
"mining_chart_5m_ago": "5m atrás",
"mining_chart_now": "Agora",
"mining_chart_start": "Início",
"mining_click": "Clique",
"mining_click_copy_address": "Clique para copiar o endereço",
"mining_click_copy_block": "Clique para copiar o hash do bloco",
"mining_click_copy_difficulty": "Clique para copiar a dificuldade",
"mining_connected": "Conectado",
"mining_connecting": "Conectando...",
"mining_control": "Controle de Mineração",
"mining_difficulty_copied": "Dificuldade copiada",
"mining_est_block": "Bloco Est.",
"mining_est_daily": "Est. Diário",
"mining_filter_all": "Todos",
"mining_filter_tip_all": "Mostrar todos os ganhos",
"mining_filter_tip_pool": "Mostrar apenas ganhos do pool",
"mining_filter_tip_solo": "Mostrar apenas ganhos solo",
"mining_idle_off_tooltip": "Ativar mineração ociosa",
"mining_idle_on_tooltip": "Desativar mineração ociosa",
"mining_local_hashrate": "Hashrate Local",
"mining_mine": "Minerar",
"mining_mining_addr": "End. Mineração",
"mining_network": "Rede",
"mining_no_blocks_yet": "Nenhum bloco encontrado ainda",
"mining_no_payouts_yet": "Nenhum pagamento de pool ainda",
"mining_no_saved_addresses": "Nenhum endereço salvo",
"mining_no_saved_pools": "Nenhum pool salvo",
"mining_off": "Mineração está DESLIGADA",
"mining_on": "Mineração está LIGADA",
"mining_open_in_explorer": "Abrir no explorador",
"mining_payout_address": "Endereço de Pagamento",
"mining_payout_tooltip": "Endereço para receber recompensas de mineração",
"mining_pool": "Pool",
"mining_pool_hashrate": "Hashrate do Pool",
"mining_pool_url": "URL do Pool",
"mining_recent_blocks": "BLOCOS RECENTES",
"mining_recent_payouts": "PAGAMENTOS DE POOL RECENTES",
"mining_remove": "Remover",
"mining_reset_defaults": "Redefinir Padrões",
"mining_save_payout_address": "Salvar endereço de pagamento",
"mining_save_pool_url": "Salvar URL do pool",
"mining_saved_addresses": "Endereços Salvos:",
"mining_saved_pools": "Pools Salvos:",
"mining_shares": "Shares",
"mining_show_chart": "Gráfico",
"mining_show_log": "Log",
"mining_solo": "Solo",
"mining_starting": "Iniciando...",
"mining_starting_tooltip": "Minerador está iniciando...",
"mining_statistics": "Estatísticas de Mineração",
"mining_stop": "Parar",
"mining_stop_solo_for_pool": "Pare a mineração solo antes de iniciar a mineração em pool",
"mining_stop_solo_for_pool_settings": "Pare a mineração solo para alterar as configurações do pool",
"mining_stopping": "Parando...",
"mining_stopping_tooltip": "Minerador está parando...",
"mining_syncing_tooltip": "Blockchain está sincronizando...",
"mining_threads": "Threads de Mineração",
"mining_to_save": "para salvar",
"mining_today": "Hoje",
"mining_uptime": "Tempo Ativo",
"mining_yesterday": "Ontem",
"network": "Rede",
"network_fee": "TAXA DA REDE",
"network_hashrate": "Hashrate da Rede",
"new": "+ Novo",
"new_shielded_created": "Novo endereço blindado criado",
"new_t_address": "Novo Endereço T",
"new_t_transparent": "Novo endereço t (Transparente)",
"new_transparent_created": "Novo endereço transparente criado",
"new_z_address": "Novo Endereço Z",
"new_z_shielded": "Novo endereço z (Blindado)",
"no_addresses": "Nenhum endereço encontrado. Crie um usando os botões acima.",
"no_addresses_available": "Nenhum endereço disponível",
"no_addresses_match": "Nenhum endereço corresponde ao filtro",
"no_addresses_with_balance": "Nenhum endereço com saldo",
"no_matching": "Nenhuma transação correspondente",
"no_recent_receives": "Nenhum recebimento recente",
"no_recent_sends": "Nenhum envio recente",
"no_transactions": "Nenhuma transação encontrada",
"node": "NÓ",
"node_security": "NÓ & SEGURANÇA",
"noise": "Ruído",
"not_connected": "Não conectado ao daemon...",
"not_connected_to_daemon": "Não conectado ao daemon",
"notes": "Notas",
"notes_optional": "Notas (opcional):",
"output_filename": "Nome do arquivo de saída:",
"overview": "Visão Geral",
"paste": "Colar",
"paste_from_clipboard": "Colar da Área de Transferência",
"pay_from": "Pagar de",
"payment_request": "SOLICITAÇÃO DE PAGAMENTO",
"payment_request_copied": "Solicitação de pagamento copiada",
"payment_uri_copied": "URI de pagamento copiada",
"peers": "Pares",
"peers_avg_ping": "Ping Médio",
"peers_ban_24h": "Banir Par 24h",
"peers_ban_score": "Score de Ban: %d",
"peers_banned": "Banidos",
"peers_banned_count": "Banidos: %d",
"peers_best_block": "Melhor Bloco",
"peers_blockchain": "BLOCKCHAIN",
"peers_blocks": "Blocos",
"peers_blocks_left": "%d blocos restantes",
"peers_clear_all_bans": "Remover Todos os Banimentos",
"peers_click_copy": "Clique para copiar",
"peers_connected": "Conectados",
"peers_connected_count": "Conectados: %d",
"peers_copy_ip": "Copiar IP",
"peers_dir_in": "Ent.",
"peers_dir_out": "Saí.",
"peers_hash_copied": "Hash copiado",
"peers_hashrate": "Hashrate",
"peers_in_out": "Ent./Saí.",
"peers_longest": "Mais longa",
"peers_longest_chain": "Chain Mais Longa",
"peers_memory": "Memória",
"peers_no_banned": "Nenhum par banido",
"peers_no_connected": "Nenhum par conectado",
"peers_no_tls": "Sem TLS",
"peers_notarized": "Notarizado",
"peers_p2p_port": "Porta P2P",
"peers_peer_label": "Peer: %s",
"peers_protocol": "Protocolo",
"peers_received": "Recebido",
"peers_refresh": "Atualizar",
"peers_refresh_tooltip": "Atualizar lista de pares",
"peers_refreshing": "Atualizando...",
"peers_sent": "Enviado",
"peers_tt_id": "ID: %d",
"peers_tt_received": "Recebido: %s",
"peers_tt_sent": "Enviado: %s",
"peers_tt_services": "Serviços: %s",
"peers_tt_start_height": "Altura Inicial: %d",
"peers_tt_synced": "Sincronizado H/B: %d/%d",
"peers_tt_tls_cipher": "TLS: %s",
"peers_unban": "Desbanir",
"peers_upper": "PARES",
"peers_version": "Versão",
"pending": "Pendente",
"ping": "Ping",
"price_chart": "Gráfico de Preços",
"qr_code": "Código QR",
"qr_failed": "Falha ao gerar código QR",
"qr_title": "Código QR",
"qr_unavailable": "QR indisponível",
"ram_daemon_gb": "Daemon: %.1f GB (%s)",
"ram_daemon_mb": "Daemon: %.0f MB (%s)",
"ram_system_gb": "Sistema: %.1f / %.0f GB",
"ram_wallet_gb": "Carteira: %.1f GB",
"ram_wallet_mb": "Carteira: %.0f MB",
"receive": "Receber",
"received": "recebido",
"received_filter": "Recebido",
"received_label": "Recebido",
"received_upper": "RECEBIDO",
"receiving_addresses": "Seus Endereços de Recebimento",
"recent_received": "RECEBIDOS RECENTES",
"recent_sends": "ENVIOS RECENTES",
"recipient": "DESTINATÁRIO",
"recv_type": "Receb.",
"refresh": "Atualizar",
"refresh_now": "Atualizar Agora",
"remove_favorite": "Remover favorito",
"report_bug": "Reportar Bug",
"request_amount": "Valor (opcional):",
"request_copy_uri": "Copiar URI",
"request_description": "Gere uma solicitação de pagamento que outros podem escanear ou copiar. O código QR contém seu endereço e valor/memo opcionais.",
"request_label": "Rótulo (opcional):",
"request_memo": "Memo (opcional):",
"request_payment": "Solicitar Pagamento",
"request_payment_uri": "URI de Pagamento:",
"request_receive_address": "Endereço de Recebimento:",
"request_select_address": "Selecionar endereço...",
"request_shielded_addrs": "-- Endereços Blindados --",
"request_title": "Solicitar Pagamento",
"request_transparent_addrs": "-- Endereços Transparentes --",
"request_uri_copied": "URI de pagamento copiada para a área de transferência",
"rescan": "Reescanear",
"reset_to_defaults": "Redefinir Padrões",
"restore_address": "Restaurar endereço",
"review_send": "Revisar Envio",
"rpc_host": "Host RPC",
"rpc_pass": "Senha",
"rpc_port": "Porta",
"rpc_user": "Usuário",
"save": "Salvar",
"save_settings": "Salvar Configurações",
"save_z_transactions": "Salvar Z-tx na lista de tx",
"search_placeholder": "Pesquisar...",
"security": "SEGURANÇA",
"select_address": "Selecionar endereço...",
"select_receiving_address": "Selecionar endereço de recebimento...",
"select_source_address": "Selecionar endereço de origem...",
"send": "Enviar",
"send_amount": "Valor",
"send_amount_details": "DETALHES DO VALOR",
"send_amount_upper": "VALOR",
"send_clear_fields": "Limpar todos os campos do formulário?",
"send_copy_error": "Copiar Erro",
"send_dismiss": "Dispensar",
"send_error_copied": "Erro copiado para a área de transferência",
"send_error_prefix": "Erro: %s",
"send_exceeds_available": "Excede o disponível (%.8f)",
"send_fee": "Taxa",
"send_fee_high": "Alta",
"send_fee_low": "Baixa",
"send_fee_normal": "Normal",
"send_form_restored": "Formulário restaurado",
"send_from_this_address": "Enviar deste endereço",
"send_go_to_receive": "Ir para Receber",
"send_keep": "Manter",
"send_network_fee": "TAXA DA REDE",
"send_no_balance": "Sem saldo",
"send_no_recent": "Nenhum envio recente",
"send_recent_sends": "ENVIOS RECENTES",
"send_recipient": "DESTINATÁRIO",
"send_select_source": "Selecionar endereço de origem...",
"send_sending_from": "ENVIANDO DE",
"send_submitting": "Enviando transação...",
"send_switch_to_receive": "Mude para Receber para obter seu endereço e começar a receber fundos.",
"send_to": "Enviar para",
"send_tooltip_enter_amount": "Digite um valor para enviar",
"send_tooltip_exceeds_balance": "Valor excede o saldo disponível",
"send_tooltip_in_progress": "Transação já em andamento",
"send_tooltip_invalid_address": "Digite um endereço de destinatário válido",
"send_tooltip_not_connected": "Não conectado ao daemon",
"send_tooltip_select_source": "Selecione primeiro um endereço de origem",
"send_tooltip_syncing": "Aguarde a sincronização da blockchain",
"send_total": "Total",
"send_transaction": "Enviar Transação",
"send_tx_failed": "Transação falhou",
"send_tx_sent": "Transação enviada!",
"send_tx_success": "Transação enviada com sucesso!",
"send_txid_copied": "TxID copiado para a área de transferência",
"send_txid_label": "TxID: %s",
"send_valid_shielded": "Endereço blindado válido",
"send_valid_transparent": "Endereço transparente válido",
"send_wallet_empty": "Sua carteira está vazia",
"send_yes_clear": "Sim, Limpar",
"sending": "Enviando transação",
"sending_from": "ENVIANDO DE",
"sent": "enviado",
"sent_filter": "Enviado",
"sent_type": "Enviado",
"sent_upper": "ENVIADO",
"settings": "Configurações",
"settings_about_text": "Uma carteira de criptomoeda blindada para DragonX (DRGX), criada com Dear ImGui para uma experiência leve e portátil.",
"settings_acrylic_level": "Nível acrílico:",
"settings_address_book": "Livro de endereços...",
"settings_auto_detected": "Detectado automaticamente de DRAGONX.conf",
"settings_auto_lock": "BLOQUEIO AUTOMÁTICO",
"settings_auto_shield_desc": "Mover automaticamente fundos transparentes para endereços blindados",
"settings_auto_shield_funds": "Blindar fundos transparentes automaticamente",
"settings_backup": "Backup...",
"settings_block_explorer_urls": "URLs do explorador de blocos",
"settings_builtin": "Integrado",
"settings_change_passphrase": "Alterar frase secreta",
"settings_change_pin": "Alterar PIN",
"settings_clear_ztx": "Limpar histórico Z-Tx",
"settings_clear_ztx_desc": "Excluir dados de transações blindadas armazenados localmente",
"settings_clear_ztx_long": "Limpar histórico salvo de Z-transações",
"settings_configure_explorer": "Configurar links do explorador de blocos externo",
"settings_configure_rpc": "Configurar conexão ao daemon dragonxd",
"settings_connection": "Conexão",
"settings_copyright": "Copyright 2024-2026 Desenvolvedores DragonX | Licença GPLv3",
"settings_custom": "Personalizado",
"settings_data_dir": "Dir. de dados:",
"settings_debug_changed": "Categorias de depuração alteradas — reinicie o daemon para aplicar",
"settings_debug_restart_note": "As alterações entram em vigor após reiniciar o daemon.",
"settings_debug_select": "Selecione categorias para ativar o registro de depuração do daemon (flags -debug=).",
"settings_encrypt_first_pin": "Encripte a carteira primeiro para ativar o PIN",
"settings_encrypt_wallet": "Encriptar carteira",
"settings_explorer_hint": "As URLs devem incluir uma barra final. O txid/endereço será adicionado.",
"settings_export_all": "Exportar tudo...",
"settings_export_csv": "Exportar CSV...",
"settings_export_key": "Exportar chave...",
"settings_gradient_bg": "Fundo gradiente",
"settings_gradient_desc": "Substituir fundos texturizados por gradientes suaves",
"settings_idle_after": "após",
"settings_import_key": "Importar chave...",
"settings_language_note": "Nota: Alguns textos requerem reinício para atualizar",
"settings_lock_now": "Bloquear agora",
"settings_locked": "Bloqueado",
"settings_merge_to_address": "Fundir para endereço...",
"settings_noise_opacity": "Opacidade do ruído:",
"settings_not_encrypted": "Não encriptado",
"settings_not_found": "Não encontrado",
"settings_other": "Outros",
"settings_pin_active": "PIN",
"settings_privacy": "Privacidade",
"settings_quick_unlock_pin": "PIN de desbloqueio rápido",
"settings_reduce_transparency": "Reduzir transparência",
"settings_remove_encryption": "Remover encriptação",
"settings_remove_pin": "Remover PIN",
"settings_request_payment": "Solicitar pagamento...",
"settings_rescan_desc": "Reescanear a blockchain em busca de transações ausentes",
"settings_restart_daemon": "Reiniciar daemon",
"settings_rpc_connection": "Conexão RPC",
"settings_rpc_note": "Nota: As configurações de conexão são normalmente detectadas automaticamente do DRAGONX.conf",
"settings_save_shielded_desc": "Armazena transações z-addr em um arquivo local para visualização",
"settings_save_shielded_local": "Salvar histórico de transações blindadas localmente",
"settings_set_pin": "Definir PIN",
"settings_shield_mining": "Blindar mineração...",
"settings_solid_colors_desc": "Usar cores sólidas em vez de efeitos de desfoque (acessibilidade)",
"settings_tor_desc": "Rotear todas as conexões através do Tor para maior privacidade",
"settings_unlocked": "Desbloqueado",
"settings_use_tor_network": "Usar Tor para conexões de rede",
"settings_validate_address": "Validar endereço...",
"settings_visual_effects": "Efeitos visuais",
"settings_wallet_file_size": "Tamanho do arquivo da carteira: %s",
"settings_wallet_info": "Informações da carteira",
"settings_wallet_location": "Localização da carteira: %s",
"settings_wallet_maintenance": "Manutenção da carteira",
"settings_wallet_not_found": "Arquivo da carteira não encontrado",
"settings_wallet_size_label": "Tamanho da carteira:",
"setup_wizard": "Assistente de Configuração",
"share": "Compartilhar",
"shield_check_status": "Verificar Status",
"shield_completed": "Operação concluída com sucesso!",
"shield_description": "Blinde suas recompensas de mineração enviando saídas coinbase de endereços transparentes para um endereço blindado. Isso melhora a privacidade ocultando sua renda de mineração.",
"shield_from_address": "Do Endereço:",
"shield_funds": "Blindar Fundos",
"shield_in_progress": "Operação em andamento...",
"shield_max_utxos": "Máx. UTXOs por operação",
"shield_merge_done": "Blindagem/fusão concluída!",
"shield_operation_id": "ID da operação: %s",
"shield_select_z": "Selecionar z-endereço...",
"shield_started": "Operação de blindagem iniciada",
"shield_title": "Blindar Recompensas Coinbase",
"shield_to_address": "Para Endereço (Blindado):",
"shield_utxo_limit": "Limite UTXO:",
"shield_wildcard_hint": "Use '*' para blindar de todos os endereços transparentes",
"shielded": "Blindado",
"shielded_to": "BLINDADO PARA",
"shielded_type": "Blindado",
"show": "Mostrar",
"show_hidden": "Mostrar ocultos (%d)",
"show_qr_code": "Mostrar Código QR",
"showing_transactions": "Mostrando %d–%d de %d transações (total: %zu)",
"simple_background": "Fundo simples",
"start_mining": "Iniciar Mineração",
"status": "Status",
"stop_external": "Parar daemon externo",
"stop_mining": "Parar Mineração",
"submitting_transaction": "Enviando transação...",
"success": "Sucesso",
"summary": "Resumo",
"syncing": "Sincronizando...",
"t_addresses": "Endereços T",
"test_connection": "Testar",
"theme": "Tema",
"theme_effects": "Efeitos de tema",
"time_days_ago": "há %d dias",
"time_hours_ago": "há %d horas",
"time_minutes_ago": "há %d minutos",
"time_seconds_ago": "há %d segundos",
"to": "Para",
"to_upper": "PARA",
"tools": "FERRAMENTAS",
"total": "Total",
"transaction_id": "ID DA TRANSAÇÃO",
"transaction_sent": "Transação enviada com sucesso",
"transaction_sent_msg": "Transação enviada!",
"transaction_url": "URL da Transação",
"transactions": "Transações",
"transactions_upper": "TRANSAÇÕES",
"transparent": "Transparente",
"tt_addr_url": "URL base para visualizar endereços em um explorador de blocos",
"tt_address_book": "Gerenciar endereços salvos para envio rápido",
"tt_auto_lock": "Bloquear carteira após este tempo de inatividade",
"tt_auto_shield": "Mover automaticamente o saldo transparente para endereços blindados para privacidade",
"tt_backup": "Criar um backup do seu wallet.dat",
"tt_block_explorer": "Abrir o explorador de blocos DragonX no seu navegador",
"tt_blur": "Quantidade de desfoque (0%% = desligado, 100%% = máximo)",
"tt_change_pass": "Alterar a frase secreta de encriptação da carteira",
"tt_change_pin": "Alterar seu PIN de desbloqueio",
"tt_clear_ztx": "Excluir histórico de z-transações em cache local",
"tt_custom_fees": "Ativar entrada manual de taxas ao enviar transações",
"tt_custom_theme": "Tema personalizado ativo",
"tt_debug_collapse": "Recolher opções de registro de depuração",
"tt_debug_expand": "Expandir opções de registro de depuração",
"tt_encrypt": "Encriptar wallet.dat com uma frase secreta",
"tt_export_all": "Exportar todas as chaves privadas para um arquivo",
"tt_export_csv": "Exportar histórico de transações como planilha CSV",
"tt_export_key": "Exportar a chave privada do endereço selecionado",
"tt_fetch_prices": "Obter preços de mercado DRGX da API CoinGecko",
"tt_font_scale": "Escalar todo o texto e interface (1.0x = padrão, até 1.5x).",
"tt_idle_delay": "Quanto tempo esperar antes de iniciar a mineração",
"tt_import_key": "Importar uma chave privada (zkey ou tkey) nesta carteira",
"tt_keep_daemon": "O daemon será parado ao executar o assistente de configuração",
"tt_language": "Idioma da interface da carteira",
"tt_layout_hotkey": "Atalho: teclas de seta esquerda/direita para alternar layouts de Saldo",
"tt_lock": "Bloquear a carteira imediatamente",
"tt_low_spec": "Desativar todos os efeitos visuais pesados\\nAtalho: Ctrl+Shift+Down",
"tt_merge": "Consolidar múltiplos UTXOs em um endereço",
"tt_mine_idle": "Iniciar mineração automaticamente quando o\\nsistema estiver ocioso (sem entrada de teclado/mouse)",
"tt_noise": "Intensidade de textura granulada (0%% = desligado, 100%% = máximo)",
"tt_open_dir": "Clique para abrir no explorador de arquivos",
"tt_remove_encrypt": "Remover encriptação e armazenar a carteira desprotegida",
"tt_remove_pin": "Remover PIN e exigir frase secreta para desbloquear",
"tt_report_bug": "Reportar um problema no rastreador do projeto",
"tt_request_payment": "Gerar uma solicitação de pagamento com código QR",
"tt_rescan": "Reescanear a blockchain em busca de transações ausentes",
"tt_reset_settings": "Recarregar configurações do disco (desfazer alterações não salvas)",
"tt_restart_daemon": "Reiniciar o daemon para aplicar alterações de registro de depuração",
"tt_rpc_host": "Nome do host do daemon DragonX",
"tt_rpc_pass": "Senha de autenticação RPC",
"tt_rpc_port": "Porta para conexões RPC do daemon",
"tt_rpc_user": "Nome de usuário de autenticação RPC",
"tt_save_settings": "Salvar todas as configurações no disco",
"tt_save_ztx": "Armazenar histórico de transações z-address localmente para carregamento mais rápido",
"tt_scan_themes": "Procurar novos temas.\\nColoque pastas de temas em:\\n%s",
"tt_scanline": "Efeito de linhas de varredura CRT no console",
"tt_set_pin": "Definir um PIN de 4-8 dígitos para desbloqueio rápido",
"tt_shield_mining": "Mover recompensas de mineração transparentes para um endereço blindado",
"tt_simple_bg": "Usar um gradiente simples para o fundo\\nAtalho: Ctrl+Up",
"tt_simple_bg_alt": "Usar uma versão gradiente da imagem de fundo do tema\\nAtalho: Ctrl+Up",
"tt_stop_external": "Aplica-se ao conectar a um daemon\\niniciado fora desta carteira",
"tt_test_conn": "Verificar a conexão RPC ao daemon",
"tt_theme_effects": "Brilho, luminescência, ciclo de matiz por tema",
"tt_theme_hotkey": "Atalho: Ctrl+Esquerda/Direita para alternar temas",
"tt_tor": "Rotear conexões do daemon através da rede Tor para anonimato",
"tt_tx_url": "URL base para visualizar transações em um explorador de blocos",
"tt_ui_opacity": "Opacidade de cartões e barra lateral (100%% = totalmente opaco, menor = mais transparente)",
"tt_validate": "Verificar se um endereço DragonX é válido",
"tt_verbose": "Registrar diagnósticos detalhados de conexão,\\nestado do daemon e info de proprietário de porta\\nna aba Console",
"tt_website": "Abrir o site do DragonX",
"tt_window_opacity": "Opacidade do fundo (menor = área de trabalho visível através da janela)",
"tt_wizard": "Executar novamente o assistente de configuração inicial\\nO daemon será reiniciado",
"tx_confirmations": "%d confirmações",
"tx_details_title": "Detalhes da Transação",
"tx_from_address": "Endereço de Origem:",
"tx_id_label": "ID da Transação:",
"tx_immature": "IMATURO",
"tx_mined": "MINERADO",
"tx_received": "RECEBIDO",
"tx_sent": "ENVIADO",
"tx_to_address": "Endereço de Destino:",
"tx_view_explorer": "Ver no Explorador",
"txs_count": "%d txs",
"type": "Tipo",
"ui_opacity": "Opacidade da Interface",
"unban": "Desbanir",
"unconfirmed": "Não confirmado",
"undo_clear": "Desfazer Limpeza",
"unknown": "Desconhecido",
"use_embedded_daemon": "Usar dragonxd integrado",
"use_tor": "Usar Tor",
"validate_btn": "Validar",
"validate_description": "Digite um endereço DragonX para verificar se é válido e se pertence a esta carteira.",
"validate_invalid": "INVÁLIDO",
"validate_is_mine": "Esta carteira possui este endereço",
"validate_not_mine": "Não pertence a esta carteira",
"validate_ownership": "Propriedade:",
"validate_results": "Resultados:",
"validate_shielded_type": "Blindado (z-endereço)",
"validate_status": "Status:",
"validate_title": "Validar Endereço",
"validate_transparent_type": "Transparente (t-endereço)",
"validate_type": "Tipo:",
"validate_valid": "VÁLIDO",
"validating": "Validando...",
"verbose_logging": "Log detalhado",
"version": "Versão",
"view": "Visualizar",
"view_details": "Ver Detalhes",
"view_on_explorer": "Ver no Explorador",
"waiting_for_daemon": "Aguardando conexão com o daemon...",
"wallet": "CARTEIRA",
"wallet_empty": "Sua carteira está vazia",
"wallet_empty_hint": "Mude para Receber para obter seu endereço e começar a receber fundos.",
"warning": "Aviso",
"warning_upper": "AVISO!",
"website": "Website",
"window_opacity": "Opacidade da Janela",
"yes_clear": "Sim, Limpar",
"your_addresses": "Seus Endereços",
"z_addresses": "Endereços Z"
}
+789 -133
View File
@@ -1,139 +1,795 @@
{
"balance": "Баланс",
"send": "Отправить",
"receive": "Получить",
"transactions": "Транзакции",
"mining": "Майнинг",
"peers": "Узлы",
"market": "Рынок",
"settings": "Настройки",
"summary": "Сводка",
"shielded": "Защищённый",
"transparent": "Прозрачный",
"total": "Итого",
"unconfirmed": "Неподтверждённые",
"your_addresses": "Ваши адреса",
"z_addresses": "Z-адреса",
"t_addresses": "T-адреса",
"no_addresses": "Адреса не найдены. Создайте адрес с помощью кнопок выше.",
"new_z_address": "Новый Z-адрес",
"new_t_address": "Новый T-адрес",
"type": "Тип",
"address": "Адрес",
"copy_address": "Копировать полный адрес",
"send_from_this_address": "Отправить с этого адреса",
"export_private_key": "Экспорт приватного ключа",
"export_viewing_key": "Экспорт ключа просмотра",
"show_qr_code": "Показать QR-код",
"not_connected": "Не подключён к демону...",
"pay_from": "Оплата с",
"send_to": "Отправить на",
"amount": "Сумма",
"memo": "Примечание (необязательно, зашифровано)",
"miner_fee": "Комиссия майнера",
"fee": "Комиссия",
"send_transaction": "Отправить транзакцию",
"clear": "Очистить",
"select_address": "Выберите адрес...",
"paste": "Вставить",
"max": "Макс.",
"available": "Доступно",
"invalid_address": "Неверный формат адреса",
"memo_z_only": "Примечания доступны только при отправке на защищённые (z) адреса",
"characters": "символов",
"from": "От",
"to": "Кому",
"sending": "Отправка транзакции",
"confirm_send": "Подтвердить отправку",
"confirm_transaction": "Подтвердить транзакцию",
"confirm_and_send": "Подтвердить и отправить",
"cancel": "Отмена",
"receiving_addresses": "Ваши адреса для получения",
"new_z_shielded": "Новый z-адрес (защищённый)",
"new_t_transparent": "Новый t-адрес (прозрачный)",
"address_details": "Детали адреса",
"view_on_explorer": "Открыть в обозревателе",
"qr_code": "QR-код",
"request_payment": "Запросить платёж",
"date": "Дата",
"status": "Статус",
"confirmations": "Подтверждения",
"confirmed": "Подтверждена",
"pending": "Ожидание",
"sent": "отправлено",
"received": "получено",
"mined": "добыто",
"mining_control": "Управление майнингом",
"start_mining": "Начать майнинг",
"stop_mining": "Остановить майнинг",
"mining_threads": "Потоки майнинга",
"mining_statistics": "Статистика майнинга",
"local_hashrate": "Локальный хешрейт",
"network_hashrate": "Хешрейт сети",
"difficulty": "Сложность",
"est_time_to_block": "Ожидаемое время до блока",
"mining_off": "Майнинг ВЫКЛЮЧЕН",
"mining_on": "Майнинг ВКЛЮЧЁН",
"connected_peers": "Подключённые узлы",
"banned_peers": "Заблокированные узлы",
"ip_address": "IP-адрес",
"version": "Версия",
"height": "Высота",
"ping": "Пинг",
"ban": "Блокировать",
"unban": "Разблокировать",
"clear_all_bans": "Снять все блокировки",
"price_chart": "График цены",
"current_price": "Текущая цена",
"24h_change": "Изменение за 24ч",
"24h_volume": "Объём за 24ч",
"market_cap": "Рыночная кап.",
"general": "Основные",
"display": "Отображение",
"network": "Сеть",
"theme": "Тема",
"language": "Язык",
"dragonx_green": "DragonX (зелёный)",
"dark": "Тёмная",
"light": "Светлая",
"allow_custom_fees": "Разрешить пользовательские комиссии",
"use_embedded_daemon": "Встроенный dragonxd",
"save": "Сохранить",
"close": "Закрыть",
"file": "Файл",
"edit": "Редактировать",
"view": "Вид",
"help": "Помощь",
"import_private_key": "Импорт приватного ключа...",
"backup_wallet": "Резервное копирование кошелька...",
"exit": "Выход",
"about_dragonx": "О программе ObsidianDragon",
"refresh_now": "Обновить сейчас",
"about": "О программе",
"import": "Импорт",
"export": "Экспорт",
"copy_to_clipboard": "Копировать в буфер обмена",
"connected": "Подключён",
"disconnected": "Отключён",
"connecting": "Подключение...",
"syncing": "Синхронизация...",
"block": "Блок",
"no_addresses_available": "Нет доступных адресов",
"error": "Ошибка",
"success": "Успешно",
"warning": "Предупреждение",
"about_block_explorer": "Обозреватель блоков",
"about_block_height": "Высота блока:",
"about_build_date": "Дата сборки:",
"about_build_type": "Тип сборки:",
"about_chain": "Цепочка:",
"about_connections": "Подключения:",
"about_credits": "Благодарности",
"about_daemon": "Daemon:",
"about_debug": "Отладка",
"about_dragonx": "Об ObsidianDragon",
"about_edition": "Редакция ImGui",
"about_github": "GitHub",
"about_imgui": "ImGui:",
"about_license": "Лицензия",
"about_license_text": "Это программное обеспечение выпущено под лицензией GNU General Public License v3 (GPLv3). Вы можете свободно использовать, изменять и распространять это ПО в соответствии с условиями лицензии.",
"about_peers_count": "%zu узлов",
"about_release": "Релиз",
"about_title": "Об ObsidianDragon",
"about_version": "Версия:",
"about_website": "Веб-сайт",
"acrylic": "Акрил",
"add": "Добавить",
"address": "Адрес",
"address_book_add": "Добавить адрес",
"address_book_add_new": "Добавить новый",
"address_book_added": "Адрес добавлен в книгу",
"address_book_count": "%zu адресов сохранено",
"address_book_deleted": "Запись удалена",
"address_book_edit": "Редактировать адрес",
"address_book_empty": "Нет сохранённых адресов. Нажмите 'Добавить новый', чтобы создать.",
"address_book_exists": "Адрес уже существует в книге",
"address_book_title": "Адресная книга",
"address_book_update_failed": "Не удалось обновить — адрес может быть дубликатом",
"address_book_updated": "Адрес обновлён",
"address_copied": "Адрес скопирован в буфер обмена",
"address_details": "Детали адреса",
"address_label": "Адрес:",
"address_upper": "АДРЕС",
"address_url": "URL адреса",
"addresses_appear_here": "Ваши адреса для получения появятся здесь после подключения.",
"advanced": "РАСШИРЕННЫЕ",
"all_filter": "Все",
"allow_custom_fees": "Разрешить пользовательские комиссии",
"amount": "Сумма",
"amount_details": "ДЕТАЛИ СУММЫ",
"amount_exceeds_balance": "Сумма превышает баланс",
"transaction_sent": "Транзакция успешно отправлена"
"amount_label": "Сумма:",
"appearance": "ВНЕШНИЙ ВИД",
"auto_shield": "Авто-экранирование майнинга",
"available": "Доступно",
"backup_backing_up": "Создание резервной копии...",
"backup_create": "Создать резервную копию",
"backup_created": "Резервная копия кошелька создана",
"backup_data": "РЕЗЕРВНОЕ КОПИРОВАНИЕ И ДАННЫЕ",
"backup_description": "Создайте резервную копию файла wallet.dat. Этот файл содержит все ваши приватные ключи и историю транзакций. Храните копию в безопасном месте.",
"backup_destination": "Место сохранения:",
"backup_source": "Источник: %s",
"backup_tip_external": "Храните резервные копии на внешних дисках или в облаке",
"backup_tip_multiple": "Создавайте несколько копий в разных местах",
"backup_tip_test": "Периодически проверяйте восстановление из резервной копии",
"backup_tips": "Советы:",
"backup_title": "Резервное копирование кошелька",
"backup_wallet": "Создать резервную копию...",
"backup_wallet_not_found": "Предупреждение: wallet.dat не найден в ожидаемом расположении",
"balance": "Баланс",
"balance_layout": "Макет баланса",
"ban": "Заблокировать",
"banned_peers": "Заблокированные узлы",
"block": "Блок",
"block_bits": "Биты:",
"block_click_copy": "Нажмите для копирования",
"block_click_next": "Нажмите для следующего блока",
"block_click_prev": "Нажмите для предыдущего блока",
"block_explorer": "Обозреватель блоков",
"block_get_info": "Получить информацию о блоке",
"block_hash": "Хэш блока:",
"block_hash_copied": "Хеш блока скопирован",
"block_height": "Высота блока:",
"block_info_title": "Информация о блоке",
"block_merkle_root": "Корень Меркла:",
"block_nav_next": "Далее >>",
"block_nav_prev": "<< Назад",
"block_next": "Следующий блок:",
"block_previous": "Предыдущий блок:",
"block_size": "Размер:",
"block_timestamp": "Временная метка:",
"block_transactions": "Транзакции:",
"blockchain_syncing": "Синхронизация блокчейна (%.1f%%)... Балансы могут быть неточными.",
"cancel": "Отмена",
"characters": "символов",
"clear": "Очистить",
"clear_all_bans": "Снять все блокировки",
"clear_anyway": "Всё равно очистить",
"clear_form_confirm": "Очистить все поля формы?",
"clear_request": "Очистить запрос",
"click_copy_address": "Нажмите, чтобы скопировать адрес",
"click_copy_uri": "Нажмите, чтобы скопировать URI",
"click_to_copy": "Нажмите для копирования",
"close": "Закрыть",
"conf_count": "%d подтв.",
"confirm_and_send": "Подтвердить и отправить",
"confirm_clear_ztx_title": "Подтвердить очистку истории Z-Tx",
"confirm_clear_ztx_warning1": "Очистка истории z-транзакций может привести к отображению защищённого баланса как 0, пока не будет выполнено пересканирование кошелька.",
"confirm_clear_ztx_warning2": "Если это произойдёт, вам потребуется повторно импортировать приватные ключи вашего z-адреса с включённым пересканированием для восстановления баланса.",
"confirm_send": "Подтвердить отправку",
"confirm_transaction": "Подтвердить транзакцию",
"confirmations": "Подтверждения",
"confirmations_display": "%d подтверждений | %s",
"confirmed": "Подтверждено",
"connected": "Подключено",
"connected_peers": "Подключённые узлы",
"connecting": "Подключение...",
"console": "Консоль",
"console_auto_scroll": "Авто-прокрутка",
"console_available_commands": "Доступные команды:",
"console_capturing_output": "Захват вывода daemon...",
"console_clear": "Очистить",
"console_clear_console": "Очистить консоль",
"console_cleared": "Консоль очищена",
"console_click_commands": "Нажмите на команды выше, чтобы вставить их",
"console_click_insert": "Нажмите для вставки",
"console_click_insert_params": "Нажмите для вставки с параметрами",
"console_close": "Закрыть",
"console_commands": "Команды",
"console_common_rpc": "Частые RPC-команды:",
"console_completions": "Дополнения:",
"console_connected": "Подключено к daemon",
"console_copy_all": "Копировать всё",
"console_copy_selected": "Копировать",
"console_daemon": "Daemon",
"console_daemon_error": "Ошибка daemon!",
"console_daemon_started": "Daemon запущен",
"console_daemon_stopped": "Daemon остановлен",
"console_disconnected": "Отключено от daemon",
"console_errors": "Ошибки",
"console_filter_hint": "Фильтр вывода...",
"console_help_clear": " clear - Очистить консоль",
"console_help_getbalance": " getbalance - Показать прозрачный баланс",
"console_help_getblockcount": " getblockcount - Показать текущую высоту блока",
"console_help_getinfo": " getinfo - Показать информацию об узле",
"console_help_getmininginfo": " getmininginfo - Показать статус майнинга",
"console_help_getpeerinfo": " getpeerinfo - Показать подключённые узлы",
"console_help_gettotalbalance": " gettotalbalance - Показать общий баланс",
"console_help_help": " help - Показать эту справку",
"console_help_setgenerate": " setgenerate - Управление майнингом",
"console_help_stop": " stop - Остановить daemon",
"console_line_count": "%zu строк",
"console_new_lines": "%d новых строк",
"console_no_daemon": "Нет daemon",
"console_not_connected": "Ошибка: Не подключено к daemon",
"console_rpc_reference": "Справочник RPC-команд",
"console_scanline": "Скан-линия консоли",
"console_search_commands": "Поиск команд...",
"console_select_all": "Выбрать всё",
"console_show_daemon_output": "Показать вывод daemon",
"console_show_errors_only": "Показать только ошибки",
"console_show_rpc_ref": "Показать справочник RPC-команд",
"console_showing_lines": "Показано %zu из %zu строк",
"console_starting_node": "Запуск узла...",
"console_status_error": "Ошибка",
"console_status_running": "Работает",
"console_status_starting": "Запуск",
"console_status_stopped": "Остановлен",
"console_status_stopping": "Остановка",
"console_status_unknown": "Неизвестно",
"console_tab_completion": "Tab для дополнения",
"console_type_help": "Введите 'help' для списка команд",
"console_welcome": "Добро пожаловать в консоль ObsidianDragon",
"console_zoom_in": "Увеличить",
"console_zoom_out": "Уменьшить",
"copy": "Копировать",
"copy_address": "Копировать полный адрес",
"copy_error": "Копировать ошибку",
"copy_to_clipboard": "Копировать в буфер обмена",
"copy_txid": "Копировать TxID",
"copy_uri": "Копировать URI",
"current_price": "Текущая цена",
"custom_fees": "Пользовательские комиссии",
"dark": "Тёмная",
"date": "Дата",
"date_label": "Дата:",
"debug_logging": "ЖУРНАЛ ОТЛАДКИ",
"delete": "Удалить",
"difficulty": "Сложность",
"disconnected": "Отключено",
"dismiss": "Отклонить",
"display": "Отображение",
"dragonx_green": "DragonX (Зелёная)",
"edit": "Редактировать",
"error": "Ошибка",
"error_format": "Ошибка: %s",
"est_time_to_block": "Расч. время до блока",
"exit": "Выход",
"explorer": "ОБОЗРЕВАТЕЛЬ",
"export": "Экспорт",
"export_csv": "Экспорт в CSV",
"export_keys_btn": "Экспорт ключей",
"export_keys_danger": "ОПАСНОСТЬ: Будут экспортированы ВСЕ приватные ключи из вашего кошелька! Любой, кто получит доступ к этому файлу, сможет украсть ваши средства. Храните его в безопасности и удалите после использования.",
"export_keys_include_t": "Включить T-адреса (прозрачные)",
"export_keys_include_z": "Включить Z-адреса (экранированные)",
"export_keys_options": "Параметры экспорта:",
"export_keys_progress": "Экспорт %d/%d...",
"export_keys_success": "Ключи успешно экспортированы",
"export_keys_title": "Экспорт всех приватных ключей",
"export_private_key": "Экспорт приватного ключа",
"export_tx_count": "Экспортировать %zu транзакций в файл CSV.",
"export_tx_file_fail": "Не удалось создать файл CSV",
"export_tx_none": "Нет транзакций для экспорта",
"export_tx_success": "Транзакции успешно экспортированы",
"export_tx_title": "Экспорт транзакций в CSV",
"export_viewing_key": "Экспорт ключа просмотра",
"failed_create_shielded": "Не удалось создать экранированный адрес",
"failed_create_transparent": "Не удалось создать прозрачный адрес",
"favorite_address": "Добавить в избранное",
"fee": "Комиссия",
"fee_high": "Высокая",
"fee_label": "Комиссия:",
"fee_low": "Низкая",
"fee_normal": "Обычная",
"fetch_prices": "Получить цены",
"file": "Файл",
"file_save_location": "Файл будет сохранён в: ~/.config/ObsidianDragon/",
"font_scale": "Масштаб шрифта",
"from": "От",
"from_upper": "ОТ",
"full_details": "Полные детали",
"general": "Общие",
"go_to_receive": "Перейти к получению",
"height": "Высота",
"help": "Справка",
"hide": "Скрыть",
"hide_address": "Скрыть адрес",
"hide_zero_balances": "Скрыть нулевые балансы",
"history": "История",
"immature_type": "Незрелая",
"import": "Импорт",
"import_key_btn": "Импорт ключей",
"import_key_formats": "Поддерживаемые форматы ключей:",
"import_key_full_rescan": "(0 = полное сканирование)",
"import_key_label": "Приватный ключ(и):",
"import_key_no_valid": "В введённых данных не найдено действительных ключей",
"import_key_progress": "Импорт %d/%d...",
"import_key_rescan": "Пересканировать блокчейн после импорта",
"import_key_start_height": "Начальная высота:",
"import_key_success": "Ключи успешно импортированы",
"import_key_t_format": "Приватные ключи WIF для T-адресов",
"import_key_title": "Импорт приватного ключа",
"import_key_tooltip": "Введите один или несколько приватных ключей, по одному на строку.\nПоддерживаются ключи z-адресов и t-адресов.\nСтроки, начинающиеся с #, считаются комментариями.",
"import_key_warning": "Предупреждение: Никогда не делитесь своими приватными ключами! Импорт ключей из ненадёжных источников может скомпрометировать ваш кошелёк.",
"import_key_z_format": "Ключи расходования z-адресов (secret-extended-key-...)",
"import_private_key": "Импорт приватного ключа...",
"invalid_address": "Неверный формат адреса",
"ip_address": "IP-адрес",
"keep": "Сохранить",
"keep_daemon": "Оставить daemon работающим",
"key_export_click_retrieve": "Нажмите, чтобы получить ключ из вашего кошелька",
"key_export_fetching": "Получение ключа из кошелька...",
"key_export_private_key": "Приватный ключ:",
"key_export_private_warning": "Держите этот ключ в ТАЙНЕ! Любой, кто владеет этим ключом, может потратить ваши средства. Никогда не делитесь им в интернете или с ненадёжными лицами.",
"key_export_reveal": "Показать ключ",
"key_export_viewing_key": "Ключ просмотра:",
"key_export_viewing_keys_zonly": "Ключи просмотра доступны только для экранированных (z) адресов",
"key_export_viewing_warning": "Этот ключ просмотра позволяет другим видеть входящие транзакции и баланс, но НЕ тратить ваши средства. Делитесь только с доверенными лицами.",
"label": "Метка:",
"language": "Язык",
"light": "Светлая",
"loading": "Загрузка...",
"loading_addresses": "Загрузка адресов...",
"local_hashrate": "Локальный хешрейт",
"low_spec_mode": "Режим экономии",
"market": "Рынок",
"market_12h": "12ч",
"market_18h": "18ч",
"market_24h": "24ч",
"market_24h_volume": "ОБЪЁМ 24Ч",
"market_6h": "6ч",
"market_attribution": "Данные о ценах с NonKYC",
"market_btc_price": "ЦЕНА BTC",
"market_cap": "Рыночная капитализация",
"market_no_history": "Нет истории цен",
"market_no_price": "Нет данных о ценах",
"market_now": "Сейчас",
"market_pct_shielded": "%.0f%% Экранировано",
"market_portfolio": "ПОРТФЕЛЬ",
"market_price_unavailable": "Данные о ценах недоступны",
"market_refresh_price": "Обновить данные о ценах",
"market_trade_on": "Торговать на %s",
"mature": "Зрелая",
"max": "Макс",
"memo": "Заметка (необязательно, зашифровано)",
"memo_label": "Заметка:",
"memo_optional": "ЗАМЕТКА (НЕОБЯЗАТЕЛЬНО)",
"memo_upper": "ЗАМЕТКА",
"memo_z_only": "Примечание: Заметки доступны только при отправке на экранированные (z) адреса",
"merge_description": "Объедините несколько UTXO в один экранированный адрес. Это может уменьшить размер кошелька и улучшить конфиденциальность.",
"merge_funds": "Объединить средства",
"merge_started": "Операция объединения начата",
"merge_title": "Объединить на адрес",
"mine_when_idle": "Майнить в простое",
"mined": "добыто",
"mined_filter": "Добытые",
"mined_type": "Добытая",
"mined_upper": "ДОБЫТО",
"miner_fee": "Комиссия майнера",
"mining": "Майнинг",
"mining_active": "Активен",
"mining_address_copied": "Адрес майнинга скопирован",
"mining_all_time": "За всё время",
"mining_already_saved": "URL пула уже сохранён",
"mining_block_copied": "Хэш блока скопирован",
"mining_chart_1m_ago": "1м назад",
"mining_chart_5m_ago": "5м назад",
"mining_chart_now": "Сейчас",
"mining_chart_start": "Старт",
"mining_click": "Нажмите",
"mining_click_copy_address": "Нажмите, чтобы скопировать адрес",
"mining_click_copy_block": "Нажмите, чтобы скопировать хэш блока",
"mining_click_copy_difficulty": "Нажмите, чтобы скопировать сложность",
"mining_connected": "Подключено",
"mining_connecting": "Подключение...",
"mining_control": "Управление майнингом",
"mining_difficulty_copied": "Сложность скопирована",
"mining_est_block": "Расч. блок",
"mining_est_daily": "Расч. за день",
"mining_filter_all": "Все",
"mining_filter_tip_all": "Показать все доходы",
"mining_filter_tip_pool": "Показать только доходы пула",
"mining_filter_tip_solo": "Показать только доходы соло",
"mining_idle_off_tooltip": "Включить майнинг в простое",
"mining_idle_on_tooltip": "Отключить майнинг в простое",
"mining_local_hashrate": "Локальный хешрейт",
"mining_mine": "Майнить",
"mining_mining_addr": "Адрес майн.",
"mining_network": "Сеть",
"mining_no_blocks_yet": "Блоки пока не найдены",
"mining_no_payouts_yet": "Выплат пула пока нет",
"mining_no_saved_addresses": "Нет сохранённых адресов",
"mining_no_saved_pools": "Нет сохранённых пулов",
"mining_off": "Майнинг ВЫКЛЮЧЕН",
"mining_on": "Майнинг ВКЛЮЧЁН",
"mining_open_in_explorer": "Открыть в обозревателе",
"mining_payout_address": "Адрес выплат",
"mining_payout_tooltip": "Адрес для получения вознаграждений за майнинг",
"mining_pool": "Пул",
"mining_pool_hashrate": "Хешрейт пула",
"mining_pool_url": "URL пула",
"mining_recent_blocks": "ПОСЛЕДНИЕ БЛОКИ",
"mining_recent_payouts": "ПОСЛЕДНИЕ ВЫПЛАТЫ ПУЛА",
"mining_remove": "Удалить",
"mining_reset_defaults": "Сбросить настройки",
"mining_save_payout_address": "Сохранить адрес выплат",
"mining_save_pool_url": "Сохранить URL пула",
"mining_saved_addresses": "Сохранённые адреса:",
"mining_saved_pools": "Сохранённые пулы:",
"mining_shares": "Шары",
"mining_show_chart": "График",
"mining_show_log": "Журнал",
"mining_solo": "Соло",
"mining_starting": "Запуск...",
"mining_starting_tooltip": "Майнер запускается...",
"mining_statistics": "Статистика майнинга",
"mining_stop": "Стоп",
"mining_stop_solo_for_pool": "Остановите соло-майнинг перед запуском пул-майнинга",
"mining_stop_solo_for_pool_settings": "Остановите соло-майнинг для изменения настроек пула",
"mining_stopping": "Остановка...",
"mining_stopping_tooltip": "Майнер останавливается...",
"mining_syncing_tooltip": "Блокчейн синхронизируется...",
"mining_threads": "Потоки майнинга",
"mining_to_save": "для сохранения",
"mining_today": "Сегодня",
"mining_uptime": "Время работы",
"mining_yesterday": "Вчера",
"network": "Сеть",
"network_fee": "СЕТЕВАЯ КОМИССИЯ",
"network_hashrate": "Хешрейт сети",
"new": "+ Новый",
"new_shielded_created": "Создан новый экранированный адрес",
"new_t_address": "Новый T-адрес",
"new_t_transparent": "Новый t-адрес (Прозрачный)",
"new_transparent_created": "Создан новый прозрачный адрес",
"new_z_address": "Новый Z-адрес",
"new_z_shielded": "Новый z-адрес (Экранированный)",
"no_addresses": "Адреса не найдены. Создайте один, используя кнопки выше.",
"no_addresses_available": "Нет доступных адресов",
"no_addresses_match": "Нет адресов, соответствующих фильтру",
"no_addresses_with_balance": "Нет адресов с балансом",
"no_matching": "Нет подходящих транзакций",
"no_recent_receives": "Нет недавних получений",
"no_recent_sends": "Нет недавних отправлений",
"no_transactions": "Транзакции не найдены",
"node": "УЗЕЛ",
"node_security": "УЗЕЛ И БЕЗОПАСНОСТЬ",
"noise": "Шум",
"not_connected": "Не подключено к daemon...",
"not_connected_to_daemon": "Не подключено к daemon",
"notes": "Заметки",
"notes_optional": "Заметки (необязательно):",
"output_filename": "Имя выходного файла:",
"overview": "Обзор",
"paste": "Вставить",
"paste_from_clipboard": "Вставить из буфера обмена",
"pay_from": "Оплатить с",
"payment_request": "ЗАПРОС НА ОПЛАТУ",
"payment_request_copied": "Запрос на оплату скопирован",
"payment_uri_copied": "URI платежа скопирован",
"peers": "Узлы",
"peers_avg_ping": "Средний пинг",
"peers_ban_24h": "Заблокировать узел на 24ч",
"peers_ban_score": "Очки блокировки: %d",
"peers_banned": "Заблокированные",
"peers_banned_count": "Заблокировано: %d",
"peers_best_block": "Лучший блок",
"peers_blockchain": "БЛОКЧЕЙН",
"peers_blocks": "Блоки",
"peers_blocks_left": "Осталось %d блоков",
"peers_clear_all_bans": "Снять все блокировки",
"peers_click_copy": "Нажмите, чтобы скопировать",
"peers_connected": "Подключено",
"peers_connected_count": "Подключено: %d",
"peers_copy_ip": "Копировать IP",
"peers_dir_in": "Вх.",
"peers_dir_out": "Исх.",
"peers_hash_copied": "Хэш скопирован",
"peers_hashrate": "Хешрейт",
"peers_in_out": "Вх./Исх.",
"peers_longest": "Длиннейшая",
"peers_longest_chain": "Длиннейшая цепь",
"peers_memory": "Память",
"peers_no_banned": "Нет заблокированных узлов",
"peers_no_connected": "Нет подключённых узлов",
"peers_no_tls": "Без TLS",
"peers_notarized": "Нотаризован",
"peers_p2p_port": "P2P-порт",
"peers_peer_label": "Пир: %s",
"peers_protocol": "Протокол",
"peers_received": "Получено",
"peers_refresh": "Обновить",
"peers_refresh_tooltip": "Обновить список узлов",
"peers_refreshing": "Обновление...",
"peers_sent": "Отправлено",
"peers_tt_id": "ID: %d",
"peers_tt_received": "Получено: %s",
"peers_tt_sent": "Отправлено: %s",
"peers_tt_services": "Сервисы: %s",
"peers_tt_start_height": "Начальная высота: %d",
"peers_tt_synced": "Синхронизировано В/Б: %d/%d",
"peers_tt_tls_cipher": "TLS: %s",
"peers_unban": "Разблокировать",
"peers_upper": "УЗЛЫ",
"peers_version": "Версия",
"pending": "Ожидание",
"ping": "Пинг",
"price_chart": "График цен",
"qr_code": "QR-код",
"qr_failed": "Не удалось сгенерировать QR-код",
"qr_title": "QR-код",
"qr_unavailable": "QR недоступен",
"ram_daemon_gb": "Демон: %.1f ГБ (%s)",
"ram_daemon_mb": "Демон: %.0f МБ (%s)",
"ram_system_gb": "Система: %.1f / %.0f ГБ",
"ram_wallet_gb": "Кошелёк: %.1f ГБ",
"ram_wallet_mb": "Кошелёк: %.0f МБ",
"receive": "Получить",
"received": "получено",
"received_filter": "Получено",
"received_label": "Получено",
"received_upper": "ПОЛУЧЕНО",
"receiving_addresses": "Ваши адреса для получения",
"recent_received": "НЕДАВНО ПОЛУЧЕНО",
"recent_sends": "НЕДАВНО ОТПРАВЛЕНО",
"recipient": "ПОЛУЧАТЕЛЬ",
"recv_type": "Получ.",
"refresh": "Обновить",
"refresh_now": "Обновить сейчас",
"remove_favorite": "Удалить из избранного",
"report_bug": "Сообщить об ошибке",
"request_amount": "Сумма (необязательно):",
"request_copy_uri": "Копировать URI",
"request_description": "Создайте запрос на оплату, который другие могут отсканировать или скопировать. QR-код содержит ваш адрес и опциональную сумму/заметку.",
"request_label": "Метка (необязательно):",
"request_memo": "Заметка (необязательно):",
"request_payment": "Запрос оплаты",
"request_payment_uri": "URI платежа:",
"request_receive_address": "Адрес получения:",
"request_select_address": "Выбрать адрес...",
"request_shielded_addrs": "-- Экранированные адреса --",
"request_title": "Запрос оплаты",
"request_transparent_addrs": "-- Прозрачные адреса --",
"request_uri_copied": "URI платежа скопирован в буфер обмена",
"rescan": "Пересканировать",
"reset_to_defaults": "Сбросить настройки",
"restore_address": "Восстановить адрес",
"review_send": "Проверить отправку",
"rpc_host": "RPC-хост",
"rpc_pass": "Пароль",
"rpc_port": "Порт",
"rpc_user": "Имя пользователя",
"save": "Сохранить",
"save_settings": "Сохранить настройки",
"save_z_transactions": "Сохранять Z-tx в списке транзакций",
"search_placeholder": "Поиск...",
"security": "БЕЗОПАСНОСТЬ",
"select_address": "Выбрать адрес...",
"select_receiving_address": "Выбрать адрес получения...",
"select_source_address": "Выбрать адрес-источник...",
"send": "Отправить",
"send_amount": "Сумма",
"send_amount_details": "ДЕТАЛИ СУММЫ",
"send_amount_upper": "СУММА",
"send_clear_fields": "Очистить все поля формы?",
"send_copy_error": "Копировать ошибку",
"send_dismiss": "Отклонить",
"send_error_copied": "Ошибка скопирована в буфер обмена",
"send_error_prefix": "Ошибка: %s",
"send_exceeds_available": "Превышает доступное (%.8f)",
"send_fee": "Комиссия",
"send_fee_high": "Высокая",
"send_fee_low": "Низкая",
"send_fee_normal": "Обычная",
"send_form_restored": "Форма восстановлена",
"send_from_this_address": "Отправить с этого адреса",
"send_go_to_receive": "Перейти к получению",
"send_keep": "Сохранить",
"send_network_fee": "СЕТЕВАЯ КОМИССИЯ",
"send_no_balance": "Нет баланса",
"send_no_recent": "Нет недавних отправлений",
"send_recent_sends": "НЕДАВНО ОТПРАВЛЕНО",
"send_recipient": "ПОЛУЧАТЕЛЬ",
"send_select_source": "Выбрать адрес-источник...",
"send_sending_from": "ОТПРАВКА С",
"send_submitting": "Отправка транзакции...",
"send_switch_to_receive": "Перейдите к получению, чтобы получить свой адрес и начать получать средства.",
"send_to": "Отправить на",
"send_tooltip_enter_amount": "Введите сумму для отправки",
"send_tooltip_exceeds_balance": "Сумма превышает доступный баланс",
"send_tooltip_in_progress": "Транзакция уже выполняется",
"send_tooltip_invalid_address": "Введите действительный адрес получателя",
"send_tooltip_not_connected": "Не подключено к daemon",
"send_tooltip_select_source": "Сначала выберите адрес-источник",
"send_tooltip_syncing": "Дождитесь синхронизации блокчейна",
"send_total": "Итого",
"send_transaction": "Отправить транзакцию",
"send_tx_failed": "Транзакция не удалась",
"send_tx_sent": "Транзакция отправлена!",
"send_tx_success": "Транзакция успешно отправлена!",
"send_txid_copied": "TxID скопирован в буфер обмена",
"send_txid_label": "TxID: %s",
"send_valid_shielded": "Действительный экранированный адрес",
"send_valid_transparent": "Действительный прозрачный адрес",
"send_wallet_empty": "Ваш кошелёк пуст",
"send_yes_clear": "Да, очистить",
"sending": "Отправка транзакции",
"sending_from": "ОТПРАВКА С",
"sent": "отправлено",
"sent_filter": "Отправлено",
"sent_type": "Отправлено",
"sent_upper": "ОТПРАВЛЕНО",
"settings": "Настройки",
"settings_about_text": "Защищённый криптовалютный кошелёк для DragonX (DRGX), созданный на Dear ImGui для лёгкого и портативного использования.",
"settings_acrylic_level": "Уровень акрила:",
"settings_address_book": "Адресная книга...",
"settings_auto_detected": "Автоопределено из DRAGONX.conf",
"settings_auto_lock": "АВТОБЛОКИРОВКА",
"settings_auto_shield_desc": "Автоматически перемещать прозрачные средства на экранированные адреса",
"settings_auto_shield_funds": "Автоматически экранировать прозрачные средства",
"settings_backup": "Резервная копия...",
"settings_block_explorer_urls": "URL-адреса обозревателя блоков",
"settings_builtin": "Встроенные",
"settings_change_passphrase": "Сменить пароль",
"settings_change_pin": "Изменить PIN",
"settings_clear_ztx": "Очистить историю Z-Tx",
"settings_clear_ztx_desc": "Удалить локально сохранённые данные защищённых транзакций",
"settings_clear_ztx_long": "Очистить сохранённую историю Z-транзакций",
"settings_configure_explorer": "Настроить ссылки внешнего обозревателя блоков",
"settings_configure_rpc": "Настроить подключение к демону dragonxd",
"settings_connection": "Подключение",
"settings_copyright": "Copyright 2024-2026 Разработчики DragonX | Лицензия GPLv3",
"settings_custom": "Пользовательские",
"settings_data_dir": "Каталог данных:",
"settings_debug_changed": "Категории отладки изменены — перезапустите демон для применения",
"settings_debug_restart_note": "Изменения вступают в силу после перезапуска демона.",
"settings_debug_select": "Выберите категории для включения журнала отладки демона (флаги -debug=).",
"settings_encrypt_first_pin": "Сначала зашифруйте кошелёк, чтобы включить PIN",
"settings_encrypt_wallet": "Зашифровать кошелёк",
"settings_explorer_hint": "URL-адреса должны заканчиваться косой чертой. Txid/адрес будет добавлен.",
"settings_export_all": "Экспортировать все...",
"settings_export_csv": "Экспорт CSV...",
"settings_export_key": "Экспортировать ключ...",
"settings_gradient_bg": "Градиент фона",
"settings_gradient_desc": "Заменить текстурные фоны плавными градиентами",
"settings_idle_after": "через",
"settings_import_key": "Импортировать ключ...",
"settings_language_note": "Примечание: Некоторый текст требует перезапуска для обновления",
"settings_lock_now": "Заблокировать сейчас",
"settings_locked": "Заблокирован",
"settings_merge_to_address": "Объединить на адрес...",
"settings_noise_opacity": "Непрозрачность шума:",
"settings_not_encrypted": "Не зашифрован",
"settings_not_found": "Не найден",
"settings_other": "Прочее",
"settings_pin_active": "PIN",
"settings_privacy": "Конфиденциальность",
"settings_quick_unlock_pin": "Быстрый PIN-код разблокировки",
"settings_reduce_transparency": "Уменьшить прозрачность",
"settings_remove_encryption": "Удалить шифрование",
"settings_remove_pin": "Удалить PIN",
"settings_request_payment": "Запросить платёж...",
"settings_rescan_desc": "Пересканировать блокчейн для поиска пропущенных транзакций",
"settings_restart_daemon": "Перезапустить демон",
"settings_rpc_connection": "RPC-соединение",
"settings_rpc_note": "Примечание: Настройки подключения обычно определяются автоматически из DRAGONX.conf",
"settings_save_shielded_desc": "Сохраняет z-addr транзакции в локальном файле для просмотра",
"settings_save_shielded_local": "Сохранять историю защищённых транзакций локально",
"settings_set_pin": "Установить PIN",
"settings_shield_mining": "Экранировать майнинг...",
"settings_solid_colors_desc": "Использовать сплошные цвета вместо эффектов размытия (доступность)",
"settings_tor_desc": "Маршрутизировать все соединения через Tor для повышения конфиденциальности",
"settings_unlocked": "Разблокирован",
"settings_use_tor_network": "Использовать Tor для сетевых подключений",
"settings_validate_address": "Проверить адрес...",
"settings_visual_effects": "Визуальные эффекты",
"settings_wallet_file_size": "Размер файла кошелька: %s",
"settings_wallet_info": "Информация о кошельке",
"settings_wallet_location": "Расположение кошелька: %s",
"settings_wallet_maintenance": "Обслуживание кошелька",
"settings_wallet_not_found": "Файл кошелька не найден",
"settings_wallet_size_label": "Размер кошелька:",
"setup_wizard": "Мастер настройки",
"share": "Поделиться",
"shield_check_status": "Проверить статус",
"shield_completed": "Операция успешно завершена!",
"shield_description": "Экранируйте вознаграждения за майнинг, отправив coinbase-выходы с прозрачных адресов на экранированный адрес. Это улучшает конфиденциальность, скрывая ваш доход от майнинга.",
"shield_from_address": "С адреса:",
"shield_funds": "Экранировать средства",
"shield_in_progress": "Операция выполняется...",
"shield_max_utxos": "Макс. UTXO за операцию",
"shield_merge_done": "Экранирование/объединение завершено!",
"shield_operation_id": "ID операции: %s",
"shield_select_z": "Выбрать z-адрес...",
"shield_started": "Операция экранирования начата",
"shield_title": "Экранировать вознаграждения coinbase",
"shield_to_address": "На адрес (экранированный):",
"shield_utxo_limit": "Лимит UTXO:",
"shield_wildcard_hint": "Используйте '*' для экранирования со всех прозрачных адресов",
"shielded": "Экранированный",
"shielded_to": "ЭКРАНИРОВАНО НА",
"shielded_type": "Экранированный",
"show": "Показать",
"show_hidden": "Показать скрытые (%d)",
"show_qr_code": "Показать QR-код",
"showing_transactions": "Показано %d–%d из %d транзакций (всего: %zu)",
"simple_background": "Простой фон",
"start_mining": "Начать майнинг",
"status": "Статус",
"stop_external": "Остановить внешний daemon",
"stop_mining": "Остановить майнинг",
"submitting_transaction": "Отправка транзакции...",
"success": "Успешно",
"summary": "Итоги",
"syncing": "Синхронизация...",
"t_addresses": "T-адреса",
"test_connection": "Тест",
"theme": "Тема",
"theme_effects": "Эффекты темы",
"time_days_ago": "%d дней назад",
"time_hours_ago": "%d часов назад",
"time_minutes_ago": "%d минут назад",
"time_seconds_ago": "%d секунд назад",
"to": "Кому",
"to_upper": "КОМУ",
"tools": "ИНСТРУМЕНТЫ",
"total": "Итого",
"transaction_id": "ID ТРАНЗАКЦИИ",
"transaction_sent": "Транзакция успешно отправлена",
"transaction_sent_msg": "Транзакция отправлена!",
"transaction_url": "URL транзакции",
"transactions": "Транзакции",
"transactions_upper": "ТРАНЗАКЦИИ",
"transparent": "Прозрачный",
"tt_addr_url": "Базовый URL для просмотра адресов в обозревателе блоков",
"tt_address_book": "Управление сохранёнными адресами для быстрой отправки",
"tt_auto_lock": "Заблокировать кошелёк после этого времени бездействия",
"tt_auto_shield": "Автоматически перемещать прозрачный баланс на экранированные адреса для конфиденциальности",
"tt_backup": "Создать резервную копию вашего wallet.dat",
"tt_block_explorer": "Открыть обозреватель блоков DragonX в браузере",
"tt_blur": "Степень размытия (0%% = выкл., 100%% = максимум)",
"tt_change_pass": "Сменить пароль шифрования кошелька",
"tt_change_pin": "Изменить PIN-код разблокировки",
"tt_clear_ztx": "Удалить локально кешированную историю z-транзакций",
"tt_custom_fees": "Включить ручной ввод комиссий при отправке транзакций",
"tt_custom_theme": "Пользовательская тема активна",
"tt_debug_collapse": "Свернуть параметры журнала отладки",
"tt_debug_expand": "Развернуть параметры журнала отладки",
"tt_encrypt": "Зашифровать wallet.dat паролем",
"tt_export_all": "Экспортировать все приватные ключи в файл",
"tt_export_csv": "Экспортировать историю транзакций в виде таблицы CSV",
"tt_export_key": "Экспортировать приватный ключ выбранного адреса",
"tt_fetch_prices": "Получить рыночные цены DRGX из API CoinGecko",
"tt_font_scale": "Масштабировать весь текст и интерфейс (1.0x = по умолчанию, до 1.5x).",
"tt_idle_delay": "Сколько ждать перед началом майнинга",
"tt_import_key": "Импортировать приватный ключ (zkey или tkey) в этот кошелёк",
"tt_keep_daemon": "Демон будет остановлен при запуске мастера настройки",
"tt_language": "Язык интерфейса кошелька",
"tt_layout_hotkey": "Горячая клавиша: стрелки влево/вправо для переключения раскладок Баланса",
"tt_lock": "Немедленно заблокировать кошелёк",
"tt_low_spec": "Отключить все тяжёлые визуальные эффекты\\nГорячая клавиша: Ctrl+Shift+Down",
"tt_merge": "Объединить несколько UTXO в один адрес",
"tt_mine_idle": "Автоматически начать майнинг при\\nпростое системы (нет ввода с клавиатуры/мыши)",
"tt_noise": "Интенсивность зернистой текстуры (0%% = выкл., 100%% = максимум)",
"tt_open_dir": "Нажмите, чтобы открыть в проводнике",
"tt_remove_encrypt": "Удалить шифрование и хранить кошелёк без защиты",
"tt_remove_pin": "Удалить PIN и требовать пароль для разблокировки",
"tt_report_bug": "Сообщить о проблеме в трекере проекта",
"tt_request_payment": "Сгенерировать запрос на оплату с QR-кодом",
"tt_rescan": "Пересканировать блокчейн для поиска пропущенных транзакций",
"tt_reset_settings": "Перезагрузить настройки с диска (отменить несохранённые изменения)",
"tt_restart_daemon": "Перезапустить демон для применения изменений журнала отладки",
"tt_rpc_host": "Имя хоста демона DragonX",
"tt_rpc_pass": "Пароль аутентификации RPC",
"tt_rpc_port": "Порт для RPC-подключений демона",
"tt_rpc_user": "Имя пользователя аутентификации RPC",
"tt_save_settings": "Сохранить все настройки на диск",
"tt_save_ztx": "Хранить историю транзакций z-адреса локально для более быстрой загрузки",
"tt_scan_themes": "Поиск новых тем.\\nРазместите папки тем в:\\n%s",
"tt_scanline": "Эффект развёртки ЭЛТ в консоли",
"tt_set_pin": "Установить 4-8-значный PIN для быстрой разблокировки",
"tt_shield_mining": "Перевести прозрачные вознаграждения за майнинг на экранированный адрес",
"tt_simple_bg": "Использовать простой градиент для фона\\nГорячая клавиша: Ctrl+Up",
"tt_simple_bg_alt": "Использовать градиентную версию фонового изображения темы\\nГорячая клавиша: Ctrl+Up",
"tt_stop_external": "Применяется при подключении к демону,\\nзапущенному вне этого кошелька",
"tt_test_conn": "Проверить RPC-подключение к демону",
"tt_theme_effects": "Мерцание, свечение, циклическая смена оттенка по теме",
"tt_theme_hotkey": "Горячая клавиша: Ctrl+Влево/Вправо для переключения тем",
"tt_tor": "Маршрутизировать подключения демона через сеть Tor для анонимности",
"tt_tx_url": "Базовый URL для просмотра транзакций в обозревателе блоков",
"tt_ui_opacity": "Непрозрачность карточек и боковой панели (100%% = полностью непрозрачно, ниже = прозрачнее)",
"tt_validate": "Проверить, действителен ли адрес DragonX",
"tt_verbose": "Записывать подробную диагностику подключений,\\nсостояние демона и информацию о владельце порта\\nна вкладке Консоль",
"tt_website": "Открыть сайт DragonX",
"tt_window_opacity": "Непрозрачность фона (ниже = рабочий стол виден сквозь окно)",
"tt_wizard": "Повторно запустить мастер начальной настройки\\nДемон будет перезапущен",
"tx_confirmations": "%d подтверждений",
"tx_details_title": "Детали транзакции",
"tx_from_address": "Адрес отправителя:",
"tx_id_label": "ID транзакции:",
"tx_immature": "НЕЗРЕЛАЯ",
"tx_mined": "ДОБЫТА",
"tx_received": "ПОЛУЧЕНО",
"tx_sent": "ОТПРАВЛЕНО",
"tx_to_address": "Адрес получателя:",
"tx_view_explorer": "Посмотреть в обозревателе",
"txs_count": "%d тр.",
"type": "Тип",
"ui_opacity": "Прозрачность интерфейса",
"unban": "Разблокировать",
"unconfirmed": "Не подтверждено",
"undo_clear": "Отменить очистку",
"unknown": "Неизвестно",
"use_embedded_daemon": "Использовать встроенный dragonxd",
"use_tor": "Использовать Tor",
"validate_btn": "Проверить",
"validate_description": "Введите адрес DragonX, чтобы проверить его действительность и принадлежность к этому кошельку.",
"validate_invalid": "НЕДЕЙСТВИТЕЛЕН",
"validate_is_mine": "Этот кошелёк владеет этим адресом",
"validate_not_mine": "Не принадлежит этому кошельку",
"validate_ownership": "Принадлежность:",
"validate_results": "Результаты:",
"validate_shielded_type": "Экранированный (z-адрес)",
"validate_status": "Статус:",
"validate_title": "Проверить адрес",
"validate_transparent_type": "Прозрачный (t-адрес)",
"validate_type": "Тип:",
"validate_valid": "ДЕЙСТВИТЕЛЕН",
"validating": "Проверка...",
"verbose_logging": "Подробное логирование",
"version": "Версия",
"view": "Просмотр",
"view_details": "Подробнее",
"view_on_explorer": "Посмотреть в обозревателе",
"waiting_for_daemon": "Ожидание подключения к daemon...",
"wallet": "КОШЕЛЁК",
"wallet_empty": "Ваш кошелёк пуст",
"wallet_empty_hint": "Перейдите к получению, чтобы получить свой адрес и начать получать средства.",
"warning": "Предупреждение",
"warning_upper": "ПРЕДУПРЕЖДЕНИЕ!",
"website": "Веб-сайт",
"window_opacity": "Прозрачность окна",
"yes_clear": "Да, очистить",
"your_addresses": "Ваши адреса",
"z_addresses": "Z-адреса"
}
+777 -121
View File
@@ -1,139 +1,795 @@
{
"balance": "余额",
"send": "发送",
"receive": "接收",
"transactions": "交易记录",
"mining": "挖矿",
"peers": "节点",
"market": "市场",
"settings": "设置",
"summary": "概览",
"shielded": "隐私地址",
"transparent": "透明地址",
"total": "总计",
"unconfirmed": "未确认",
"your_addresses": "您的地址",
"z_addresses": "Z-地址",
"t_addresses": "T-地址",
"no_addresses": "未找到地址。请使用上方按钮创建。",
"new_z_address": "新建 Z-地址",
"new_t_address": "新建 T-地址",
"type": "类型",
"24h_change": "24小时变化",
"24h_volume": "24小时交易量",
"about": "关于",
"about_block_explorer": "区块浏览器",
"about_block_height": "区块高度:",
"about_build_date": "构建日期:",
"about_build_type": "构建类型:",
"about_chain": "链:",
"about_connections": "连接数:",
"about_credits": "致谢",
"about_daemon": "守护进程:",
"about_debug": "调试",
"about_dragonx": "关于 ObsidianDragon",
"about_edition": "ImGui 版本",
"about_github": "GitHub",
"about_imgui": "ImGui:",
"about_license": "许可证",
"about_license_text": "本软件根据 GNU 通用公共许可证 v3 (GPLv3) 发布。您可以根据许可证条款自由使用、修改和分发本软件。",
"about_peers_count": "%zu 个节点",
"about_release": "发布版",
"about_title": "关于 ObsidianDragon",
"about_version": "版本:",
"about_website": "网站",
"acrylic": "亚克力",
"add": "添加",
"address": "地址",
"copy_address": "复制完整地址",
"send_from_this_address": "从此地址发送",
"export_private_key": "导出私钥",
"export_viewing_key": "导出查看密钥",
"show_qr_code": "显示二维码",
"not_connected": "未连接到守护进程...",
"pay_from": "付款地址",
"send_to": "收款地址",
"address_book_add": "添加地址",
"address_book_add_new": "添加新地址",
"address_book_added": "地址已添加到通讯录",
"address_book_count": "已保存 %zu 个地址",
"address_book_deleted": "条目已删除",
"address_book_edit": "编辑地址",
"address_book_empty": "没有保存的地址。点击'添加新地址'创建一个。",
"address_book_exists": "地址已存在于通讯录中",
"address_book_title": "地址簿",
"address_book_update_failed": "更新失败——地址可能重复",
"address_book_updated": "地址已更新",
"address_copied": "地址已复制到剪贴板",
"address_details": "地址详情",
"address_label": "地址:",
"address_upper": "地址",
"address_url": "地址 URL",
"addresses_appear_here": "连接后,您的接收地址将显示在此处。",
"advanced": "高级",
"all_filter": "全部",
"allow_custom_fees": "允许自定义手续费",
"amount": "金额",
"memo": "备注(可选,已加密)",
"miner_fee": "矿工手续费",
"fee": "手续费",
"send_transaction": "发送交易",
"clear": "清除",
"select_address": "选择地址...",
"paste": "粘贴",
"max": "最大",
"amount_details": "金额详情",
"amount_exceeds_balance": "金额超过余额",
"amount_label": "金额:",
"appearance": "外观",
"auto_shield": "自动屏蔽挖矿",
"available": "可用",
"invalid_address": "地址格式无效",
"memo_z_only": "注意:备注仅在发送到隐私(z)地址时可用",
"backup_backing_up": "正在备份...",
"backup_create": "创建备份",
"backup_created": "钱包备份已创建",
"backup_data": "备份与数据",
"backup_description": "创建 wallet.dat 文件的备份。此文件包含您所有的私钥和交易历史。请将备份存放在安全的地方。",
"backup_destination": "备份目标:",
"backup_source": "来源:%s",
"backup_tip_external": "将备份存储在外部驱动器或云存储中",
"backup_tip_multiple": "在不同位置创建多个备份",
"backup_tip_test": "定期测试从备份恢复",
"backup_tips": "提示:",
"backup_title": "备份钱包",
"backup_wallet": "备份钱包...",
"backup_wallet_not_found": "警告:在预期位置未找到 wallet.dat",
"balance": "余额",
"balance_layout": "余额布局",
"ban": "封禁",
"banned_peers": "已封禁节点",
"block": "区块",
"block_bits": "比特:",
"block_click_copy": "点击复制",
"block_click_next": "点击查看下一个区块",
"block_click_prev": "点击查看上一个区块",
"block_explorer": "区块浏览器",
"block_get_info": "获取区块信息",
"block_hash": "区块哈希:",
"block_hash_copied": "区块哈希已复制",
"block_height": "区块高度:",
"block_info_title": "区块信息",
"block_merkle_root": "默克尔根:",
"block_nav_next": "下一个 >>",
"block_nav_prev": "<< 上一个",
"block_next": "下一个区块:",
"block_previous": "上一个区块:",
"block_size": "大小:",
"block_timestamp": "时间戳:",
"block_transactions": "交易:",
"blockchain_syncing": "区块链同步中 (%.1f%%)... 余额可能不准确。",
"cancel": "取消",
"characters": "字符",
"from": "发送方",
"to": "接收方",
"sending": "正在发送交易",
"clear": "清除",
"clear_all_bans": "解除所有封禁",
"clear_anyway": "仍然清除",
"clear_form_confirm": "清除所有表单字段?",
"clear_request": "清除请求",
"click_copy_address": "点击复制地址",
"click_copy_uri": "点击复制 URI",
"click_to_copy": "点击复制",
"close": "关闭",
"conf_count": "%d 确认",
"confirm_and_send": "确认并发送",
"confirm_clear_ztx_title": "确认清除 Z-Tx 历史",
"confirm_clear_ztx_warning1": "清除 z-交易历史可能导致您的屏蔽余额显示为 0,直到执行钱包重新扫描。",
"confirm_clear_ztx_warning2": "如果发生这种情况,您需要在启用重新扫描的情况下重新导入 z-地址私钥以恢复余额。",
"confirm_send": "确认发送",
"confirm_transaction": "确认交易",
"confirm_and_send": "确认并发送",
"cancel": "取消",
"receiving_addresses": "您的接收地址",
"new_z_shielded": "新建 z-地址(隐私)",
"new_t_transparent": "新建 t-地址(透明)",
"address_details": "地址详情",
"view_on_explorer": "在浏览器查看",
"qr_code": "二维码",
"request_payment": "请求付款",
"date": "日期",
"status": "状态",
"confirmations": "确认数",
"confirmations_display": "%d 次确认 | %s",
"confirmed": "已确认",
"pending": "待确认",
"sent": "已发送",
"received": "已接收",
"mined": "已挖出",
"mining_control": "挖矿控制",
"start_mining": "开始挖矿",
"stop_mining": "停止挖矿",
"mining_threads": "挖矿线程",
"mining_statistics": "挖矿统计",
"local_hashrate": "本地算力",
"network_hashrate": "全网算力",
"connected": "已连接",
"connected_peers": "已连接节点",
"connecting": "连接中...",
"console": "控制台",
"console_auto_scroll": "自动滚动",
"console_available_commands": "可用命令:",
"console_capturing_output": "正在捕获守护进程输出...",
"console_clear": "清除",
"console_clear_console": "清除控制台",
"console_cleared": "控制台已清除",
"console_click_commands": "点击上方命令以插入",
"console_click_insert": "点击插入",
"console_click_insert_params": "点击插入(含参数)",
"console_close": "关闭",
"console_commands": "命令",
"console_common_rpc": "常用 RPC 命令:",
"console_completions": "补全:",
"console_connected": "已连接到守护进程",
"console_copy_all": "全部复制",
"console_copy_selected": "复制",
"console_daemon": "守护进程",
"console_daemon_error": "守护进程错误!",
"console_daemon_started": "守护进程已启动",
"console_daemon_stopped": "守护进程已停止",
"console_disconnected": "已断开与守护进程的连接",
"console_errors": "错误",
"console_filter_hint": "过滤输出...",
"console_help_clear": " clear - 清除控制台",
"console_help_getbalance": " getbalance - 显示透明余额",
"console_help_getblockcount": " getblockcount - 显示当前区块高度",
"console_help_getinfo": " getinfo - 显示节点信息",
"console_help_getmininginfo": " getmininginfo - 显示挖矿状态",
"console_help_getpeerinfo": " getpeerinfo - 显示已连接节点",
"console_help_gettotalbalance": " gettotalbalance - 显示总余额",
"console_help_help": " help - 显示此帮助信息",
"console_help_setgenerate": " setgenerate - 控制挖矿",
"console_help_stop": " stop - 停止守护进程",
"console_line_count": "%zu 行",
"console_new_lines": "%d 新行",
"console_no_daemon": "无守护进程",
"console_not_connected": "错误:未连接到守护进程",
"console_rpc_reference": "RPC 命令参考",
"console_scanline": "控制台扫描线",
"console_search_commands": "搜索命令...",
"console_select_all": "全选",
"console_show_daemon_output": "显示守护进程输出",
"console_show_errors_only": "仅显示错误",
"console_show_rpc_ref": "显示 RPC 命令参考",
"console_showing_lines": "显示 %zu / %zu 行",
"console_starting_node": "正在启动节点...",
"console_status_error": "错误",
"console_status_running": "运行中",
"console_status_starting": "启动中",
"console_status_stopped": "已停止",
"console_status_stopping": "停止中",
"console_status_unknown": "未知",
"console_tab_completion": "Tab 补全",
"console_type_help": "输入 'help' 查看可用命令",
"console_welcome": "欢迎使用 ObsidianDragon 控制台",
"console_zoom_in": "放大",
"console_zoom_out": "缩小",
"copy": "复制",
"copy_address": "复制完整地址",
"copy_error": "复制错误",
"copy_to_clipboard": "复制到剪贴板",
"copy_txid": "复制交易ID",
"copy_uri": "复制 URI",
"current_price": "当前价格",
"custom_fees": "自定义手续费",
"dark": "深色",
"date": "日期",
"date_label": "日期:",
"debug_logging": "调试日志",
"delete": "删除",
"difficulty": "难度",
"disconnected": "已断开",
"dismiss": "关闭",
"display": "显示",
"dragonx_green": "DragonX(绿色)",
"edit": "编辑",
"error": "错误",
"error_format": "错误:%s",
"est_time_to_block": "预计出块时间",
"exit": "退出",
"explorer": "浏览器",
"export": "导出",
"export_csv": "导出 CSV",
"export_keys_btn": "导出密钥",
"export_keys_danger": "危险:这将导出您钱包中的所有私钥!任何获得此文件的人都可以窃取您的资金。请安全保管并在使用后删除。",
"export_keys_include_t": "包含 T 地址(透明)",
"export_keys_include_z": "包含 Z 地址(屏蔽)",
"export_keys_options": "导出选项:",
"export_keys_progress": "正在导出 %d/%d...",
"export_keys_success": "密钥导出成功",
"export_keys_title": "导出所有私钥",
"export_private_key": "导出私钥",
"export_tx_count": "导出 %zu 笔交易到 CSV 文件。",
"export_tx_file_fail": "无法创建 CSV 文件",
"export_tx_none": "没有交易可导出",
"export_tx_success": "交易导出成功",
"export_tx_title": "导出交易到 CSV",
"export_viewing_key": "导出查看密钥",
"failed_create_shielded": "无法创建屏蔽地址",
"failed_create_transparent": "无法创建透明地址",
"favorite_address": "收藏地址",
"fee": "手续费",
"fee_high": "高",
"fee_label": "手续费:",
"fee_low": "低",
"fee_normal": "普通",
"fetch_prices": "获取价格",
"file": "文件",
"file_save_location": "文件将保存至:~/.config/ObsidianDragon/",
"font_scale": "字体大小",
"from": "从",
"from_upper": "从",
"full_details": "完整详情",
"general": "常规",
"go_to_receive": "前往接收",
"height": "高度",
"help": "帮助",
"hide": "隐藏",
"hide_address": "隐藏地址",
"hide_zero_balances": "隐藏零余额",
"history": "历史",
"immature_type": "未成熟",
"import": "导入",
"import_key_btn": "导入密钥",
"import_key_formats": "支持的密钥格式:",
"import_key_full_rescan": "(0 = 完整重扫)",
"import_key_label": "私钥:",
"import_key_no_valid": "输入中未找到有效密钥",
"import_key_progress": "正在导入 %d/%d...",
"import_key_rescan": "导入后重新扫描区块链",
"import_key_start_height": "起始高度:",
"import_key_success": "密钥导入成功",
"import_key_t_format": "T 地址 WIF 私钥",
"import_key_title": "导入私钥",
"import_key_tooltip": "输入一个或多个私钥,每行一个。\n支持 z 地址和 t 地址密钥。\n以 # 开头的行视为注释。",
"import_key_warning": "警告:切勿分享您的私钥!从不可信来源导入密钥可能会危及您的钱包安全。",
"import_key_z_format": "Z 地址花费密钥 (secret-extended-key-...)",
"import_private_key": "导入私钥...",
"invalid_address": "无效的地址格式",
"ip_address": "IP 地址",
"keep": "保留",
"keep_daemon": "保持守护进程运行",
"key_export_click_retrieve": "点击从钱包中获取密钥",
"key_export_fetching": "正在从钱包获取密钥...",
"key_export_private_key": "私钥:",
"key_export_private_warning": "请保密此密钥!任何拥有此密钥的人都可以花费您的资金。切勿在网上或与不可信的人分享。",
"key_export_reveal": "显示密钥",
"key_export_viewing_key": "查看密钥:",
"key_export_viewing_keys_zonly": "查看密钥仅适用于屏蔽 (z) 地址",
"key_export_viewing_warning": "此查看密钥允许他人查看您的入账交易和余额,但不能花费您的资金。仅与信任的人分享。",
"label": "标签:",
"language": "语言",
"light": "浅色",
"loading": "加载中...",
"loading_addresses": "正在加载地址...",
"local_hashrate": "本地算力",
"low_spec_mode": "低配模式",
"market": "市场",
"market_12h": "12小时",
"market_18h": "18小时",
"market_24h": "24小时",
"market_24h_volume": "24小时交易量",
"market_6h": "6小时",
"market_attribution": "价格数据来自 NonKYC",
"market_btc_price": "BTC 价格",
"market_cap": "市值",
"market_no_history": "无价格历史",
"market_no_price": "无价格数据",
"market_now": "现在",
"market_pct_shielded": "%.0f%% 屏蔽",
"market_portfolio": "投资组合",
"market_price_unavailable": "价格数据不可用",
"market_refresh_price": "刷新价格数据",
"market_trade_on": "在 %s 交易",
"mature": "已成熟",
"max": "最大",
"memo": "备注(可选,加密)",
"memo_label": "备注:",
"memo_optional": "备注(可选)",
"memo_upper": "备注",
"memo_z_only": "注意:备注仅在发送到屏蔽 (z) 地址时可用",
"merge_description": "将多个 UTXO 合并到一个屏蔽地址。这可以帮助减小钱包大小并提高隐私性。",
"merge_funds": "合并资金",
"merge_started": "合并操作已开始",
"merge_title": "合并到地址",
"mine_when_idle": "空闲时挖矿",
"mined": "已挖得",
"mined_filter": "已挖得",
"mined_type": "已挖得",
"mined_upper": "已挖得",
"miner_fee": "矿工费",
"mining": "挖矿",
"mining_active": "活跃",
"mining_address_copied": "挖矿地址已复制",
"mining_all_time": "所有时间",
"mining_already_saved": "矿池 URL 已保存",
"mining_block_copied": "区块哈希已复制",
"mining_chart_1m_ago": "1分钟前",
"mining_chart_5m_ago": "5分钟前",
"mining_chart_now": "现在",
"mining_chart_start": "开始",
"mining_click": "点击",
"mining_click_copy_address": "点击复制地址",
"mining_click_copy_block": "点击复制区块哈希",
"mining_click_copy_difficulty": "点击复制难度",
"mining_connected": "已连接",
"mining_connecting": "连接中...",
"mining_control": "挖矿控制",
"mining_difficulty_copied": "难度已复制",
"mining_est_block": "预计区块",
"mining_est_daily": "预计日收益",
"mining_filter_all": "全部",
"mining_filter_tip_all": "显示所有收益",
"mining_filter_tip_pool": "仅显示矿池收益",
"mining_filter_tip_solo": "仅显示单人收益",
"mining_idle_off_tooltip": "启用空闲挖矿",
"mining_idle_on_tooltip": "禁用空闲挖矿",
"mining_local_hashrate": "本地算力",
"mining_mine": "挖矿",
"mining_mining_addr": "挖矿地址",
"mining_network": "网络",
"mining_no_blocks_yet": "尚未找到区块",
"mining_no_payouts_yet": "尚无矿池支付",
"mining_no_saved_addresses": "没有保存的地址",
"mining_no_saved_pools": "没有保存的矿池",
"mining_off": "挖矿已关闭",
"mining_on": "挖矿已开启",
"connected_peers": "已连接节点",
"banned_peers": "已封禁节点",
"ip_address": "IP 地址",
"version": "版本",
"height": "高度",
"ping": "延迟",
"ban": "封禁",
"unban": "解封",
"clear_all_bans": "清除所有封禁",
"price_chart": "价格图表",
"current_price": "当前价格",
"24h_change": "24小时涨跌",
"24h_volume": "24小时成交量",
"market_cap": "市值",
"general": "通用",
"display": "显示",
"mining_open_in_explorer": "在浏览器中打开",
"mining_payout_address": "支付地址",
"mining_payout_tooltip": "接收挖矿奖励的地址",
"mining_pool": "矿池",
"mining_pool_hashrate": "矿池算力",
"mining_pool_url": "矿池 URL",
"mining_recent_blocks": "最近区块",
"mining_recent_payouts": "最近矿池支付",
"mining_remove": "移除",
"mining_reset_defaults": "重置默认值",
"mining_save_payout_address": "保存支付地址",
"mining_save_pool_url": "保存矿池 URL",
"mining_saved_addresses": "已保存地址:",
"mining_saved_pools": "已保存矿池:",
"mining_shares": "份额",
"mining_show_chart": "图表",
"mining_show_log": "日志",
"mining_solo": "单人",
"mining_starting": "启动中...",
"mining_starting_tooltip": "矿工正在启动...",
"mining_statistics": "挖矿统计",
"mining_stop": "停止",
"mining_stop_solo_for_pool": "启动矿池挖矿前请先停止单人挖矿",
"mining_stop_solo_for_pool_settings": "请停止单人挖矿以更改矿池设置",
"mining_stopping": "停止中...",
"mining_stopping_tooltip": "矿工正在停止...",
"mining_syncing_tooltip": "区块链同步中...",
"mining_threads": "挖矿线程",
"mining_to_save": "保存",
"mining_today": "今天",
"mining_uptime": "运行时间",
"mining_yesterday": "昨天",
"network": "网络",
"theme": "主题",
"language": "语言",
"dragonx_green": "DragonX(绿色)",
"dark": "深色",
"light": "浅色",
"allow_custom_fees": "允许自定义手续费",
"use_embedded_daemon": "使用内置 dragonxd",
"save": "保存",
"close": "关闭",
"file": "文件",
"edit": "编辑",
"view": "查看",
"help": "帮助",
"import_private_key": "导入私钥...",
"backup_wallet": "备份钱包...",
"exit": "退出",
"about_dragonx": "关于 ObsidianDragon",
"network_fee": "网络手续费",
"network_hashrate": "全网算力",
"new": "+ 新建",
"new_shielded_created": "新屏蔽地址已创建",
"new_t_address": "新 T 地址",
"new_t_transparent": "新 t 地址(透明)",
"new_transparent_created": "新透明地址已创建",
"new_z_address": "新 Z 地址",
"new_z_shielded": "新 z 地址(屏蔽)",
"no_addresses": "未找到地址。请使用上方按钮创建一个。",
"no_addresses_available": "无可用地址",
"no_addresses_match": "没有匹配过滤器的地址",
"no_addresses_with_balance": "没有有余额的地址",
"no_matching": "没有匹配的交易",
"no_recent_receives": "没有最近的接收",
"no_recent_sends": "没有最近的发送",
"no_transactions": "未找到交易",
"node": "节点",
"node_security": "节点与安全",
"noise": "噪点",
"not_connected": "未连接到守护进程...",
"not_connected_to_daemon": "未连接到守护进程",
"notes": "备注",
"notes_optional": "备注(可选):",
"output_filename": "输出文件名:",
"overview": "概览",
"paste": "粘贴",
"paste_from_clipboard": "从剪贴板粘贴",
"pay_from": "付款来源",
"payment_request": "付款请求",
"payment_request_copied": "付款请求已复制",
"payment_uri_copied": "付款 URI 已复制",
"peers": "节点",
"peers_avg_ping": "平均延迟",
"peers_ban_24h": "封禁节点 24 小时",
"peers_ban_score": "封禁评分:%d",
"peers_banned": "已封禁",
"peers_banned_count": "已封禁:%d",
"peers_best_block": "最佳区块",
"peers_blockchain": "区块链",
"peers_blocks": "区块",
"peers_blocks_left": "剩余 %d 个区块",
"peers_clear_all_bans": "解除所有封禁",
"peers_click_copy": "点击复制",
"peers_connected": "已连接",
"peers_connected_count": "已连接:%d",
"peers_copy_ip": "复制 IP",
"peers_dir_in": "入",
"peers_dir_out": "出",
"peers_hash_copied": "哈希已复制",
"peers_hashrate": "算力",
"peers_in_out": "入/出",
"peers_longest": "最长",
"peers_longest_chain": "最长链",
"peers_memory": "内存",
"peers_no_banned": "无已封禁节点",
"peers_no_connected": "无已连接节点",
"peers_no_tls": "无 TLS",
"peers_notarized": "已公证",
"peers_p2p_port": "P2P 端口",
"peers_peer_label": "节点:%s",
"peers_protocol": "协议",
"peers_received": "已接收",
"peers_refresh": "刷新",
"peers_refresh_tooltip": "刷新节点列表",
"peers_refreshing": "刷新中...",
"peers_sent": "已发送",
"peers_tt_id": "ID:%d",
"peers_tt_received": "已接收:%s",
"peers_tt_sent": "已发送:%s",
"peers_tt_services": "服务:%s",
"peers_tt_start_height": "起始高度:%d",
"peers_tt_synced": "已同步 H/B:%d/%d",
"peers_tt_tls_cipher": "TLS:%s",
"peers_unban": "解除封禁",
"peers_upper": "节点",
"peers_version": "版本",
"pending": "待处理",
"ping": "延迟",
"price_chart": "价格图表",
"qr_code": "二维码",
"qr_failed": "无法生成二维码",
"qr_title": "二维码",
"qr_unavailable": "二维码不可用",
"ram_daemon_gb": "守护进程:%.1f GB (%s)",
"ram_daemon_mb": "守护进程:%.0f MB (%s)",
"ram_system_gb": "系统:%.1f / %.0f GB",
"ram_wallet_gb": "钱包:%.1f GB",
"ram_wallet_mb": "钱包:%.0f MB",
"receive": "接收",
"received": "已接收",
"received_filter": "已接收",
"received_label": "已接收",
"received_upper": "已接收",
"receiving_addresses": "您的接收地址",
"recent_received": "最近接收",
"recent_sends": "最近发送",
"recipient": "收款方",
"recv_type": "接收",
"refresh": "刷新",
"refresh_now": "立即刷新",
"about": "关于",
"import": "导入",
"export": "导出",
"copy_to_clipboard": "复制到剪贴板",
"connected": "已连接",
"disconnected": "已断开",
"connecting": "连接中...",
"syncing": "同步中...",
"block": "区块",
"no_addresses_available": "暂无可用地址",
"error": "错误",
"remove_favorite": "移除收藏",
"report_bug": "报告错误",
"request_amount": "金额(可选):",
"request_copy_uri": "复制 URI",
"request_description": "生成一个付款请求,他人可以扫描或复制。二维码包含您的地址和可选的金额/备注。",
"request_label": "标签(可选):",
"request_memo": "备注(可选):",
"request_payment": "请求付款",
"request_payment_uri": "付款 URI:",
"request_receive_address": "接收地址:",
"request_select_address": "选择地址...",
"request_shielded_addrs": "-- 屏蔽地址 --",
"request_title": "请求付款",
"request_transparent_addrs": "-- 透明地址 --",
"request_uri_copied": "付款 URI 已复制到剪贴板",
"rescan": "重新扫描",
"reset_to_defaults": "重置为默认值",
"restore_address": "恢复地址",
"review_send": "审核发送",
"rpc_host": "RPC 主机",
"rpc_pass": "密码",
"rpc_port": "端口",
"rpc_user": "用户名",
"save": "保存",
"save_settings": "保存设置",
"save_z_transactions": "将 Z 交易保存到列表",
"search_placeholder": "搜索...",
"security": "安全",
"select_address": "选择地址...",
"select_receiving_address": "选择接收地址...",
"select_source_address": "选择来源地址...",
"send": "发送",
"send_amount": "金额",
"send_amount_details": "金额详情",
"send_amount_upper": "金额",
"send_clear_fields": "清除所有表单字段?",
"send_copy_error": "复制错误",
"send_dismiss": "关闭",
"send_error_copied": "错误已复制到剪贴板",
"send_error_prefix": "错误:%s",
"send_exceeds_available": "超过可用额 (%.8f)",
"send_fee": "手续费",
"send_fee_high": "高",
"send_fee_low": "低",
"send_fee_normal": "普通",
"send_form_restored": "表单已恢复",
"send_from_this_address": "从此地址发送",
"send_go_to_receive": "前往接收",
"send_keep": "保留",
"send_network_fee": "网络手续费",
"send_no_balance": "无余额",
"send_no_recent": "没有最近的发送",
"send_recent_sends": "最近发送",
"send_recipient": "收款方",
"send_select_source": "选择来源地址...",
"send_sending_from": "发送来源",
"send_submitting": "正在提交交易...",
"send_switch_to_receive": "切换到接收页面获取您的地址并开始接收资金。",
"send_to": "发送至",
"send_tooltip_enter_amount": "请输入发送金额",
"send_tooltip_exceeds_balance": "金额超过可用余额",
"send_tooltip_in_progress": "交易正在进行中",
"send_tooltip_invalid_address": "请输入有效的收款地址",
"send_tooltip_not_connected": "未连接到守护进程",
"send_tooltip_select_source": "请先选择来源地址",
"send_tooltip_syncing": "请等待区块链同步",
"send_total": "合计",
"send_transaction": "发送交易",
"send_tx_failed": "交易失败",
"send_tx_sent": "交易已发送!",
"send_tx_success": "交易发送成功!",
"send_txid_copied": "交易ID 已复制到剪贴板",
"send_txid_label": "TxID:%s",
"send_valid_shielded": "有效的屏蔽地址",
"send_valid_transparent": "有效的透明地址",
"send_wallet_empty": "您的钱包是空的",
"send_yes_clear": "是,清除",
"sending": "正在发送交易",
"sending_from": "发送来源",
"sent": "已发送",
"sent_filter": "已发送",
"sent_type": "已发送",
"sent_upper": "已发送",
"settings": "设置",
"settings_about_text": "DragonX (DRGX) 屏蔽加密货币钱包,使用 Dear ImGui 构建,提供轻量、便携的体验。",
"settings_acrylic_level": "亚克力级别:",
"settings_address_book": "地址簿...",
"settings_auto_detected": "从 DRAGONX.conf 自动检测",
"settings_auto_lock": "自动锁定",
"settings_auto_shield_desc": "自动将透明资金转移到屏蔽地址",
"settings_auto_shield_funds": "自动屏蔽透明资金",
"settings_backup": "备份...",
"settings_block_explorer_urls": "区块浏览器网址",
"settings_builtin": "内置",
"settings_change_passphrase": "更改密码",
"settings_change_pin": "更改 PIN",
"settings_clear_ztx": "清除 Z-Tx 历史",
"settings_clear_ztx_desc": "删除本地存储的屏蔽交易数据",
"settings_clear_ztx_long": "清除已保存的 Z-交易历史",
"settings_configure_explorer": "配置外部区块浏览器链接",
"settings_configure_rpc": "配置 dragonxd 守护进程连接",
"settings_connection": "连接",
"settings_copyright": "版权所有 2024-2026 DragonX 开发者 | GPLv3 许可证",
"settings_custom": "自定义",
"settings_data_dir": "数据目录:",
"settings_debug_changed": "调试类别已更改——重启守护进程以应用",
"settings_debug_restart_note": "更改将在重启守护进程后生效。",
"settings_debug_select": "选择要启用的守护进程调试日志类别(-debug= 标志)。",
"settings_encrypt_first_pin": "请先加密钱包以启用 PIN",
"settings_encrypt_wallet": "加密钱包",
"settings_explorer_hint": "URL 应包含尾部斜杠。将自动附加 txid/地址。",
"settings_export_all": "全部导出...",
"settings_export_csv": "导出 CSV...",
"settings_export_key": "导出密钥...",
"settings_gradient_bg": "渐变背景",
"settings_gradient_desc": "用平滑渐变替换纹理背景",
"settings_idle_after": "之后",
"settings_import_key": "导入密钥...",
"settings_language_note": "注意:部分文本需要重启才能更新",
"settings_lock_now": "立即锁定",
"settings_locked": "已锁定",
"settings_merge_to_address": "合并到地址...",
"settings_noise_opacity": "噪点不透明度:",
"settings_not_encrypted": "未加密",
"settings_not_found": "未找到",
"settings_other": "其他",
"settings_pin_active": "PIN",
"settings_privacy": "隐私",
"settings_quick_unlock_pin": "快速解锁 PIN",
"settings_reduce_transparency": "降低透明度",
"settings_remove_encryption": "移除加密",
"settings_remove_pin": "移除 PIN",
"settings_request_payment": "请求付款...",
"settings_rescan_desc": "重新扫描区块链以查找丢失的交易",
"settings_restart_daemon": "重启守护进程",
"settings_rpc_connection": "RPC 连接",
"settings_rpc_note": "注意:连接设置通常从 DRAGONX.conf 自动检测",
"settings_save_shielded_desc": "将 z-addr 交易存储在本地文件中以供查看",
"settings_save_shielded_local": "将屏蔽交易历史保存到本地",
"settings_set_pin": "设置 PIN",
"settings_shield_mining": "屏蔽挖矿...",
"settings_solid_colors_desc": "使用纯色代替模糊效果(无障碍功能)",
"settings_tor_desc": "通过 Tor 路由所有连接以增强隐私",
"settings_unlocked": "已解锁",
"settings_use_tor_network": "使用 Tor 进行网络连接",
"settings_validate_address": "验证地址...",
"settings_visual_effects": "视觉效果",
"settings_wallet_file_size": "钱包文件大小:%s",
"settings_wallet_info": "钱包信息",
"settings_wallet_location": "钱包位置:%s",
"settings_wallet_maintenance": "钱包维护",
"settings_wallet_not_found": "未找到钱包文件",
"settings_wallet_size_label": "钱包大小:",
"setup_wizard": "设置向导",
"share": "分享",
"shield_check_status": "检查状态",
"shield_completed": "操作成功完成!",
"shield_description": "通过将透明地址的 coinbase 输出发送到屏蔽地址来屏蔽您的挖矿奖励。这可以隐藏您的挖矿收入,提高隐私性。",
"shield_from_address": "从地址:",
"shield_funds": "屏蔽资金",
"shield_in_progress": "操作进行中...",
"shield_max_utxos": "每次操作最大 UTXO 数",
"shield_merge_done": "屏蔽/合并完成!",
"shield_operation_id": "操作 ID:%s",
"shield_select_z": "选择 z 地址...",
"shield_started": "屏蔽操作已开始",
"shield_title": "屏蔽 Coinbase 奖励",
"shield_to_address": "至地址(屏蔽):",
"shield_utxo_limit": "UTXO 限制:",
"shield_wildcard_hint": "使用 '*' 从所有透明地址屏蔽",
"shielded": "屏蔽",
"shielded_to": "屏蔽至",
"shielded_type": "屏蔽",
"show": "显示",
"show_hidden": "显示已隐藏 (%d)",
"show_qr_code": "显示二维码",
"showing_transactions": "显示第 %d–%d 笔,共 %d 笔交易(总计:%zu)",
"simple_background": "简单背景",
"start_mining": "开始挖矿",
"status": "状态",
"stop_external": "停止外部守护进程",
"stop_mining": "停止挖矿",
"submitting_transaction": "正在提交交易...",
"success": "成功",
"summary": "摘要",
"syncing": "同步中...",
"t_addresses": "T 地址",
"test_connection": "测试",
"theme": "主题",
"theme_effects": "主题效果",
"time_days_ago": "%d 天前",
"time_hours_ago": "%d 小时前",
"time_minutes_ago": "%d 分钟前",
"time_seconds_ago": "%d 秒前",
"to": "至",
"to_upper": "至",
"tools": "工具",
"total": "合计",
"transaction_id": "交易 ID",
"transaction_sent": "交易发送成功",
"transaction_sent_msg": "交易已发送!",
"transaction_url": "交易 URL",
"transactions": "交易",
"transactions_upper": "交易",
"transparent": "透明",
"tt_addr_url": "在区块浏览器中查看地址的基础 URL",
"tt_address_book": "管理已保存的地址以快速发送",
"tt_auto_lock": "在此不活动时间后锁定钱包",
"tt_auto_shield": "自动将透明余额转移到屏蔽地址以增强隐私",
"tt_backup": "创建 wallet.dat 的备份",
"tt_block_explorer": "在浏览器中打开 DragonX 区块浏览器",
"tt_blur": "模糊程度(0%% = 关闭,100%% = 最大)",
"tt_change_pass": "更改钱包加密密码",
"tt_change_pin": "更改您的解锁 PIN",
"tt_clear_ztx": "删除本地缓存的 z-交易历史",
"tt_custom_fees": "发送交易时启用手动费用输入",
"tt_custom_theme": "自定义主题已激活",
"tt_debug_collapse": "折叠调试日志选项",
"tt_debug_expand": "展开调试日志选项",
"tt_encrypt": "使用密码加密 wallet.dat",
"tt_export_all": "将所有私钥导出到文件",
"tt_export_csv": "将交易历史导出为 CSV 电子表格",
"tt_export_key": "导出所选地址的私钥",
"tt_fetch_prices": "从 CoinGecko API 获取 DRGX 市场价格",
"tt_font_scale": "缩放所有文本和界面(1.0x = 默认,最大 1.5x)。",
"tt_idle_delay": "开始挖矿前等待多长时间",
"tt_import_key": "将私钥(zkey 或 tkey)导入此钱包",
"tt_keep_daemon": "运行设置向导时守护进程仍会停止",
"tt_language": "钱包界面语言",
"tt_layout_hotkey": "快捷键:左/右箭头键切换余额布局",
"tt_lock": "立即锁定钱包",
"tt_low_spec": "禁用所有重度视觉效果\\n快捷键:Ctrl+Shift+Down",
"tt_merge": "将多个 UTXO 合并到一个地址",
"tt_mine_idle": "系统空闲时自动开始挖矿\\n(无键盘/鼠标输入)",
"tt_noise": "颗粒纹理强度(0%% = 关闭,100%% = 最大)",
"tt_open_dir": "点击在文件管理器中打开",
"tt_remove_encrypt": "移除加密并以未受保护状态存储钱包",
"tt_remove_pin": "移除 PIN 并要求密码解锁",
"tt_report_bug": "在项目跟踪器中报告问题",
"tt_request_payment": "生成带二维码的付款请求",
"tt_rescan": "重新扫描区块链以查找丢失的交易",
"tt_reset_settings": "从磁盘重新加载设置(撤消未保存的更改)",
"tt_restart_daemon": "重启守护进程以应用调试日志更改",
"tt_rpc_host": "DragonX 守护进程主机名",
"tt_rpc_pass": "RPC 认证密码",
"tt_rpc_port": "守护进程 RPC 连接端口",
"tt_rpc_user": "RPC 认证用户名",
"tt_save_settings": "将所有设置保存到磁盘",
"tt_save_ztx": "将 z-address 交易历史存储在本地以加快加载速度",
"tt_scan_themes": "扫描新主题。\\n将主题文件夹放在:\\n%s",
"tt_scanline": "控制台中的 CRT 扫描线效果",
"tt_set_pin": "设置 4-8 位 PIN 以快速解锁",
"tt_shield_mining": "将透明挖矿奖励转移到屏蔽地址",
"tt_simple_bg": "使用简单渐变作为背景\\n快捷键:Ctrl+Up",
"tt_simple_bg_alt": "使用主题背景图像的渐变版本\\n快捷键:Ctrl+Up",
"tt_stop_external": "适用于连接到在此钱包\\n外部启动的守护进程",
"tt_test_conn": "验证与守护进程的 RPC 连接",
"tt_theme_effects": "每个主题的闪烁、发光、色调循环",
"tt_theme_hotkey": "快捷键:Ctrl+左/右箭头切换主题",
"tt_tor": "通过 Tor 网络路由守护进程连接以实现匿名",
"tt_tx_url": "在区块浏览器中查看交易的基础 URL",
"tt_ui_opacity": "卡片和侧边栏不透明度(100%% = 完全不透明,越低越透明)",
"tt_validate": "检查 DragonX 地址是否有效",
"tt_verbose": "将详细连接诊断、守护进程状态\\n和端口所有者信息记录到控制台选项卡",
"tt_website": "打开 DragonX 网站",
"tt_window_opacity": "背景不透明度(越低 = 桌面透过窗口可见)",
"tt_wizard": "重新运行初始设置向导\\n守护进程将被重启",
"tx_confirmations": "%d 次确认",
"tx_details_title": "交易详情",
"tx_from_address": "发送地址:",
"tx_id_label": "交易 ID:",
"tx_immature": "未成熟",
"tx_mined": "已挖得",
"tx_received": "已接收",
"tx_sent": "已发送",
"tx_to_address": "接收地址:",
"tx_view_explorer": "在浏览器中查看",
"txs_count": "%d 笔交易",
"type": "类型",
"ui_opacity": "界面透明度",
"unban": "解除封禁",
"unconfirmed": "未确认",
"undo_clear": "撤销清除",
"unknown": "未知",
"use_embedded_daemon": "使用内置 dragonxd",
"use_tor": "使用 Tor",
"validate_btn": "验证",
"validate_description": "输入一个 DragonX 地址来检查它是否有效以及是否属于此钱包。",
"validate_invalid": "无效",
"validate_is_mine": "此钱包拥有该地址",
"validate_not_mine": "不属于此钱包",
"validate_ownership": "所有权:",
"validate_results": "结果:",
"validate_shielded_type": "屏蔽(z 地址)",
"validate_status": "状态:",
"validate_title": "验证地址",
"validate_transparent_type": "透明(t 地址)",
"validate_type": "类型:",
"validate_valid": "有效",
"validating": "验证中...",
"verbose_logging": "详细日志",
"version": "版本",
"view": "查看",
"view_details": "查看详情",
"view_on_explorer": "在浏览器中查看",
"waiting_for_daemon": "等待守护进程连接...",
"wallet": "钱包",
"wallet_empty": "您的钱包是空的",
"wallet_empty_hint": "切换到接收页面获取您的地址并开始接收资金。",
"warning": "警告",
"amount_exceeds_balance": "金额超出余额",
"transaction_sent": "交易发送成功"
"warning_upper": "警告!",
"website": "网站",
"window_opacity": "窗口透明度",
"yes_clear": "是,清除",
"your_addresses": "您的地址",
"z_addresses": "Z 地址"
}
File diff suppressed because it is too large Load Diff
+645
View File
@@ -0,0 +1,645 @@
#!/usr/bin/env python3
"""Generate German (de) translations for ObsidianDragon wallet."""
import json, os
translations = {
"24h_change": "24h Änderung",
"24h_volume": "24h Volumen",
"about": "Über",
"about_block_explorer": "Block-Explorer",
"about_block_height": "Blockhöhe:",
"about_build_date": "Erstellungsdatum:",
"about_build_type": "Build-Typ:",
"about_chain": "Chain:",
"about_connections": "Verbindungen:",
"about_credits": "Danksagungen",
"about_daemon": "Daemon:",
"about_debug": "Debug",
"about_dragonx": "Über ObsidianDragon",
"about_edition": "ImGui Edition",
"about_github": "GitHub",
"about_imgui": "ImGui:",
"about_license": "Lizenz",
"about_license_text": "Diese Software wird unter der GNU General Public License v3 (GPLv3) veröffentlicht. Sie dürfen diese Software gemäß den Lizenzbedingungen frei verwenden, modifizieren und verbreiten.",
"about_peers_count": "%zu Peers",
"about_release": "Release",
"about_title": "Über ObsidianDragon",
"about_version": "Version:",
"about_website": "Webseite",
"acrylic": "Acryl",
"add": "Hinzufügen",
"address": "Adresse",
"address_book_add": "Adresse hinzufügen",
"address_book_add_new": "Neue hinzufügen",
"address_book_added": "Adresse zum Buch hinzugefügt",
"address_book_count": "%zu Adressen gespeichert",
"address_book_deleted": "Eintrag gelöscht",
"address_book_edit": "Adresse bearbeiten",
"address_book_empty": "Keine gespeicherten Adressen. Klicken Sie auf 'Neue hinzufügen', um eine hinzuzufügen.",
"address_book_exists": "Adresse existiert bereits im Buch",
"address_book_title": "Adressbuch",
"address_book_update_failed": "Aktualisierung fehlgeschlagen - Adresse könnte doppelt sein",
"address_book_updated": "Adresse aktualisiert",
"address_copied": "Adresse in Zwischenablage kopiert",
"address_details": "Adressdetails",
"address_label": "Adresse:",
"address_upper": "ADRESSE",
"address_url": "Adress-URL",
"addresses_appear_here": "Ihre Empfangsadressen erscheinen hier, sobald Sie verbunden sind.",
"advanced": "ERWEITERT",
"all_filter": "Alle",
"allow_custom_fees": "Benutzerdefinierte Gebühren erlauben",
"amount": "Betrag",
"amount_details": "BETRAGSDETAILS",
"amount_exceeds_balance": "Betrag übersteigt Guthaben",
"amount_label": "Betrag:",
"appearance": "ERSCHEINUNGSBILD",
"auto_shield": "Mining automatisch abschirmen",
"available": "Verfügbar",
"backup_backing_up": "Sicherung läuft...",
"backup_create": "Sicherung erstellen",
"backup_created": "Wallet-Sicherung erstellt",
"backup_data": "SICHERUNG & DATEN",
"backup_description": "Erstellen Sie eine Sicherung Ihrer wallet.dat-Datei. Diese Datei enthält alle Ihre privaten Schlüssel und den Transaktionsverlauf. Bewahren Sie die Sicherung an einem sicheren Ort auf.",
"backup_destination": "Sicherungsziel:",
"backup_tip_external": "Speichern Sie Sicherungen auf externen Laufwerken oder Cloud-Speicher",
"backup_tip_multiple": "Erstellen Sie mehrere Sicherungen an verschiedenen Orten",
"backup_tip_test": "Testen Sie regelmäßig die Wiederherstellung aus der Sicherung",
"backup_tips": "Tipps:",
"backup_title": "Wallet sichern",
"backup_wallet": "Wallet sichern...",
"backup_wallet_not_found": "Warnung: wallet.dat nicht am erwarteten Speicherort gefunden",
"balance": "Guthaben",
"balance_layout": "Guthaben-Layout",
"ban": "Sperren",
"banned_peers": "Gesperrte Peers",
"block": "Block",
"block_bits": "Bits:",
"block_click_next": "Klicken für nächsten Block",
"block_click_prev": "Klicken für vorherigen Block",
"block_explorer": "Block-Explorer",
"block_get_info": "Block-Info abrufen",
"block_hash": "Block-Hash:",
"block_height": "Blockhöhe:",
"block_info_title": "Block-Informationen",
"block_merkle_root": "Merkle-Root:",
"block_nav_next": "Weiter >>",
"block_nav_prev": "<< Zurück",
"block_next": "Nächster Block:",
"block_previous": "Vorheriger Block:",
"block_size": "Größe:",
"block_timestamp": "Zeitstempel:",
"block_transactions": "Transaktionen:",
"blockchain_syncing": "Blockchain synchronisiert (%.1f%%)... Guthaben könnten ungenau sein.",
"cancel": "Abbrechen",
"characters": "Zeichen",
"clear": "Leeren",
"clear_all_bans": "Alle Sperren aufheben",
"clear_form_confirm": "Alle Formularfelder leeren?",
"clear_request": "Anfrage leeren",
"click_copy_address": "Klicken zum Kopieren der Adresse",
"click_copy_uri": "Klicken zum Kopieren der URI",
"close": "Schließen",
"conf_count": "%d Best.",
"confirm_and_send": "Bestätigen & Senden",
"confirm_send": "Senden bestätigen",
"confirm_transaction": "Transaktion bestätigen",
"confirmations": "Bestätigungen",
"confirmations_display": "%d Bestätigungen | %s",
"confirmed": "Bestätigt",
"connected": "Verbunden",
"connected_peers": "Verbundene Peers",
"connecting": "Verbinde...",
"console": "Konsole",
"console_auto_scroll": "Automatisch scrollen",
"console_available_commands": "Verfügbare Befehle:",
"console_capturing_output": "Erfasse Daemon-Ausgabe...",
"console_clear": "Leeren",
"console_clear_console": "Konsole leeren",
"console_cleared": "Konsole geleert",
"console_click_commands": "Befehle oben klicken zum Einfügen",
"console_click_insert": "Klicken zum Einfügen",
"console_click_insert_params": "Klicken zum Einfügen mit Parametern",
"console_close": "Schließen",
"console_commands": "Befehle",
"console_common_rpc": "Häufige RPC-Befehle:",
"console_completions": "Vervollständigungen:",
"console_connected": "Verbunden mit Daemon",
"console_copy_all": "Alles kopieren",
"console_copy_selected": "Kopieren",
"console_daemon": "Daemon",
"console_daemon_error": "Daemon-Fehler!",
"console_daemon_started": "Daemon gestartet",
"console_daemon_stopped": "Daemon gestoppt",
"console_disconnected": "Vom Daemon getrennt",
"console_errors": "Fehler",
"console_filter_hint": "Ausgabe filtern...",
"console_help_clear": " clear - Konsole leeren",
"console_help_getbalance": " getbalance - Transparentes Guthaben anzeigen",
"console_help_getblockcount": " getblockcount - Aktuelle Blockhöhe anzeigen",
"console_help_getinfo": " getinfo - Knoteninformationen anzeigen",
"console_help_getmininginfo": " getmininginfo - Mining-Status anzeigen",
"console_help_getpeerinfo": " getpeerinfo - Verbundene Peers anzeigen",
"console_help_gettotalbalance": " gettotalbalance - Gesamtguthaben anzeigen",
"console_help_help": " help - Diese Hilfe anzeigen",
"console_help_setgenerate": " setgenerate - Mining steuern",
"console_help_stop": " stop - Daemon stoppen",
"console_line_count": "%zu Zeilen",
"console_new_lines": "%d neue Zeilen",
"console_no_daemon": "Kein Daemon",
"console_not_connected": "Fehler: Nicht mit Daemon verbunden",
"console_rpc_reference": "RPC-Befehlsreferenz",
"console_scanline": "Konsolen-Scanline",
"console_search_commands": "Befehle suchen...",
"console_select_all": "Alles auswählen",
"console_show_daemon_output": "Daemon-Ausgabe anzeigen",
"console_show_errors_only": "Nur Fehler anzeigen",
"console_show_rpc_ref": "RPC-Befehlsreferenz anzeigen",
"console_showing_lines": "Zeige %zu von %zu Zeilen",
"console_starting_node": "Knoten wird gestartet...",
"console_status_error": "Fehler",
"console_status_running": "Läuft",
"console_status_starting": "Startet",
"console_status_stopped": "Gestoppt",
"console_status_stopping": "Stoppt",
"console_status_unknown": "Unbekannt",
"console_tab_completion": "Tab zur Vervollständigung",
"console_type_help": "Geben Sie 'help' ein für verfügbare Befehle",
"console_welcome": "Willkommen bei ObsidianDragon Konsole",
"console_zoom_in": "Vergrößern",
"console_zoom_out": "Verkleinern",
"copy": "Kopieren",
"copy_address": "Vollständige Adresse kopieren",
"copy_error": "Fehler kopieren",
"copy_to_clipboard": "In Zwischenablage kopieren",
"copy_txid": "TxID kopieren",
"copy_uri": "URI kopieren",
"current_price": "Aktueller Preis",
"custom_fees": "Benutzerdefinierte Gebühren",
"dark": "Dunkel",
"date": "Datum",
"date_label": "Datum:",
"delete": "Löschen",
"difficulty": "Schwierigkeit",
"disconnected": "Getrennt",
"dismiss": "Verwerfen",
"display": "Anzeige",
"dragonx_green": "DragonX (Grün)",
"edit": "Bearbeiten",
"error": "Fehler",
"est_time_to_block": "Gesch. Zeit bis Block",
"exit": "Beenden",
"explorer": "EXPLORER",
"export": "Exportieren",
"export_csv": "CSV exportieren",
"export_keys_btn": "Schlüssel exportieren",
"export_keys_danger": "ACHTUNG: Dies exportiert ALLE privaten Schlüssel aus Ihrer Wallet! Jeder mit Zugriff auf diese Datei kann Ihre Gelder stehlen. Sicher aufbewahren und nach Gebrauch löschen.",
"export_keys_include_t": "T-Adressen einschließen (transparent)",
"export_keys_include_z": "Z-Adressen einschließen (abgeschirmt)",
"export_keys_options": "Export-Optionen:",
"export_keys_success": "Schlüssel erfolgreich exportiert",
"export_keys_title": "Alle privaten Schlüssel exportieren",
"export_private_key": "Privaten Schlüssel exportieren",
"export_tx_count": "%zu Transaktionen als CSV exportieren.",
"export_tx_file_fail": "CSV-Datei konnte nicht erstellt werden",
"export_tx_none": "Keine Transaktionen zum Exportieren",
"export_tx_success": "Transaktionen erfolgreich exportiert",
"export_tx_title": "Transaktionen als CSV exportieren",
"export_viewing_key": "Betrachtungsschlüssel exportieren",
"failed_create_shielded": "Abgeschirmte Adresse konnte nicht erstellt werden",
"failed_create_transparent": "Transparente Adresse konnte nicht erstellt werden",
"fee": "Gebühr",
"fee_high": "Hoch",
"fee_label": "Gebühr:",
"fee_low": "Niedrig",
"fee_normal": "Normal",
"fetch_prices": "Preise abrufen",
"file": "Datei",
"file_save_location": "Datei wird gespeichert in: ~/.config/ObsidianDragon/",
"font_scale": "Schriftgröße",
"from": "Von",
"from_upper": "VON",
"full_details": "Alle Details",
"general": "Allgemein",
"go_to_receive": "Zum Empfangen",
"height": "Höhe",
"help": "Hilfe",
"hide": "Ausblenden",
"history": "Verlauf",
"immature_type": "Unreif",
"import": "Importieren",
"import_key_btn": "Schlüssel importieren",
"import_key_formats": "Unterstützte Schlüsselformate:",
"import_key_full_rescan": "(0 = vollständiger Rescan)",
"import_key_label": "Privater Schlüssel:",
"import_key_no_valid": "Keine gültigen Schlüssel in der Eingabe gefunden",
"import_key_rescan": "Blockchain nach Import neu scannen",
"import_key_start_height": "Starthöhe:",
"import_key_success": "Schlüssel erfolgreich importiert",
"import_key_t_format": "T-Adresse WIF private Schlüssel",
"import_key_title": "Privaten Schlüssel importieren",
"import_key_tooltip": "Geben Sie einen oder mehrere private Schlüssel ein, einen pro Zeile.\nUnterstützt sowohl z-Adresse als auch t-Adresse Schlüssel.\nZeilen die mit # beginnen werden als Kommentare behandelt.",
"import_key_warning": "Warnung: Teilen Sie niemals Ihre privaten Schlüssel! Das Importieren von Schlüsseln aus nicht vertrauenswürdigen Quellen kann Ihr Wallet gefährden.",
"import_key_z_format": "Z-Adresse Ausgabeschlüssel (secret-extended-key-...)",
"import_private_key": "Privaten Schlüssel importieren...",
"invalid_address": "Ungültiges Adressformat",
"ip_address": "IP-Adresse",
"keep": "Behalten",
"keep_daemon": "Daemon weiterlaufen lassen",
"key_export_fetching": "Schlüssel wird aus Wallet abgerufen...",
"key_export_private_key": "Privater Schlüssel:",
"key_export_private_warning": "Halten Sie diesen Schlüssel GEHEIM! Jeder mit diesem Schlüssel kann Ihre Gelder ausgeben. Teilen Sie ihn niemals online oder mit nicht vertrauenswürdigen Parteien.",
"key_export_reveal": "Schlüssel anzeigen",
"key_export_viewing_key": "Betrachtungsschlüssel:",
"key_export_viewing_warning": "Dieser Betrachtungsschlüssel ermöglicht es anderen, Ihre eingehenden Transaktionen und Ihr Guthaben zu sehen, aber NICHT Ihre Gelder auszugeben. Teilen Sie ihn nur mit vertrauenswürdigen Parteien.",
"label": "Bezeichnung:",
"language": "Sprache",
"light": "Hell",
"loading": "Laden...",
"loading_addresses": "Adressen werden geladen...",
"local_hashrate": "Lokale Hashrate",
"low_spec_mode": "Energiesparmodus",
"market": "Markt",
"market_12h": "12h",
"market_18h": "18h",
"market_24h": "24h",
"market_24h_volume": "24H VOLUMEN",
"market_6h": "6h",
"market_attribution": "Preisdaten von NonKYC",
"market_btc_price": "BTC PREIS",
"market_cap": "Marktkapitalisierung",
"market_no_history": "Kein Preisverlauf verfügbar",
"market_no_price": "Keine Preisdaten",
"market_now": "Jetzt",
"market_pct_shielded": "%.0f%% Abgeschirmt",
"market_portfolio": "PORTFOLIO",
"market_price_unavailable": "Preisdaten nicht verfügbar",
"market_refresh_price": "Preisdaten aktualisieren",
"market_trade_on": "Handeln auf %s",
"mature": "Reif",
"max": "Max",
"memo": "Memo (optional, verschlüsselt)",
"memo_label": "Memo:",
"memo_optional": "MEMO (OPTIONAL)",
"memo_upper": "MEMO",
"memo_z_only": "Hinweis: Memos sind nur beim Senden an abgeschirmte (z) Adressen verfügbar",
"merge_description": "Mehrere UTXOs zu einer einzelnen abgeschirmten Adresse zusammenführen. Dies kann die Wallet-Größe reduzieren und die Privatsphäre verbessern.",
"merge_funds": "Gelder zusammenführen",
"merge_started": "Zusammenführung gestartet",
"merge_title": "An Adresse zusammenführen",
"mine_when_idle": "Im Leerlauf minen",
"mined": "gemined",
"mined_filter": "Gemined",
"mined_type": "Gemined",
"mined_upper": "GEMINED",
"miner_fee": "Miner-Gebühr",
"mining": "Mining",
"mining_active": "Aktiv",
"mining_address_copied": "Mining-Adresse kopiert",
"mining_all_time": "Gesamt",
"mining_already_saved": "Pool-URL bereits gespeichert",
"mining_block_copied": "Block-Hash kopiert",
"mining_chart_1m_ago": "vor 1m",
"mining_chart_5m_ago": "vor 5m",
"mining_chart_now": "Jetzt",
"mining_click": "Klicken",
"mining_click_copy_address": "Klicken zum Kopieren der Adresse",
"mining_click_copy_block": "Klicken zum Kopieren des Block-Hash",
"mining_click_copy_difficulty": "Klicken zum Kopieren der Schwierigkeit",
"mining_connected": "Verbunden",
"mining_connecting": "Verbinde...",
"mining_control": "Mining-Steuerung",
"mining_difficulty_copied": "Schwierigkeit kopiert",
"mining_est_block": "Gesch. Block",
"mining_est_daily": "Gesch. täglich",
"mining_filter_all": "Alle",
"mining_filter_tip_all": "Alle Einnahmen anzeigen",
"mining_filter_tip_pool": "Nur Pool-Einnahmen anzeigen",
"mining_filter_tip_solo": "Nur Solo-Einnahmen anzeigen",
"mining_idle_off_tooltip": "Leerlauf-Mining aktivieren",
"mining_idle_on_tooltip": "Leerlauf-Mining deaktivieren",
"mining_local_hashrate": "Lokale Hashrate",
"mining_mine": "Minen",
"mining_mining_addr": "Mining-Adr.",
"mining_network": "Netzwerk",
"mining_no_blocks_yet": "Noch keine Blöcke gefunden",
"mining_no_payouts_yet": "Noch keine Pool-Auszahlungen",
"mining_no_saved_addresses": "Keine gespeicherten Adressen",
"mining_no_saved_pools": "Keine gespeicherten Pools",
"mining_off": "Mining ist AUS",
"mining_on": "Mining ist AN",
"mining_open_in_explorer": "Im Explorer öffnen",
"mining_payout_address": "Auszahlungsadresse",
"mining_payout_tooltip": "Adresse für Mining-Belohnungen",
"mining_pool": "Pool",
"mining_pool_hashrate": "Pool-Hashrate",
"mining_pool_url": "Pool-URL",
"mining_recent_blocks": "LETZTE BLÖCKE",
"mining_recent_payouts": "LETZTE POOL-AUSZAHLUNGEN",
"mining_remove": "Entfernen",
"mining_reset_defaults": "Standardwerte zurücksetzen",
"mining_save_payout_address": "Auszahlungsadresse speichern",
"mining_save_pool_url": "Pool-URL speichern",
"mining_saved_addresses": "Gespeicherte Adressen:",
"mining_saved_pools": "Gespeicherte Pools:",
"mining_shares": "Shares",
"mining_show_chart": "Diagramm",
"mining_show_log": "Protokoll",
"mining_solo": "Solo",
"mining_starting": "Startet...",
"mining_starting_tooltip": "Miner startet...",
"mining_statistics": "Mining-Statistiken",
"mining_stop": "Stopp",
"mining_stop_solo_for_pool": "Solo-Mining stoppen bevor Pool-Mining gestartet wird",
"mining_stop_solo_for_pool_settings": "Solo-Mining stoppen um Pool-Einstellungen zu ändern",
"mining_stopping": "Stoppt...",
"mining_stopping_tooltip": "Miner stoppt...",
"mining_syncing_tooltip": "Blockchain synchronisiert...",
"mining_threads": "Mining-Threads",
"mining_to_save": "zum Speichern",
"mining_today": "Heute",
"mining_uptime": "Laufzeit",
"mining_yesterday": "Gestern",
"network": "Netzwerk",
"network_fee": "NETZWERKGEBÜHR",
"network_hashrate": "Netzwerk-Hashrate",
"new": "+ Neu",
"new_shielded_created": "Neue abgeschirmte Adresse erstellt",
"new_t_address": "Neue T-Adresse",
"new_t_transparent": "Neue t-Adresse (Transparent)",
"new_transparent_created": "Neue transparente Adresse erstellt",
"new_z_address": "Neue Z-Adresse",
"new_z_shielded": "Neue z-Adresse (Abgeschirmt)",
"no_addresses": "Keine Adressen gefunden. Erstellen Sie eine mit den Schaltflächen oben.",
"no_addresses_available": "Keine Adressen verfügbar",
"no_addresses_match": "Keine Adressen passen zum Filter",
"no_addresses_with_balance": "Keine Adressen mit Guthaben",
"no_matching": "Keine passenden Transaktionen",
"no_recent_receives": "Keine kürzlichen Empfänge",
"no_recent_sends": "Keine kürzlichen Sendungen",
"no_transactions": "Keine Transaktionen gefunden",
"node": "KNOTEN",
"node_security": "KNOTEN & SICHERHEIT",
"noise": "Rauschen",
"not_connected": "Nicht mit Daemon verbunden...",
"not_connected_to_daemon": "Nicht mit Daemon verbunden",
"notes": "Notizen",
"notes_optional": "Notizen (optional):",
"output_filename": "Ausgabedateiname:",
"overview": "Übersicht",
"paste": "Einfügen",
"paste_from_clipboard": "Aus Zwischenablage einfügen",
"pay_from": "Zahlen von",
"payment_request": "ZAHLUNGSANFRAGE",
"payment_request_copied": "Zahlungsanfrage kopiert",
"payment_uri_copied": "Zahlungs-URI kopiert",
"peers": "Peers",
"peers_avg_ping": "Durchschn. Ping",
"peers_ban_24h": "Peer 24h sperren",
"peers_ban_score": "Sperr-Score: %d",
"peers_banned": "Gesperrt",
"peers_banned_count": "Gesperrt: %d",
"peers_best_block": "Bester Block",
"peers_blockchain": "BLOCKCHAIN",
"peers_blocks": "Blöcke",
"peers_blocks_left": "%d Blöcke übrig",
"peers_clear_all_bans": "Alle Sperren aufheben",
"peers_click_copy": "Klicken zum Kopieren",
"peers_connected": "Verbunden",
"peers_connected_count": "Verbunden: %d",
"peers_copy_ip": "IP kopieren",
"peers_dir_in": "Ein",
"peers_dir_out": "Aus",
"peers_hash_copied": "Hash kopiert",
"peers_hashrate": "Hashrate",
"peers_in_out": "Ein/Aus",
"peers_longest": "Längste",
"peers_longest_chain": "Längste Chain",
"peers_memory": "Speicher",
"peers_no_banned": "Keine gesperrten Peers",
"peers_no_connected": "Keine verbundenen Peers",
"peers_no_tls": "Kein TLS",
"peers_notarized": "Notarisiert",
"peers_p2p_port": "P2P-Port",
"peers_protocol": "Protokoll",
"peers_received": "Empfangen",
"peers_refresh": "Aktualisieren",
"peers_refresh_tooltip": "Peer-Liste aktualisieren",
"peers_refreshing": "Aktualisiere...",
"peers_sent": "Gesendet",
"peers_tt_id": "ID: %d",
"peers_tt_received": "Empfangen: %s",
"peers_tt_sent": "Gesendet: %s",
"peers_tt_services": "Dienste: %s",
"peers_tt_start_height": "Starthöhe: %d",
"peers_tt_synced": "Synchronisiert H/B: %d/%d",
"peers_tt_tls_cipher": "TLS: %s",
"peers_unban": "Entsperren",
"peers_upper": "PEERS",
"peers_version": "Version",
"pending": "Ausstehend",
"ping": "Ping",
"price_chart": "Preisdiagramm",
"qr_code": "QR-Code",
"qr_failed": "QR-Code konnte nicht generiert werden",
"qr_title": "QR-Code",
"qr_unavailable": "QR nicht verfügbar",
"receive": "Empfangen",
"received": "empfangen",
"received_filter": "Empfangen",
"received_label": "Empfangen",
"received_upper": "EMPFANGEN",
"receiving_addresses": "Ihre Empfangsadressen",
"recent_received": "KÜRZLICH EMPFANGEN",
"recent_sends": "KÜRZLICH GESENDET",
"recipient": "EMPFÄNGER",
"recv_type": "Empf.",
"refresh": "Aktualisieren",
"refresh_now": "Jetzt aktualisieren",
"report_bug": "Fehler melden",
"request_amount": "Betrag (optional):",
"request_copy_uri": "URI kopieren",
"request_description": "Erstellen Sie eine Zahlungsanfrage, die andere scannen oder kopieren können. Der QR-Code enthält Ihre Adresse und optionalen Betrag/Memo.",
"request_label": "Bezeichnung (optional):",
"request_memo": "Memo (optional):",
"request_payment": "Zahlung anfordern",
"request_payment_uri": "Zahlungs-URI:",
"request_receive_address": "Empfangsadresse:",
"request_select_address": "Adresse auswählen...",
"request_shielded_addrs": "-- Abgeschirmte Adressen --",
"request_title": "Zahlung anfordern",
"request_transparent_addrs": "-- Transparente Adressen --",
"request_uri_copied": "Zahlungs-URI in Zwischenablage kopiert",
"rescan": "Neu scannen",
"reset_to_defaults": "Standardwerte zurücksetzen",
"review_send": "Senden prüfen",
"rpc_host": "RPC-Host",
"rpc_pass": "Passwort",
"rpc_port": "Port",
"rpc_user": "Benutzername",
"save": "Speichern",
"save_settings": "Einstellungen speichern",
"save_z_transactions": "Z-Tx in Tx-Liste speichern",
"search_placeholder": "Suchen...",
"security": "SICHERHEIT",
"select_address": "Adresse auswählen...",
"select_receiving_address": "Empfangsadresse auswählen...",
"select_source_address": "Quelladresse auswählen...",
"send": "Senden",
"send_amount": "Betrag",
"send_amount_details": "BETRAGSDETAILS",
"send_amount_upper": "BETRAG",
"send_clear_fields": "Alle Formularfelder leeren?",
"send_copy_error": "Fehler kopieren",
"send_dismiss": "Verwerfen",
"send_error_copied": "Fehler in Zwischenablage kopiert",
"send_error_prefix": "Fehler: %s",
"send_exceeds_available": "Übersteigt verfügbar (%.8f)",
"send_fee": "Gebühr",
"send_fee_high": "Hoch",
"send_fee_low": "Niedrig",
"send_fee_normal": "Normal",
"send_form_restored": "Formular wiederhergestellt",
"send_from_this_address": "Von dieser Adresse senden",
"send_go_to_receive": "Zum Empfangen",
"send_keep": "Behalten",
"send_network_fee": "NETZWERKGEBÜHR",
"send_no_balance": "Kein Guthaben",
"send_no_recent": "Keine kürzlichen Sendungen",
"send_recent_sends": "KÜRZLICH GESENDET",
"send_recipient": "EMPFÄNGER",
"send_select_source": "Quelladresse auswählen...",
"send_sending_from": "SENDEN VON",
"send_submitting": "Transaktion wird übermittelt...",
"send_switch_to_receive": "Wechseln Sie zu Empfangen, um Ihre Adresse zu erhalten und Gelder zu empfangen.",
"send_to": "Senden an",
"send_tooltip_enter_amount": "Geben Sie einen Betrag zum Senden ein",
"send_tooltip_exceeds_balance": "Betrag übersteigt verfügbares Guthaben",
"send_tooltip_in_progress": "Transaktion bereits in Bearbeitung",
"send_tooltip_invalid_address": "Geben Sie eine gültige Empfängeradresse ein",
"send_tooltip_not_connected": "Nicht mit Daemon verbunden",
"send_tooltip_select_source": "Wählen Sie zuerst eine Quelladresse",
"send_tooltip_syncing": "Warten Sie auf die Blockchain-Synchronisierung",
"send_total": "Gesamt",
"send_transaction": "Transaktion senden",
"send_tx_failed": "Transaktion fehlgeschlagen",
"send_tx_sent": "Transaktion gesendet!",
"send_tx_success": "Transaktion erfolgreich gesendet!",
"send_txid_copied": "TxID in Zwischenablage kopiert",
"send_txid_label": "TxID: %s",
"send_valid_shielded": "Gültige abgeschirmte Adresse",
"send_valid_transparent": "Gültige transparente Adresse",
"send_wallet_empty": "Ihre Wallet ist leer",
"send_yes_clear": "Ja, leeren",
"sending": "Transaktion wird gesendet",
"sending_from": "SENDEN VON",
"sent": "gesendet",
"sent_filter": "Gesendet",
"sent_type": "Gesendet",
"sent_upper": "GESENDET",
"settings": "Einstellungen",
"setup_wizard": "Einrichtungsassistent",
"share": "Teilen",
"shield_check_status": "Status prüfen",
"shield_completed": "Vorgang erfolgreich abgeschlossen!",
"shield_description": "Schirmen Sie Ihre Mining-Belohnungen ab, indem Sie Coinbase-Ausgaben von transparenten Adressen an eine abgeschirmte Adresse senden. Dies verbessert die Privatsphäre, indem Ihre Mining-Einkünfte verborgen werden.",
"shield_from_address": "Von Adresse:",
"shield_funds": "Gelder abschirmen",
"shield_in_progress": "Vorgang läuft...",
"shield_max_utxos": "Max. UTXOs pro Vorgang",
"shield_merge_done": "Abschirmung/Zusammenführung abgeschlossen!",
"shield_select_z": "z-Adresse auswählen...",
"shield_started": "Abschirmvorgang gestartet",
"shield_title": "Coinbase-Belohnungen abschirmen",
"shield_to_address": "An Adresse (Abgeschirmt):",
"shield_utxo_limit": "UTXO-Limit:",
"shield_wildcard_hint": "Verwenden Sie '*' um von allen transparenten Adressen abzuschirmen",
"shielded": "Abgeschirmt",
"shielded_to": "ABGESCHIRMT AN",
"shielded_type": "Abgeschirmt",
"show": "Anzeigen",
"show_qr_code": "QR-Code anzeigen",
"showing_transactions": "Zeige %d\xe2\x80\x93%d von %d Transaktionen (gesamt: %zu)",
"simple_background": "Einfacher Hintergrund",
"start_mining": "Mining starten",
"status": "Status",
"stop_external": "Externen Daemon stoppen",
"stop_mining": "Mining stoppen",
"submitting_transaction": "Transaktion wird übermittelt...",
"success": "Erfolg",
"summary": "Zusammenfassung",
"syncing": "Synchronisiere...",
"t_addresses": "T-Adressen",
"test_connection": "Testen",
"theme": "Design",
"theme_effects": "Design-Effekte",
"time_days_ago": "vor %d Tagen",
"time_hours_ago": "vor %d Stunden",
"time_minutes_ago": "vor %d Minuten",
"time_seconds_ago": "vor %d Sekunden",
"to": "An",
"to_upper": "AN",
"tools": "WERKZEUGE",
"total": "Gesamt",
"transaction_id": "TRANSAKTIONS-ID",
"transaction_sent": "Transaktion erfolgreich gesendet",
"transaction_sent_msg": "Transaktion gesendet!",
"transaction_url": "Transaktions-URL",
"transactions": "Transaktionen",
"transactions_upper": "TRANSAKTIONEN",
"transparent": "Transparent",
"tx_confirmations": "%d Bestätigungen",
"tx_details_title": "Transaktionsdetails",
"tx_from_address": "Von Adresse:",
"tx_id_label": "Transaktions-ID:",
"tx_immature": "UNREIF",
"tx_mined": "GEMINED",
"tx_received": "EMPFANGEN",
"tx_sent": "GESENDET",
"tx_to_address": "An Adresse:",
"tx_view_explorer": "Im Explorer anzeigen",
"txs_count": "%d Txs",
"type": "Typ",
"ui_opacity": "UI-Transparenz",
"unban": "Entsperren",
"unconfirmed": "Unbestätigt",
"undo_clear": "Leeren rückgängig",
"unknown": "Unbekannt",
"use_embedded_daemon": "Eingebetteten dragonxd verwenden",
"use_tor": "Tor verwenden",
"validate_btn": "Validieren",
"validate_description": "Geben Sie eine DragonX-Adresse ein, um zu prüfen, ob sie gültig ist und ob sie zu dieser Wallet gehört.",
"validate_invalid": "UNGÜLTIG",
"validate_is_mine": "Diese Wallet besitzt diese Adresse",
"validate_not_mine": "Nicht im Besitz dieser Wallet",
"validate_ownership": "Eigentum:",
"validate_results": "Ergebnisse:",
"validate_shielded_type": "Abgeschirmt (z-Adresse)",
"validate_status": "Status:",
"validate_title": "Adresse validieren",
"validate_transparent_type": "Transparent (t-Adresse)",
"validate_type": "Typ:",
"validate_valid": "GÜLTIG",
"validating": "Validiere...",
"verbose_logging": "Ausführliches Logging",
"version": "Version",
"view": "Ansicht",
"view_details": "Details anzeigen",
"view_on_explorer": "Im Explorer anzeigen",
"waiting_for_daemon": "Warte auf Daemon-Verbindung...",
"wallet": "WALLET",
"wallet_empty": "Ihre Wallet ist leer",
"wallet_empty_hint": "Wechseln Sie zu Empfangen, um Ihre Adresse zu erhalten und Gelder zu empfangen.",
"warning": "Warnung",
"warning_upper": "WARNUNG!",
"website": "Webseite",
"window_opacity": "Fenster-Transparenz",
"yes_clear": "Ja, leeren",
"your_addresses": "Ihre Adressen",
"z_addresses": "Z-Adressen",
}
out = os.path.join(os.path.dirname(__file__), "..", "res", "lang", "de.json")
with open(out, "w", encoding="utf-8") as f:
json.dump(translations, f, indent=4, ensure_ascii=False, sort_keys=True)
print(f"Wrote {len(translations)} German translations to {os.path.abspath(out)}")
+665
View File
@@ -0,0 +1,665 @@
#!/usr/bin/env python3
"""Generate complete Spanish (es.json) translations for ObsidianDragon wallet."""
import json
es = {
# ---- Navigation & Tabs ----
"overview": "Resumen",
"balance": "Saldo",
"send": "Enviar",
"receive": "Recibir",
"transactions": "Transacciones",
"history": "Historial",
"mining": "Minería",
"peers": "Nodos",
"market": "Mercado",
"settings": "Configuración",
"console": "Consola",
"tools": "HERRAMIENTAS",
"advanced": "AVANZADO",
"network": "Red",
# ---- Settings sections ----
"appearance": "APARIENCIA",
"wallet": "CARTERA",
"node_security": "NODO Y SEGURIDAD",
"node": "NODO",
"security": "SEGURIDAD",
"explorer": "EXPLORADOR",
"about": "Acerca de",
"backup_data": "RESPALDO Y DATOS",
"general": "General",
# ---- Settings options ----
"balance_layout": "Diseño de Saldo",
"low_spec_mode": "Modo bajo rendimiento",
"simple_background": "Fondo simple",
"console_scanline": "Líneas de consola",
"theme_effects": "Efectos de tema",
"language": "Idioma",
"save_z_transactions": "Guardar Z-tx en lista",
"allow_custom_fees": "Permitir comisiones personalizadas",
"custom_fees": "Comisiones personalizadas",
"auto_shield": "Auto-proteger minería",
"fetch_prices": "Obtener precios",
"use_tor": "Usar Tor",
"font_scale": "Escala de fuente",
"keep_daemon": "Mantener daemon activo",
"stop_external": "Detener daemon externo",
"mine_when_idle": "Minar en reposo",
"verbose_logging": "Registro detallado",
"acrylic": "Acrílico",
"noise": "Ruido",
"ui_opacity": "Opacidad de UI",
"window_opacity": "Opacidad de ventana",
# ---- Settings buttons ----
"save_settings": "Guardar Configuración",
"reset_to_defaults": "Restablecer Valores",
"report_bug": "Reportar Error",
"website": "Sitio Web",
"setup_wizard": "Asistente de Configuración",
"rescan": "Re-escanear",
"test_connection": "Probar",
# ---- Settings fields ----
"rpc_host": "Host RPC",
"rpc_port": "Puerto",
"rpc_user": "Usuario",
"rpc_pass": "Contraseña",
"transaction_url": "URL de Transacción",
"address_url": "URL de Dirección",
"block_explorer": "Explorador de Bloques",
# ---- Common actions ----
"add": "Agregar",
"edit": "Editar",
"delete": "Eliminar",
"cancel": "Cancelar",
"close": "Cerrar",
"clear": "Limpiar",
"copy": "Copiar",
"paste": "Pegar",
"save": "Guardar",
"refresh": "Actualizar",
"export": "Exportar",
"import": "Importar",
"show": "Mostrar",
"hide": "Ocultar",
"share": "Compartir",
"confirm_and_send": "Confirmar y Enviar",
"confirm_send": "Confirmar Envío",
"confirm_transaction": "Confirmar Transacción",
"review_send": "Revisar Envío",
"copy_address": "Copiar Dirección Completa",
"copy_to_clipboard": "Copiar al Portapapeles",
"paste_from_clipboard": "Pegar del Portapapeles",
"copy_txid": "Copiar TxID",
"copy_uri": "Copiar URI",
"copy_error": "Copiar Error",
"search_placeholder": "Buscar...",
"exit": "Salir",
"help": "Ayuda",
"file": "Archivo",
"display": "Pantalla",
"new": "+ Nuevo",
"dismiss": "Descartar",
"keep": "Mantener",
"yes_clear": "Sí, Limpiar",
"undo_clear": "Deshacer Limpieza",
# ---- Common labels ----
"address": "Dirección",
"address_label": "Dirección:",
"amount": "Cantidad",
"amount_label": "Cantidad:",
"date": "Fecha",
"date_label": "Fecha:",
"fee": "Comisión",
"fee_label": "Comisión:",
"label": "Etiqueta:",
"memo": "Memo (opcional, encriptado)",
"memo_label": "Memo:",
"notes": "Notas",
"notes_optional": "Notas (opcional):",
"total": "Total",
"from": "Desde",
"to_upper": "PARA",
"from_upper": "DESDE",
"max": "Máximo",
"characters": "caracteres",
"ping": "Ping",
"height": "Altura",
"block": "Bloque",
"available": "Disponible",
"unknown": "Desconocido",
"loading": "Cargando...",
"validating": "Validando...",
"warning_upper": "¡ADVERTENCIA!",
"output_filename": "Nombre del archivo:",
"file_save_location": "El archivo se guardará en: ~/.config/ObsidianDragon/",
"light": "Claro",
"dark": "Oscuro",
# ---- Status ----
"connected": "Conectado",
"disconnected": "Desconectado",
"connecting": "Conectando...",
"confirmed": "Confirmada",
"confirmations": "Confirmaciones",
"not_connected_to_daemon": "No conectado al daemon",
"waiting_for_daemon": "Esperando conexión al daemon...",
"blockchain_syncing": "Sincronizando blockchain (%.1f%%)... Los saldos pueden ser inexactos.",
"error": "Error",
"success": "Éxito",
"warning": "Advertencia",
# ---- Time ----
"time_days_ago": "hace %d días",
"time_hours_ago": "hace %d horas",
"time_minutes_ago": "hace %d minutos",
"time_seconds_ago": "hace %d segundos",
# ---- Transaction types/filters ----
"sent_type": "Enviado",
"sent_filter": "Enviado",
"sent_upper": "ENVIADO",
"received_label": "Recibido",
"received_filter": "Recibido",
"received_upper": "RECIBIDO",
"mined_type": "Minado",
"mined_filter": "Minado",
"mined_upper": "MINADO",
"immature_type": "Inmaduro",
"mature": "Maduro",
"recv_type": "Recibido",
"all_filter": "Todos",
"shielded_type": "Protegido",
# ---- Balance / Overview ----
"address_upper": "DIRECCIÓN",
"address_details": "Detalles de Dirección",
"amount_details": "DETALLES DE CANTIDAD",
"transactions_upper": "TRANSACCIONES",
"addresses_appear_here": "Tus direcciones de recepción aparecerán aquí una vez conectado.",
"wallet_empty": "Tu cartera está vacía",
"wallet_empty_hint": "Cambia a Recibir para obtener tu dirección y empezar a recibir fondos.",
"loading_addresses": "Cargando direcciones...",
"no_addresses_match": "No hay direcciones que coincidan con el filtro",
"no_addresses_with_balance": "No hay direcciones con saldo",
"click_copy_address": "Clic para copiar dirección",
"click_copy_uri": "Clic para copiar URI",
"address_copied": "Dirección copiada al portapapeles",
"about_dragonx": "Acerca de DragonX",
"dragonx_green": "DragonX (Verde)",
# ---- Transactions tab ----
"no_transactions": "No se encontraron transacciones",
"no_matching": "No hay transacciones coincidentes",
"showing_transactions": "Mostrando %d\u2013%d de %d transacciones (total: %zu)",
"conf_count": "%d conf",
"confirmations_display": "%d confirmaciones | %s",
"txs_count": "%d txs",
"view_details": "Ver Detalles",
"full_details": "Detalles Completos",
"export_csv": "Exportar CSV",
"transaction_id": "ID DE TRANSACCIÓN",
# ---- Receive tab ----
"select_receiving_address": "Seleccionar dirección de recepción...",
"payment_request": "SOLICITUD DE PAGO",
"recent_received": "RECIBIDOS RECIENTES",
"no_recent_receives": "No hay recepciones recientes",
"qr_unavailable": "QR no disponible",
"clear_request": "Limpiar Solicitud",
"clear_form_confirm": "¿Limpiar todos los campos del formulario?",
"payment_request_copied": "Solicitud de pago copiada",
"payment_uri_copied": "URI de pago copiada",
"failed_create_shielded": "Error al crear dirección protegida",
"failed_create_transparent": "Error al crear dirección transparente",
"new_shielded_created": "Nueva dirección protegida creada",
"new_transparent_created": "Nueva dirección transparente creada",
# ---- Send tab ----
"send_sending_from": "ENVIANDO DESDE",
"send_select_source": "Seleccionar dirección de origen...",
"send_no_balance": "Sin saldo",
"send_recipient": "DESTINATARIO",
"send_amount_upper": "CANTIDAD",
"send_amount": "Cantidad",
"send_amount_details": "DETALLES DE CANTIDAD",
"send_fee": "Comisión",
"send_fee_low": "Baja",
"send_fee_normal": "Normal",
"send_fee_high": "Alta",
"send_network_fee": "COMISIÓN DE RED",
"send_total": "Total",
"send_recent_sends": "ENVÍOS RECIENTES",
"send_no_recent": "No hay envíos recientes",
"send_clear_fields": "¿Limpiar todos los campos del formulario?",
"send_yes_clear": "Sí, Limpiar",
"send_keep": "Mantener",
"send_form_restored": "Formulario restaurado",
"send_valid_shielded": "Dirección protegida válida",
"send_valid_transparent": "Dirección transparente válida",
"send_exceeds_available": "Excede disponible (%.8f)",
"send_submitting": "Enviando transacción...",
"send_tx_sent": "¡Transacción enviada!",
"send_tx_success": "¡Transacción enviada exitosamente!",
"send_tx_failed": "Error en la transacción",
"send_error_prefix": "Error: %s",
"send_error_copied": "Error copiado al portapapeles",
"send_copy_error": "Copiar Error",
"send_dismiss": "Descartar",
"send_txid_copied": "TxID copiado al portapapeles",
"send_txid_label": "TxID: %s",
"send_go_to_receive": "Ir a Recibir",
"send_wallet_empty": "Tu cartera está vacía",
"send_switch_to_receive": "Cambia a Recibir para obtener tu dirección y empezar a recibir fondos.",
"send_tooltip_select_source": "Selecciona una dirección de origen primero",
"send_tooltip_invalid_address": "Ingresa una dirección de destinatario válida",
"send_tooltip_enter_amount": "Ingresa una cantidad a enviar",
"send_tooltip_exceeds_balance": "La cantidad excede el saldo disponible",
"send_tooltip_not_connected": "No conectado al daemon",
"send_tooltip_syncing": "Espera a que se sincronice el blockchain",
"send_tooltip_in_progress": "Transacción ya en progreso",
"sending_from": "ENVIANDO DESDE",
"select_source_address": "Seleccionar dirección de origen...",
"recipient": "DESTINATARIO",
"memo_optional": "MEMO (OPCIONAL)",
"memo_upper": "MEMO",
"network_fee": "COMISIÓN DE RED",
"fee_low": "Baja",
"fee_normal": "Normal",
"fee_high": "Alta",
"recent_sends": "ENVÍOS RECIENTES",
"no_recent_sends": "No hay envíos recientes",
"shielded_to": "PROTEGIDA PARA",
"submitting_transaction": "Enviando transacción...",
"transaction_sent_msg": "¡Transacción enviada!",
"amount_exceeds_balance": "La cantidad excede el saldo",
# ---- Mining tab ----
"mining_solo": "Solo",
"mining_pool": "Pool",
"mining_pool_url": "URL del Pool",
"mining_pool_hashrate": "Hashrate del Pool",
"mining_local_hashrate": "Hashrate Local",
"mining_payout_address": "Dirección de Pago",
"mining_payout_tooltip": "Dirección para recibir recompensas de minería",
"mining_mine": "Minar",
"mining_stop": "Detener",
"mining_starting": "Iniciando...",
"mining_stopping": "Deteniendo...",
"mining_active": "Activo",
"mining_connected": "Conectado",
"mining_connecting": "Conectando...",
"mining_network": "Red",
"mining_shares": "Shares",
"mining_uptime": "Tiempo activo",
"mining_mining_addr": "Dir. Minería",
"mining_est_block": "Bloque Est.",
"mining_est_daily": "Diario Est.",
"mining_today": "Hoy",
"mining_yesterday": "Ayer",
"mining_all_time": "Todo el Tiempo",
"mining_recent_blocks": "BLOQUES RECIENTES",
"mining_recent_payouts": "PAGOS DE POOL RECIENTES",
"mining_no_blocks_yet": "Aún no se han encontrado bloques",
"mining_no_payouts_yet": "Aún no hay pagos del pool",
"mining_show_chart": "Gráfico",
"mining_show_log": "Registro",
"mining_chart_now": "Ahora",
"mining_chart_start": "Inicio",
"mining_chart_1m_ago": "hace 1m",
"mining_chart_5m_ago": "hace 5m",
"mining_save_pool_url": "Guardar URL del pool",
"mining_save_payout_address": "Guardar dirección de pago",
"mining_saved_pools": "Pools Guardados:",
"mining_saved_addresses": "Direcciones Guardadas:",
"mining_no_saved_pools": "No hay pools guardados",
"mining_no_saved_addresses": "No hay direcciones guardadas",
"mining_already_saved": "URL del pool ya guardada",
"mining_remove": "Eliminar",
"mining_reset_defaults": "Restablecer Valores",
"mining_click": "Clic",
"mining_to_save": "para guardar",
"mining_click_copy_address": "Clic para copiar dirección",
"mining_click_copy_block": "Clic para copiar hash de bloque",
"mining_click_copy_difficulty": "Clic para copiar dificultad",
"mining_address_copied": "Dirección de minería copiada",
"mining_block_copied": "Hash de bloque copiado",
"mining_difficulty_copied": "Dificultad copiada",
"mining_open_in_explorer": "Abrir en explorador",
"mining_starting_tooltip": "El minero está iniciando...",
"mining_stopping_tooltip": "El minero está deteniéndose...",
"mining_syncing_tooltip": "El blockchain está sincronizando...",
"mining_idle_on_tooltip": "Desactivar minería en reposo",
"mining_idle_off_tooltip": "Activar minería en reposo",
"mining_stop_solo_for_pool": "Detener minería solo antes de iniciar minería en pool",
"mining_stop_solo_for_pool_settings": "Detener minería solo para cambiar configuración del pool",
"mining_filter_all": "Todos",
"mining_filter_tip_all": "Mostrar todas las ganancias",
"mining_filter_tip_solo": "Mostrar solo ganancias solo",
"mining_filter_tip_pool": "Mostrar solo ganancias del pool",
"local_hashrate": "Tasa Hash Local",
"est_time_to_block": "Tiempo Est. al Bloque",
"difficulty": "Dificultad",
"current_price": "Precio Actual",
"market_cap": "Cap. de Mercado",
# ---- Peers tab ----
"peers_blockchain": "BLOCKCHAIN",
"peers_blocks": "Bloques",
"peers_connected": "Conectados",
"peers_connected_count": "Conectados: %d",
"peers_banned": "Bloqueados",
"peers_banned_count": "Bloqueados: %d",
"peers_upper": "NODOS",
"peers_avg_ping": "Ping Prom.",
"peers_best_block": "Mejor Bloque",
"peers_hashrate": "Hashrate",
"peers_longest": "Más Larga",
"peers_longest_chain": "Cadena Más Larga",
"peers_memory": "Memoria",
"peers_notarized": "Notarizado",
"peers_p2p_port": "Puerto P2P",
"peers_protocol": "Protocolo",
"peers_version": "Versión",
"peers_in_out": "Ent/Sal",
"peers_dir_in": "Ent",
"peers_dir_out": "Sal",
"peers_received": "Recibido",
"peers_sent": "Enviado",
"peers_refresh": "Actualizar",
"peers_refresh_tooltip": "Actualizar lista de nodos",
"peers_refreshing": "Actualizando...",
"peers_no_connected": "No hay nodos conectados",
"peers_no_banned": "No hay nodos bloqueados",
"peers_ban_24h": "Bloquear Nodo 24h",
"peers_unban": "Desbloquear",
"peers_clear_all_bans": "Limpiar Todos los Bloqueos",
"peers_copy_ip": "Copiar IP",
"peers_click_copy": "Clic para copiar",
"peers_hash_copied": "Hash copiado",
"peers_no_tls": "Sin TLS",
"peers_blocks_left": "%d bloques restantes",
"peers_ban_score": "Puntuación: %d",
"peers_tt_id": "ID: %d",
"peers_tt_sent": "Enviado: %s",
"peers_tt_received": "Recibido: %s",
"peers_tt_services": "Servicios: %s",
"peers_tt_start_height": "Altura Inicial: %d",
"peers_tt_synced": "Sinc H/B: %d/%d",
"peers_tt_tls_cipher": "TLS: %s",
"connected_peers": "Nodos Conectados",
"banned_peers": "Nodos Bloqueados",
"ban": "Bloquear",
"clear_all_bans": "Limpiar Todos los Bloqueos",
"ip_address": "Dirección IP",
# ---- Market tab ----
"market_btc_price": "PRECIO BTC",
"market_24h_volume": "VOLUMEN 24H",
"market_portfolio": "PORTAFOLIO",
"market_pct_shielded": "%.0f%% Protegido",
"market_attribution": "Datos de precios de NonKYC",
"market_no_price": "Sin datos de precio",
"market_no_history": "No hay historial de precios disponible",
"market_price_unavailable": "Datos de precio no disponibles",
"market_refresh_price": "Actualizar datos de precio",
"market_trade_on": "Operar en %s",
"market_now": "Ahora",
"market_6h": "6h",
"market_12h": "12h",
"market_18h": "18h",
"market_24h": "24h",
"24h_change": "Cambio 24h",
"24h_volume": "Volumen 24h",
# ---- Console tab ----
"console_welcome": "Bienvenido a la Consola de ObsidianDragon",
"console_type_help": "Escribe 'help' para ver los comandos disponibles",
"console_available_commands": "Comandos disponibles:",
"console_common_rpc": "Comandos RPC comunes:",
"console_rpc_reference": "Referencia de Comandos RPC",
"console_auto_scroll": "Auto-desplazamiento",
"console_clear": "Limpiar",
"console_clear_console": "Limpiar Consola",
"console_cleared": "Consola limpiada",
"console_commands": "Comandos",
"console_completions": "Completaciones:",
"console_tab_completion": "Tab para completar",
"console_connected": "Conectado al daemon",
"console_disconnected": "Desconectado del daemon",
"console_not_connected": "Error: No conectado al daemon",
"console_no_daemon": "Sin daemon",
"console_daemon": "Daemon",
"console_daemon_error": "¡Error del daemon!",
"console_daemon_started": "Daemon iniciado",
"console_daemon_stopped": "Daemon detenido",
"console_errors": "Errores",
"console_filter_hint": "Filtrar salida...",
"console_search_commands": "Buscar comandos...",
"console_copy_all": "Copiar Todo",
"console_copy_selected": "Copiar",
"console_select_all": "Seleccionar Todo",
"console_zoom_in": "Acercar",
"console_zoom_out": "Alejar",
"console_show_daemon_output": "Mostrar salida del daemon",
"console_show_errors_only": "Mostrar solo errores",
"console_show_rpc_ref": "Mostrar referencia de comandos RPC",
"console_capturing_output": "Capturando salida del daemon...",
"console_starting_node": "Iniciando nodo...",
"console_line_count": "%zu líneas",
"console_new_lines": "%d nuevas líneas",
"console_showing_lines": "Mostrando %zu de %zu líneas",
"console_click_commands": "Clic en los comandos de arriba para insertarlos",
"console_click_insert": "Clic para insertar",
"console_click_insert_params": "Clic para insertar con parámetros",
"console_close": "Cerrar",
"console_status_running": "Ejecutando",
"console_status_stopped": "Detenido",
"console_status_starting": "Iniciando",
"console_status_stopping": "Deteniendo",
"console_status_error": "Error",
"console_status_unknown": "Desconocido",
"console_help_help": " help - Mostrar este mensaje de ayuda",
"console_help_getinfo": " getinfo - Mostrar información del nodo",
"console_help_getblockcount": " getblockcount - Mostrar altura actual del bloque",
"console_help_getbalance": " getbalance - Mostrar saldo transparente",
"console_help_gettotalbalance": " gettotalbalance - Mostrar saldo total",
"console_help_getmininginfo": " getmininginfo - Mostrar estado de minería",
"console_help_getpeerinfo": " getpeerinfo - Mostrar nodos conectados",
"console_help_setgenerate": " setgenerate - Controlar minería",
"console_help_stop": " stop - Detener el daemon",
"console_help_clear": " clear - Limpiar la consola",
# ---- About dialog ----
"about_title": "Acerca de ObsidianDragon",
"about_edition": "Edición ImGui",
"about_version": "Versión:",
"about_imgui": "ImGui:",
"about_build_date": "Fecha de Compilación:",
"about_build_type": "Tipo de Compilación:",
"about_debug": "Depuración",
"about_release": "Producción",
"about_daemon": "Daemon:",
"about_chain": "Cadena:",
"about_block_height": "Altura de Bloque:",
"about_connections": "Conexiones:",
"about_peers_count": "%zu nodos",
"about_credits": "Créditos",
"about_license": "Licencia",
"about_license_text": "Este software se distribuye bajo la Licencia Pública General de GNU v3 (GPLv3). Usted es libre de usar, modificar y distribuir este software bajo los términos de la licencia.",
"about_website": "Sitio Web",
"about_github": "GitHub",
"about_block_explorer": "Explorador de Bloques",
# ---- Address Book dialog ----
"address_book_title": "Libreta de Direcciones",
"address_book_add_new": "Agregar Nueva",
"address_book_add": "Agregar Dirección",
"address_book_edit": "Editar Dirección",
"address_book_empty": "No hay direcciones guardadas. Haz clic en 'Agregar Nueva' para añadir una.",
"address_book_count": "%zu direcciones guardadas",
"address_book_deleted": "Entrada eliminada",
"address_book_added": "Dirección agregada a la libreta",
"address_book_exists": "La dirección ya existe en la libreta",
"address_book_updated": "Dirección actualizada",
"address_book_update_failed": "Error al actualizar - la dirección puede estar duplicada",
# ---- Backup dialog ----
"backup_title": "Respaldar Cartera",
"backup_description": "Crea un respaldo de tu archivo wallet.dat. Este archivo contiene todas tus claves privadas e historial de transacciones. Guarda el respaldo en un lugar seguro.",
"backup_destination": "Destino del respaldo:",
"backup_wallet_not_found": "Advertencia: wallet.dat no encontrado en la ubicación esperada",
"backup_create": "Crear Respaldo",
"backup_created": "Respaldo de cartera creado",
"backup_backing_up": "Respaldando...",
"backup_tips": "Consejos:",
"backup_tip_external": "Guarda respaldos en unidades externas o almacenamiento en la nube",
"backup_tip_multiple": "Crea múltiples respaldos en diferentes ubicaciones",
"backup_tip_test": "Prueba restaurar desde el respaldo periódicamente",
"backup_wallet": "Respaldar Cartera...",
# ---- Block Info dialog ----
"block_info_title": "Información del Bloque",
"block_height": "Altura del Bloque:",
"block_get_info": "Obtener Info del Bloque",
"block_hash": "Hash del Bloque:",
"block_timestamp": "Fecha y Hora:",
"block_transactions": "Transacciones:",
"block_size": "Tamaño:",
"block_bits": "Bits:",
"block_merkle_root": "Raíz Merkle:",
"block_previous": "Bloque Anterior:",
"block_next": "Bloque Siguiente:",
"block_click_prev": "Clic para ver bloque anterior",
"block_click_next": "Clic para ver bloque siguiente",
"block_nav_prev": "<< Anterior",
"block_nav_next": "Siguiente >>",
# ---- Export Keys dialog ----
"export_keys_title": "Exportar Todas las Claves Privadas",
"export_keys_danger": "PELIGRO: ¡Esto exportará TODAS las claves privadas de tu cartera! Cualquiera con acceso a este archivo puede robar tus fondos. Guárdalo de forma segura y elimínalo después de usar.",
"export_keys_options": "Opciones de exportación:",
"export_keys_include_z": "Incluir direcciones Z (protegidas)",
"export_keys_include_t": "Incluir direcciones T (transparentes)",
"export_keys_btn": "Exportar Claves",
"export_keys_success": "Claves exportadas exitosamente",
"export_private_key": "Exportar Clave Privada",
"export_viewing_key": "Exportar Clave de Vista",
# ---- Export Transactions dialog ----
"export_tx_title": "Exportar Transacciones a CSV",
"export_tx_count": "Exportar %zu transacciones a archivo CSV.",
"export_tx_none": "No hay transacciones para exportar",
"export_tx_file_fail": "Error al crear archivo CSV",
"export_tx_success": "Transacciones exportadas exitosamente",
# ---- Import Key dialog ----
"import_key_title": "Importar Clave Privada",
"import_key_warning": "Advertencia: ¡Nunca compartas tus claves privadas! Importar claves de fuentes no confiables puede comprometer tu cartera.",
"import_key_label": "Clave(s) Privada(s):",
"import_key_tooltip": "Ingresa una o más claves privadas, una por línea.\nSoporta claves de direcciones z y t.\nLas líneas que empiezan con # se tratan como comentarios.",
"import_key_btn": "Importar Clave(s)",
"import_key_no_valid": "No se encontraron claves válidas en la entrada",
"import_key_success": "Claves importadas exitosamente",
"import_key_rescan": "Re-escanear blockchain después de importar",
"import_key_start_height": "Altura inicial:",
"import_key_full_rescan": "(0 = re-escaneo completo)",
"import_key_formats": "Formatos de clave soportados:",
"import_key_z_format": "Claves de gasto de direcciones Z (secret-extended-key-...)",
"import_key_t_format": "Claves privadas WIF de direcciones T",
"import_private_key": "Importar Clave Privada...",
"invalid_address": "Formato de dirección inválido",
# ---- Key Export dialog ----
"key_export_private_key": "Clave Privada:",
"key_export_viewing_key": "Clave de Vista:",
"key_export_private_warning": "¡Mantén esta clave en SECRETO! Cualquiera con esta clave puede gastar tus fondos. Nunca la compartas en línea ni con personas no confiables.",
"key_export_viewing_warning": "Esta clave de vista permite a otros ver tus transacciones entrantes y saldo, pero NO gastar tus fondos. Comparte solo con personas de confianza.",
"key_export_fetching": "Obteniendo clave de la cartera...",
"key_export_reveal": "Revelar Clave",
# ---- QR dialog ----
"qr_title": "Código QR",
"qr_failed": "Error al generar código QR",
# ---- Request Payment dialog ----
"request_title": "Solicitar Pago",
"request_description": "Genera una solicitud de pago que otros pueden escanear o copiar. El código QR contiene tu dirección y cantidad/memo opcionales.",
"request_receive_address": "Dirección de Recepción:",
"request_select_address": "Seleccionar dirección...",
"request_shielded_addrs": "-- Direcciones Protegidas --",
"request_transparent_addrs": "-- Direcciones Transparentes --",
"request_amount": "Cantidad (opcional):",
"request_label": "Etiqueta (opcional):",
"request_memo": "Memo (opcional):",
"request_payment_uri": "URI de Pago:",
"request_copy_uri": "Copiar URI",
"request_uri_copied": "URI de pago copiada al portapapeles",
# ---- Shield dialog ----
"shield_title": "Proteger Recompensas de Coinbase",
"shield_description": "Protege tus recompensas de minería enviando salidas coinbase de direcciones transparentes a una dirección protegida. Esto mejora la privacidad ocultando tus ingresos de minería.",
"shield_from_address": "Dirección de Origen:",
"shield_wildcard_hint": "Usa '*' para proteger desde todas las direcciones transparentes",
"shield_to_address": "Dirección Destino (Protegida):",
"shield_select_z": "Seleccionar dirección z...",
"shield_utxo_limit": "Límite UTXO:",
"shield_max_utxos": "UTXOs máximos por operación",
"shield_funds": "Proteger Fondos",
"shield_started": "Operación de protección iniciada",
"shield_check_status": "Verificar Estado",
"shield_completed": "¡Operación completada exitosamente!",
"shield_merge_done": "¡Protección/fusión completada!",
"shield_in_progress": "Operación en progreso...",
"merge_title": "Fusionar a Dirección",
"merge_description": "Fusiona múltiples UTXOs en una sola dirección protegida. Esto puede ayudar a reducir el tamaño de la cartera y mejorar la privacidad.",
"merge_funds": "Fusionar Fondos",
"merge_started": "Operación de fusión iniciada",
# ---- Transaction Details dialog ----
"tx_details_title": "Detalles de Transacción",
"tx_received": "RECIBIDO",
"tx_sent": "ENVIADO",
"tx_mined": "MINADO",
"tx_immature": "INMADURO",
"tx_confirmations": "%d confirmaciones",
"tx_id_label": "ID de Transacción:",
"tx_to_address": "Dirección Destino:",
"tx_from_address": "Dirección Origen:",
"tx_view_explorer": "Ver en Explorador",
"pending": "Pendiente",
# ---- Validate Address dialog ----
"validate_title": "Validar Dirección",
"validate_description": "Ingresa una dirección DragonX para verificar si es válida y si pertenece a esta cartera.",
"validate_btn": "Validar",
"validate_results": "Resultados:",
"validate_status": "Estado:",
"validate_valid": "VÁLIDA",
"validate_invalid": "INVÁLIDA",
"validate_type": "Tipo:",
"validate_ownership": "Propiedad:",
"validate_is_mine": "Esta cartera es dueña de esta dirección",
"validate_not_mine": "No es propiedad de esta cartera",
"validate_shielded_type": "Protegida (dirección z)",
"validate_transparent_type": "Transparente (dirección t)",
# ---- Misc ----
"transaction_sent": "Transacción enviada exitosamente",
}
# Load existing to preserve anything we might have missed
import os
existing_path = os.path.join(os.path.dirname(__file__), '..', 'res', 'lang', 'es.json')
out_path = existing_path
with open(out_path, 'w', encoding='utf-8') as f:
json.dump(dict(sorted(es.items())), f, indent=4, ensure_ascii=False)
f.write('\n')
print(f"Wrote {len(es)} Spanish translations to {out_path}")
+646
View File
@@ -0,0 +1,646 @@
#!/usr/bin/env python3
"""Generate French (fr) translations for ObsidianDragon wallet."""
import json, os
translations = {
"24h_change": "Variation 24h",
"24h_volume": "Volume 24h",
"about": "À propos",
"about_block_explorer": "Explorateur de blocs",
"about_block_height": "Hauteur de bloc :",
"about_build_date": "Date de compilation :",
"about_build_type": "Type de build :",
"about_chain": "Chaîne :",
"about_connections": "Connexions :",
"about_credits": "Crédits",
"about_daemon": "Daemon :",
"about_debug": "Débogage",
"about_dragonx": "À propos d'ObsidianDragon",
"about_edition": "Édition ImGui",
"about_github": "GitHub",
"about_imgui": "ImGui :",
"about_license": "Licence",
"about_license_text": "Ce logiciel est publié sous la licence publique générale GNU v3 (GPLv3). Vous êtes libre d'utiliser, de modifier et de distribuer ce logiciel selon les termes de la licence.",
"about_peers_count": "%zu pairs",
"about_release": "Version",
"about_title": "À propos d'ObsidianDragon",
"about_version": "Version :",
"about_website": "Site web",
"acrylic": "Acrylique",
"add": "Ajouter",
"address": "Adresse",
"address_book_add": "Ajouter une adresse",
"address_book_add_new": "Ajouter",
"address_book_added": "Adresse ajoutée au carnet",
"address_book_count": "%zu adresses enregistrées",
"address_book_deleted": "Entrée supprimée",
"address_book_edit": "Modifier l'adresse",
"address_book_empty": "Aucune adresse enregistrée. Cliquez sur 'Ajouter' pour en créer une.",
"address_book_exists": "L'adresse existe déjà dans le carnet",
"address_book_title": "Carnet d'adresses",
"address_book_update_failed": "Échec de la mise à jour - l'adresse est peut-être en double",
"address_book_updated": "Adresse mise à jour",
"address_copied": "Adresse copiée dans le presse-papiers",
"address_details": "Détails de l'adresse",
"address_label": "Adresse :",
"address_upper": "ADRESSE",
"address_url": "URL de l'adresse",
"addresses_appear_here": "Vos adresses de réception apparaîtront ici une fois connecté.",
"advanced": "AVANCÉ",
"all_filter": "Tout",
"allow_custom_fees": "Autoriser les frais personnalisés",
"amount": "Montant",
"amount_details": "DÉTAILS DU MONTANT",
"amount_exceeds_balance": "Le montant dépasse le solde",
"amount_label": "Montant :",
"appearance": "APPARENCE",
"auto_shield": "Auto-blindage du minage",
"available": "Disponible",
"backup_backing_up": "Sauvegarde en cours...",
"backup_create": "Créer une sauvegarde",
"backup_created": "Sauvegarde du portefeuille créée",
"backup_data": "SAUVEGARDE & DONNÉES",
"backup_description": "Créez une sauvegarde de votre fichier wallet.dat. Ce fichier contient toutes vos clés privées et l'historique des transactions. Conservez la sauvegarde dans un endroit sûr.",
"backup_destination": "Destination de sauvegarde :",
"backup_tip_external": "Stockez les sauvegardes sur des disques externes ou un stockage cloud",
"backup_tip_multiple": "Créez plusieurs sauvegardes à différents endroits",
"backup_tip_test": "Testez périodiquement la restauration à partir de la sauvegarde",
"backup_tips": "Conseils :",
"backup_title": "Sauvegarder le portefeuille",
"backup_wallet": "Sauvegarder le portefeuille...",
"backup_wallet_not_found": "Attention : wallet.dat introuvable à l'emplacement prévu",
"balance": "Solde",
"balance_layout": "Disposition du solde",
"ban": "Bannir",
"banned_peers": "Pairs bannis",
"block": "Bloc",
"block_bits": "Bits :",
"block_click_next": "Cliquez pour voir le bloc suivant",
"block_click_prev": "Cliquez pour voir le bloc précédent",
"block_explorer": "Explorateur de blocs",
"block_get_info": "Obtenir les infos du bloc",
"block_hash": "Hash du bloc :",
"block_height": "Hauteur du bloc :",
"block_info_title": "Informations sur le bloc",
"block_merkle_root": "Racine de Merkle :",
"block_nav_next": "Suivant >>",
"block_nav_prev": "<< Précédent",
"block_next": "Bloc suivant :",
"block_previous": "Bloc précédent :",
"block_size": "Taille :",
"block_timestamp": "Horodatage :",
"block_transactions": "Transactions :",
"blockchain_syncing": "Synchronisation de la blockchain (%.1f%%)... Les soldes peuvent être inexacts.",
"cancel": "Annuler",
"characters": "caractères",
"clear": "Effacer",
"clear_all_bans": "Lever tous les bannissements",
"clear_form_confirm": "Effacer tous les champs du formulaire ?",
"clear_request": "Effacer la demande",
"click_copy_address": "Cliquez pour copier l'adresse",
"click_copy_uri": "Cliquez pour copier l'URI",
"close": "Fermer",
"conf_count": "%d conf.",
"confirm_and_send": "Confirmer & Envoyer",
"confirm_send": "Confirmer l'envoi",
"confirm_transaction": "Confirmer la transaction",
"confirmations": "Confirmations",
"confirmations_display": "%d confirmations | %s",
"confirmed": "Confirmé",
"connected": "Connecté",
"connected_peers": "Pairs connectés",
"connecting": "Connexion...",
"console": "Console",
"console_auto_scroll": "Défilement auto",
"console_available_commands": "Commandes disponibles :",
"console_capturing_output": "Capture de la sortie du daemon...",
"console_clear": "Effacer",
"console_clear_console": "Effacer la console",
"console_cleared": "Console effacée",
"console_click_commands": "Cliquez sur les commandes ci-dessus pour les insérer",
"console_click_insert": "Cliquez pour insérer",
"console_click_insert_params": "Cliquez pour insérer avec paramètres",
"console_close": "Fermer",
"console_commands": "Commandes",
"console_common_rpc": "Commandes RPC courantes :",
"console_completions": "Complétions :",
"console_connected": "Connecté au daemon",
"console_copy_all": "Tout copier",
"console_copy_selected": "Copier",
"console_daemon": "Daemon",
"console_daemon_error": "Erreur du daemon !",
"console_daemon_started": "Daemon démarré",
"console_daemon_stopped": "Daemon arrêté",
"console_disconnected": "Déconnecté du daemon",
"console_errors": "Erreurs",
"console_filter_hint": "Filtrer la sortie...",
"console_help_clear": " clear - Effacer la console",
"console_help_getbalance": " getbalance - Afficher le solde transparent",
"console_help_getblockcount": " getblockcount - Afficher la hauteur de bloc actuelle",
"console_help_getinfo": " getinfo - Afficher les infos du nœud",
"console_help_getmininginfo": " getmininginfo - Afficher le statut du minage",
"console_help_getpeerinfo": " getpeerinfo - Afficher les pairs connectés",
"console_help_gettotalbalance": " gettotalbalance - Afficher le solde total",
"console_help_help": " help - Afficher ce message d'aide",
"console_help_setgenerate": " setgenerate - Contrôler le minage",
"console_help_stop": " stop - Arrêter le daemon",
"console_line_count": "%zu lignes",
"console_new_lines": "%d nouvelles lignes",
"console_no_daemon": "Pas de daemon",
"console_not_connected": "Erreur : Non connecté au daemon",
"console_rpc_reference": "Référence des commandes RPC",
"console_scanline": "Scanline de la console",
"console_search_commands": "Rechercher des commandes...",
"console_select_all": "Tout sélectionner",
"console_show_daemon_output": "Afficher la sortie du daemon",
"console_show_errors_only": "Afficher uniquement les erreurs",
"console_show_rpc_ref": "Afficher la référence des commandes RPC",
"console_showing_lines": "Affichage de %zu sur %zu lignes",
"console_starting_node": "Démarrage du nœud...",
"console_status_error": "Erreur",
"console_status_running": "En cours",
"console_status_starting": "Démarrage",
"console_status_stopped": "Arrêté",
"console_status_stopping": "Arrêt",
"console_status_unknown": "Inconnu",
"console_tab_completion": "Tab pour compléter",
"console_type_help": "Tapez 'help' pour les commandes disponibles",
"console_welcome": "Bienvenue dans la console ObsidianDragon",
"console_zoom_in": "Agrandir",
"console_zoom_out": "Réduire",
"copy": "Copier",
"copy_address": "Copier l'adresse complète",
"copy_error": "Copier l'erreur",
"copy_to_clipboard": "Copier dans le presse-papiers",
"copy_txid": "Copier le TxID",
"copy_uri": "Copier l'URI",
"current_price": "Prix actuel",
"custom_fees": "Frais personnalisés",
"dark": "Sombre",
"date": "Date",
"date_label": "Date :",
"delete": "Supprimer",
"difficulty": "Difficulté",
"disconnected": "Déconnecté",
"dismiss": "Ignorer",
"display": "Affichage",
"dragonx_green": "DragonX (Vert)",
"edit": "Modifier",
"error": "Erreur",
"est_time_to_block": "Temps est. par bloc",
"exit": "Quitter",
"explorer": "EXPLORATEUR",
"export": "Exporter",
"export_csv": "Exporter en CSV",
"export_keys_btn": "Exporter les clés",
"export_keys_danger": "DANGER : Ceci exportera TOUTES les clés privées de votre portefeuille ! Toute personne ayant accès à ce fichier peut voler vos fonds. Conservez-le en sécurité et supprimez-le après utilisation.",
"export_keys_include_t": "Inclure les adresses T (transparentes)",
"export_keys_include_z": "Inclure les adresses Z (blindées)",
"export_keys_options": "Options d'exportation :",
"export_keys_success": "Clés exportées avec succès",
"export_keys_title": "Exporter toutes les clés privées",
"export_private_key": "Exporter la clé privée",
"export_tx_count": "Exporter %zu transactions en fichier CSV.",
"export_tx_file_fail": "Impossible de créer le fichier CSV",
"export_tx_none": "Aucune transaction à exporter",
"export_tx_success": "Transactions exportées avec succès",
"export_tx_title": "Exporter les transactions en CSV",
"export_viewing_key": "Exporter la clé de visualisation",
"failed_create_shielded": "Échec de la création de l'adresse blindée",
"failed_create_transparent": "Échec de la création de l'adresse transparente",
"fee": "Frais",
"fee_high": "Élevés",
"fee_label": "Frais :",
"fee_low": "Faibles",
"fee_normal": "Normal",
"fetch_prices": "Récupérer les prix",
"file": "Fichier",
"file_save_location": "Le fichier sera enregistré dans : ~/.config/ObsidianDragon/",
"font_scale": "Taille de police",
"from": "De",
"from_upper": "DE",
"full_details": "Tous les détails",
"general": "Général",
"go_to_receive": "Aller à Recevoir",
"height": "Hauteur",
"help": "Aide",
"hide": "Masquer",
"history": "Historique",
"immature_type": "Immature",
"import": "Importer",
"import_key_btn": "Importer clé(s)",
"import_key_formats": "Formats de clés pris en charge :",
"import_key_full_rescan": "(0 = rescan complet)",
"import_key_label": "Clé(s) privée(s) :",
"import_key_no_valid": "Aucune clé valide trouvée dans l'entrée",
"import_key_rescan": "Re-scanner la blockchain après l'importation",
"import_key_start_height": "Hauteur de départ :",
"import_key_success": "Clés importées avec succès",
"import_key_t_format": "Clés privées WIF d'adresses T",
"import_key_title": "Importer une clé privée",
"import_key_tooltip": "Entrez une ou plusieurs clés privées, une par ligne.\nPrend en charge les clés z-adresse et t-adresse.\nLes lignes commençant par # sont traitées comme des commentaires.",
"import_key_warning": "Attention : Ne partagez jamais vos clés privées ! L'importation de clés provenant de sources non fiables peut compromettre votre portefeuille.",
"import_key_z_format": "Clés de dépenses z-adresse (secret-extended-key-...)",
"import_private_key": "Importer une clé privée...",
"invalid_address": "Format d'adresse invalide",
"ip_address": "Adresse IP",
"keep": "Conserver",
"keep_daemon": "Garder le daemon en marche",
"key_export_fetching": "Récupération de la clé depuis le portefeuille...",
"key_export_private_key": "Clé privée :",
"key_export_private_warning": "Gardez cette clé SECRÈTE ! Toute personne possédant cette clé peut dépenser vos fonds. Ne la partagez jamais en ligne ou avec des tiers non fiables.",
"key_export_reveal": "Révéler la clé",
"key_export_viewing_key": "Clé de visualisation :",
"key_export_viewing_warning": "Cette clé de visualisation permet à d'autres de voir vos transactions entrantes et votre solde, mais PAS de dépenser vos fonds. Ne la partagez qu'avec des personnes de confiance.",
"label": "Libellé :",
"language": "Langue",
"light": "Clair",
"loading": "Chargement...",
"loading_addresses": "Chargement des adresses...",
"local_hashrate": "Hashrate local",
"low_spec_mode": "Mode économie",
"market": "Marché",
"market_12h": "12h",
"market_18h": "18h",
"market_24h": "24h",
"market_24h_volume": "VOLUME 24H",
"market_6h": "6h",
"market_attribution": "Données de prix de NonKYC",
"market_btc_price": "PRIX BTC",
"market_cap": "Capitalisation",
"market_no_history": "Aucun historique de prix disponible",
"market_no_price": "Pas de données de prix",
"market_now": "Maintenant",
"market_pct_shielded": "%.0f%% Blindé",
"market_portfolio": "PORTEFEUILLE",
"market_price_unavailable": "Données de prix indisponibles",
"market_refresh_price": "Actualiser les données de prix",
"market_trade_on": "Échanger sur %s",
"mature": "Mature",
"max": "Max",
"memo": "Mémo (optionnel, chiffré)",
"memo_label": "Mémo :",
"memo_optional": "MÉMO (OPTIONNEL)",
"memo_upper": "MÉMO",
"memo_z_only": "Note : Les mémos ne sont disponibles que lors de l'envoi vers des adresses blindées (z)",
"merge_description": "Fusionnez plusieurs UTXOs en une seule adresse blindée. Cela peut réduire la taille du portefeuille et améliorer la confidentialité.",
"merge_funds": "Fusionner les fonds",
"merge_started": "Opération de fusion démarrée",
"merge_title": "Fusionner vers une adresse",
"mine_when_idle": "Miner au repos",
"mined": "miné",
"mined_filter": "Miné",
"mined_type": "Miné",
"mined_upper": "MINÉ",
"miner_fee": "Frais de mineur",
"mining": "Minage",
"mining_active": "Actif",
"mining_address_copied": "Adresse de minage copiée",
"mining_all_time": "Tout le temps",
"mining_already_saved": "URL du pool déjà enregistrée",
"mining_block_copied": "Hash du bloc copié",
"mining_chart_1m_ago": "il y a 1m",
"mining_chart_5m_ago": "il y a 5m",
"mining_chart_now": "Maintenant",
"mining_chart_start": "Début",
"mining_click": "Cliquer",
"mining_click_copy_address": "Cliquez pour copier l'adresse",
"mining_click_copy_block": "Cliquez pour copier le hash du bloc",
"mining_click_copy_difficulty": "Cliquez pour copier la difficulté",
"mining_connected": "Connecté",
"mining_connecting": "Connexion...",
"mining_control": "Contrôle du minage",
"mining_difficulty_copied": "Difficulté copiée",
"mining_est_block": "Bloc est.",
"mining_est_daily": "Est. quotidien",
"mining_filter_all": "Tout",
"mining_filter_tip_all": "Afficher tous les gains",
"mining_filter_tip_pool": "Afficher uniquement les gains du pool",
"mining_filter_tip_solo": "Afficher uniquement les gains solo",
"mining_idle_off_tooltip": "Activer le minage au repos",
"mining_idle_on_tooltip": "Désactiver le minage au repos",
"mining_local_hashrate": "Hashrate local",
"mining_mine": "Miner",
"mining_mining_addr": "Adr. minage",
"mining_network": "Réseau",
"mining_no_blocks_yet": "Aucun bloc trouvé pour l'instant",
"mining_no_payouts_yet": "Aucun paiement de pool pour l'instant",
"mining_no_saved_addresses": "Aucune adresse enregistrée",
"mining_no_saved_pools": "Aucun pool enregistré",
"mining_off": "Le minage est DÉSACTIVÉ",
"mining_on": "Le minage est ACTIVÉ",
"mining_open_in_explorer": "Ouvrir dans l'explorateur",
"mining_payout_address": "Adresse de paiement",
"mining_payout_tooltip": "Adresse pour recevoir les récompenses de minage",
"mining_pool": "Pool",
"mining_pool_hashrate": "Hashrate du pool",
"mining_pool_url": "URL du pool",
"mining_recent_blocks": "BLOCS RÉCENTS",
"mining_recent_payouts": "PAIEMENTS DE POOL RÉCENTS",
"mining_remove": "Supprimer",
"mining_reset_defaults": "Réinitialiser les paramètres",
"mining_save_payout_address": "Enregistrer l'adresse de paiement",
"mining_save_pool_url": "Enregistrer l'URL du pool",
"mining_saved_addresses": "Adresses enregistrées :",
"mining_saved_pools": "Pools enregistrés :",
"mining_shares": "Parts",
"mining_show_chart": "Graphique",
"mining_show_log": "Journal",
"mining_solo": "Solo",
"mining_starting": "Démarrage...",
"mining_starting_tooltip": "Le mineur démarre...",
"mining_statistics": "Statistiques de minage",
"mining_stop": "Arrêter",
"mining_stop_solo_for_pool": "Arrêtez le minage solo avant de démarrer le minage en pool",
"mining_stop_solo_for_pool_settings": "Arrêtez le minage solo pour modifier les paramètres du pool",
"mining_stopping": "Arrêt...",
"mining_stopping_tooltip": "Le mineur s'arrête...",
"mining_syncing_tooltip": "La blockchain se synchronise...",
"mining_threads": "Threads de minage",
"mining_to_save": "pour enregistrer",
"mining_today": "Aujourd'hui",
"mining_uptime": "Temps de fonctionnement",
"mining_yesterday": "Hier",
"network": "Réseau",
"network_fee": "FRAIS RÉSEAU",
"network_hashrate": "Hashrate du réseau",
"new": "+ Nouveau",
"new_shielded_created": "Nouvelle adresse blindée créée",
"new_t_address": "Nouvelle adresse T",
"new_t_transparent": "Nouvelle adresse t (Transparente)",
"new_transparent_created": "Nouvelle adresse transparente créée",
"new_z_address": "Nouvelle adresse Z",
"new_z_shielded": "Nouvelle adresse z (Blindée)",
"no_addresses": "Aucune adresse trouvée. Créez-en une avec les boutons ci-dessus.",
"no_addresses_available": "Aucune adresse disponible",
"no_addresses_match": "Aucune adresse ne correspond au filtre",
"no_addresses_with_balance": "Aucune adresse avec solde",
"no_matching": "Aucune transaction correspondante",
"no_recent_receives": "Aucune réception récente",
"no_recent_sends": "Aucun envoi récent",
"no_transactions": "Aucune transaction trouvée",
"node": "NŒUD",
"node_security": "NŒUD & SÉCURITÉ",
"noise": "Bruit",
"not_connected": "Non connecté au daemon...",
"not_connected_to_daemon": "Non connecté au daemon",
"notes": "Notes",
"notes_optional": "Notes (optionnel) :",
"output_filename": "Nom du fichier de sortie :",
"overview": "Aperçu",
"paste": "Coller",
"paste_from_clipboard": "Coller depuis le presse-papiers",
"pay_from": "Payer depuis",
"payment_request": "DEMANDE DE PAIEMENT",
"payment_request_copied": "Demande de paiement copiée",
"payment_uri_copied": "URI de paiement copiée",
"peers": "Pairs",
"peers_avg_ping": "Ping moyen",
"peers_ban_24h": "Bannir le pair 24h",
"peers_ban_score": "Score de ban : %d",
"peers_banned": "Bannis",
"peers_banned_count": "Bannis : %d",
"peers_best_block": "Meilleur bloc",
"peers_blockchain": "BLOCKCHAIN",
"peers_blocks": "Blocs",
"peers_blocks_left": "%d blocs restants",
"peers_clear_all_bans": "Lever tous les bannissements",
"peers_click_copy": "Cliquez pour copier",
"peers_connected": "Connectés",
"peers_connected_count": "Connectés : %d",
"peers_copy_ip": "Copier l'IP",
"peers_dir_in": "Ent.",
"peers_dir_out": "Sort.",
"peers_hash_copied": "Hash copié",
"peers_hashrate": "Hashrate",
"peers_in_out": "Ent./Sort.",
"peers_longest": "Plus longue",
"peers_longest_chain": "Plus longue chaîne",
"peers_memory": "Mémoire",
"peers_no_banned": "Aucun pair banni",
"peers_no_connected": "Aucun pair connecté",
"peers_no_tls": "Pas de TLS",
"peers_notarized": "Notarisé",
"peers_p2p_port": "Port P2P",
"peers_protocol": "Protocole",
"peers_received": "Reçu",
"peers_refresh": "Actualiser",
"peers_refresh_tooltip": "Actualiser la liste des pairs",
"peers_refreshing": "Actualisation...",
"peers_sent": "Envoyé",
"peers_tt_id": "ID : %d",
"peers_tt_received": "Reçu : %s",
"peers_tt_sent": "Envoyé : %s",
"peers_tt_services": "Services : %s",
"peers_tt_start_height": "Hauteur de départ : %d",
"peers_tt_synced": "Synchronisé H/B : %d/%d",
"peers_tt_tls_cipher": "TLS : %s",
"peers_unban": "Débannir",
"peers_upper": "PAIRS",
"peers_version": "Version",
"pending": "En attente",
"ping": "Ping",
"price_chart": "Graphique des prix",
"qr_code": "Code QR",
"qr_failed": "Échec de la génération du code QR",
"qr_title": "Code QR",
"qr_unavailable": "QR indisponible",
"receive": "Recevoir",
"received": "reçu",
"received_filter": "Reçu",
"received_label": "Reçu",
"received_upper": "REÇU",
"receiving_addresses": "Vos adresses de réception",
"recent_received": "REÇUS RÉCENTS",
"recent_sends": "ENVOIS RÉCENTS",
"recipient": "DESTINATAIRE",
"recv_type": "Reçu",
"refresh": "Actualiser",
"refresh_now": "Actualiser maintenant",
"report_bug": "Signaler un bug",
"request_amount": "Montant (optionnel) :",
"request_copy_uri": "Copier l'URI",
"request_description": "Générez une demande de paiement que d'autres peuvent scanner ou copier. Le code QR contient votre adresse et un montant/mémo optionnel.",
"request_label": "Libellé (optionnel) :",
"request_memo": "Mémo (optionnel) :",
"request_payment": "Demander un paiement",
"request_payment_uri": "URI de paiement :",
"request_receive_address": "Adresse de réception :",
"request_select_address": "Sélectionner une adresse...",
"request_shielded_addrs": "-- Adresses blindées --",
"request_title": "Demander un paiement",
"request_transparent_addrs": "-- Adresses transparentes --",
"request_uri_copied": "URI de paiement copiée dans le presse-papiers",
"rescan": "Re-scanner",
"reset_to_defaults": "Réinitialiser les paramètres",
"review_send": "Vérifier l'envoi",
"rpc_host": "Hôte RPC",
"rpc_pass": "Mot de passe",
"rpc_port": "Port",
"rpc_user": "Nom d'utilisateur",
"save": "Enregistrer",
"save_settings": "Enregistrer les paramètres",
"save_z_transactions": "Enregistrer les Z-tx dans la liste",
"search_placeholder": "Rechercher...",
"security": "SÉCURITÉ",
"select_address": "Sélectionner une adresse...",
"select_receiving_address": "Sélectionner une adresse de réception...",
"select_source_address": "Sélectionner une adresse source...",
"send": "Envoyer",
"send_amount": "Montant",
"send_amount_details": "DÉTAILS DU MONTANT",
"send_amount_upper": "MONTANT",
"send_clear_fields": "Effacer tous les champs du formulaire ?",
"send_copy_error": "Copier l'erreur",
"send_dismiss": "Ignorer",
"send_error_copied": "Erreur copiée dans le presse-papiers",
"send_error_prefix": "Erreur : %s",
"send_exceeds_available": "Dépasse le disponible (%.8f)",
"send_fee": "Frais",
"send_fee_high": "Élevés",
"send_fee_low": "Faibles",
"send_fee_normal": "Normal",
"send_form_restored": "Formulaire restauré",
"send_from_this_address": "Envoyer depuis cette adresse",
"send_go_to_receive": "Aller à Recevoir",
"send_keep": "Conserver",
"send_network_fee": "FRAIS RÉSEAU",
"send_no_balance": "Pas de solde",
"send_no_recent": "Aucun envoi récent",
"send_recent_sends": "ENVOIS RÉCENTS",
"send_recipient": "DESTINATAIRE",
"send_select_source": "Sélectionner une adresse source...",
"send_sending_from": "ENVOI DEPUIS",
"send_submitting": "Soumission de la transaction...",
"send_switch_to_receive": "Passez à Recevoir pour obtenir votre adresse et commencer à recevoir des fonds.",
"send_to": "Envoyer à",
"send_tooltip_enter_amount": "Entrez un montant à envoyer",
"send_tooltip_exceeds_balance": "Le montant dépasse le solde disponible",
"send_tooltip_in_progress": "Transaction déjà en cours",
"send_tooltip_invalid_address": "Entrez une adresse de destinataire valide",
"send_tooltip_not_connected": "Non connecté au daemon",
"send_tooltip_select_source": "Sélectionnez d'abord une adresse source",
"send_tooltip_syncing": "Attendez la synchronisation de la blockchain",
"send_total": "Total",
"send_transaction": "Envoyer la transaction",
"send_tx_failed": "Transaction échouée",
"send_tx_sent": "Transaction envoyée !",
"send_tx_success": "Transaction envoyée avec succès !",
"send_txid_copied": "TxID copié dans le presse-papiers",
"send_txid_label": "TxID : %s",
"send_valid_shielded": "Adresse blindée valide",
"send_valid_transparent": "Adresse transparente valide",
"send_wallet_empty": "Votre portefeuille est vide",
"send_yes_clear": "Oui, effacer",
"sending": "Envoi de la transaction",
"sending_from": "ENVOI DEPUIS",
"sent": "envoyé",
"sent_filter": "Envoyé",
"sent_type": "Envoyé",
"sent_upper": "ENVOYÉ",
"settings": "Paramètres",
"setup_wizard": "Assistant de configuration",
"share": "Partager",
"shield_check_status": "Vérifier le statut",
"shield_completed": "Opération terminée avec succès !",
"shield_description": "Blindez vos récompenses de minage en envoyant les sorties coinbase des adresses transparentes vers une adresse blindée. Cela améliore la confidentialité en masquant vos revenus de minage.",
"shield_from_address": "Depuis l'adresse :",
"shield_funds": "Blinder les fonds",
"shield_in_progress": "Opération en cours...",
"shield_max_utxos": "UTXOs max par opération",
"shield_merge_done": "Blindage/fusion terminé !",
"shield_select_z": "Sélectionner une z-adresse...",
"shield_started": "Opération de blindage démarrée",
"shield_title": "Blinder les récompenses coinbase",
"shield_to_address": "Vers l'adresse (blindée) :",
"shield_utxo_limit": "Limite UTXO :",
"shield_wildcard_hint": "Utilisez '*' pour blinder depuis toutes les adresses transparentes",
"shielded": "Blindé",
"shielded_to": "BLINDÉ VERS",
"shielded_type": "Blindé",
"show": "Afficher",
"show_qr_code": "Afficher le code QR",
"showing_transactions": "Affichage %d\xe2\x80\x93%d sur %d transactions (total : %zu)",
"simple_background": "Arrière-plan simple",
"start_mining": "Démarrer le minage",
"status": "Statut",
"stop_external": "Arrêter le daemon externe",
"stop_mining": "Arrêter le minage",
"submitting_transaction": "Soumission de la transaction...",
"success": "Succès",
"summary": "Résumé",
"syncing": "Synchronisation...",
"t_addresses": "Adresses T",
"test_connection": "Tester",
"theme": "Thème",
"theme_effects": "Effets de thème",
"time_days_ago": "il y a %d jours",
"time_hours_ago": "il y a %d heures",
"time_minutes_ago": "il y a %d minutes",
"time_seconds_ago": "il y a %d secondes",
"to": "À",
"to_upper": "À",
"tools": "OUTILS",
"total": "Total",
"transaction_id": "ID DE TRANSACTION",
"transaction_sent": "Transaction envoyée avec succès",
"transaction_sent_msg": "Transaction envoyée !",
"transaction_url": "URL de transaction",
"transactions": "Transactions",
"transactions_upper": "TRANSACTIONS",
"transparent": "Transparent",
"tx_confirmations": "%d confirmations",
"tx_details_title": "Détails de la transaction",
"tx_from_address": "Adresse d'origine :",
"tx_id_label": "ID de transaction :",
"tx_immature": "IMMATURE",
"tx_mined": "MINÉ",
"tx_received": "REÇU",
"tx_sent": "ENVOYÉ",
"tx_to_address": "Adresse de destination :",
"tx_view_explorer": "Voir dans l'explorateur",
"txs_count": "%d txs",
"type": "Type",
"ui_opacity": "Opacité de l'interface",
"unban": "Débannir",
"unconfirmed": "Non confirmé",
"undo_clear": "Annuler l'effacement",
"unknown": "Inconnu",
"use_embedded_daemon": "Utiliser le dragonxd intégré",
"use_tor": "Utiliser Tor",
"validate_btn": "Valider",
"validate_description": "Entrez une adresse DragonX pour vérifier si elle est valide et si elle appartient à ce portefeuille.",
"validate_invalid": "INVALIDE",
"validate_is_mine": "Ce portefeuille possède cette adresse",
"validate_not_mine": "N'appartient pas à ce portefeuille",
"validate_ownership": "Propriété :",
"validate_results": "Résultats :",
"validate_shielded_type": "Blindée (z-adresse)",
"validate_status": "Statut :",
"validate_title": "Valider l'adresse",
"validate_transparent_type": "Transparente (t-adresse)",
"validate_type": "Type :",
"validate_valid": "VALIDE",
"validating": "Validation...",
"verbose_logging": "Journalisation détaillée",
"version": "Version",
"view": "Afficher",
"view_details": "Voir les détails",
"view_on_explorer": "Voir dans l'explorateur",
"waiting_for_daemon": "En attente de la connexion au daemon...",
"wallet": "PORTEFEUILLE",
"wallet_empty": "Votre portefeuille est vide",
"wallet_empty_hint": "Passez à Recevoir pour obtenir votre adresse et commencer à recevoir des fonds.",
"warning": "Attention",
"warning_upper": "ATTENTION !",
"website": "Site web",
"window_opacity": "Opacité de la fenêtre",
"yes_clear": "Oui, effacer",
"your_addresses": "Vos adresses",
"z_addresses": "Adresses Z",
}
out = os.path.join(os.path.dirname(__file__), "..", "res", "lang", "fr.json")
with open(out, "w", encoding="utf-8") as f:
json.dump(translations, f, indent=4, ensure_ascii=False, sort_keys=True)
print(f"Wrote {len(translations)} French translations to {os.path.abspath(out)}")
+646
View File
@@ -0,0 +1,646 @@
#!/usr/bin/env python3
"""Generate Japanese (ja) translations for ObsidianDragon wallet."""
import json, os
translations = {
"24h_change": "24時間変動",
"24h_volume": "24時間出来高",
"about": "概要",
"about_block_explorer": "ブロックエクスプローラー",
"about_block_height": "ブロック高:",
"about_build_date": "ビルド日:",
"about_build_type": "ビルドタイプ:",
"about_chain": "チェーン:",
"about_connections": "接続数:",
"about_credits": "クレジット",
"about_daemon": "デーモン:",
"about_debug": "デバッグ",
"about_dragonx": "ObsidianDragonについて",
"about_edition": "ImGui エディション",
"about_github": "GitHub",
"about_imgui": "ImGui:",
"about_license": "ライセンス",
"about_license_text": "本ソフトウェアはGNU General Public License v3 (GPLv3)の下で公開されています。ライセンス条項に従い、自由に使用、変更、配布できます。",
"about_peers_count": "%zu ピア",
"about_release": "リリース",
"about_title": "ObsidianDragonについて",
"about_version": "バージョン:",
"about_website": "ウェブサイト",
"acrylic": "アクリル",
"add": "追加",
"address": "アドレス",
"address_book_add": "アドレスを追加",
"address_book_add_new": "新規追加",
"address_book_added": "アドレスをアドレス帳に追加しました",
"address_book_count": "%zu 件のアドレスを保存済み",
"address_book_deleted": "エントリを削除しました",
"address_book_edit": "アドレスを編集",
"address_book_empty": "保存されたアドレスがありません。「新規追加」をクリックして追加してください。",
"address_book_exists": "アドレスは既にアドレス帳に存在します",
"address_book_title": "アドレス帳",
"address_book_update_failed": "更新に失敗しました — アドレスが重複している可能性があります",
"address_book_updated": "アドレスを更新しました",
"address_copied": "アドレスをクリップボードにコピーしました",
"address_details": "アドレス詳細",
"address_label": "アドレス:",
"address_upper": "アドレス",
"address_url": "アドレスURL",
"addresses_appear_here": "接続後、受信アドレスがここに表示されます。",
"advanced": "詳細設定",
"all_filter": "すべて",
"allow_custom_fees": "カスタム手数料を許可",
"amount": "金額",
"amount_details": "金額の詳細",
"amount_exceeds_balance": "金額が残高を超えています",
"amount_label": "金額:",
"appearance": "外観",
"auto_shield": "マイニング自動シールド",
"available": "利用可能",
"backup_backing_up": "バックアップ中...",
"backup_create": "バックアップを作成",
"backup_created": "ウォレットのバックアップを作成しました",
"backup_data": "バックアップとデータ",
"backup_description": "wallet.datファイルのバックアップを作成します。このファイルにはすべての秘密鍵と取引履歴が含まれています。バックアップは安全な場所に保管してください。",
"backup_destination": "バックアップ先:",
"backup_tip_external": "外部ドライブまたはクラウドストレージにバックアップを保存",
"backup_tip_multiple": "異なる場所に複数のバックアップを作成",
"backup_tip_test": "定期的にバックアップからの復元をテスト",
"backup_tips": "ヒント:",
"backup_title": "ウォレットのバックアップ",
"backup_wallet": "ウォレットをバックアップ...",
"backup_wallet_not_found": "警告:予想される場所にwallet.datが見つかりません",
"balance": "残高",
"balance_layout": "残高レイアウト",
"ban": "ブロック",
"banned_peers": "ブロック済みピア",
"block": "ブロック",
"block_bits": "ビット:",
"block_click_next": "クリックして次のブロックを表示",
"block_click_prev": "クリックして前のブロックを表示",
"block_explorer": "ブロックエクスプローラー",
"block_get_info": "ブロック情報を取得",
"block_hash": "ブロックハッシュ:",
"block_height": "ブロック高:",
"block_info_title": "ブロック情報",
"block_merkle_root": "マークルルート:",
"block_nav_next": "次へ >>",
"block_nav_prev": "<< 前へ",
"block_next": "次のブロック:",
"block_previous": "前のブロック:",
"block_size": "サイズ:",
"block_timestamp": "タイムスタンプ:",
"block_transactions": "トランザクション:",
"blockchain_syncing": "ブロックチェーン同期中 (%.1f%%)... 残高が不正確な場合があります。",
"cancel": "キャンセル",
"characters": "文字",
"clear": "クリア",
"clear_all_bans": "すべてのブロックを解除",
"clear_form_confirm": "すべてのフォームフィールドをクリアしますか?",
"clear_request": "リクエストをクリア",
"click_copy_address": "クリックしてアドレスをコピー",
"click_copy_uri": "クリックしてURIをコピー",
"close": "閉じる",
"conf_count": "%d 確認",
"confirm_and_send": "確認して送金",
"confirm_send": "送金を確認",
"confirm_transaction": "取引を確認",
"confirmations": "確認数",
"confirmations_display": "%d 確認 | %s",
"confirmed": "確認済み",
"connected": "接続済み",
"connected_peers": "接続中のピア",
"connecting": "接続中...",
"console": "コンソール",
"console_auto_scroll": "自動スクロール",
"console_available_commands": "利用可能なコマンド:",
"console_capturing_output": "デーモン出力をキャプチャ中...",
"console_clear": "クリア",
"console_clear_console": "コンソールをクリア",
"console_cleared": "コンソールをクリアしました",
"console_click_commands": "上のコマンドをクリックして挿入",
"console_click_insert": "クリックして挿入",
"console_click_insert_params": "クリックしてパラメータ付きで挿入",
"console_close": "閉じる",
"console_commands": "コマンド",
"console_common_rpc": "一般的なRPCコマンド:",
"console_completions": "補完:",
"console_connected": "デーモンに接続済み",
"console_copy_all": "すべてコピー",
"console_copy_selected": "コピー",
"console_daemon": "デーモン",
"console_daemon_error": "デーモンエラー!",
"console_daemon_started": "デーモンが起動しました",
"console_daemon_stopped": "デーモンが停止しました",
"console_disconnected": "デーモンから切断されました",
"console_errors": "エラー",
"console_filter_hint": "出力をフィルタ...",
"console_help_clear": " clear - コンソールをクリア",
"console_help_getbalance": " getbalance - 透明残高を表示",
"console_help_getblockcount": " getblockcount - 現在のブロック高を表示",
"console_help_getinfo": " getinfo - ノード情報を表示",
"console_help_getmininginfo": " getmininginfo - マイニング状況を表示",
"console_help_getpeerinfo": " getpeerinfo - 接続中のピアを表示",
"console_help_gettotalbalance": " gettotalbalance - 合計残高を表示",
"console_help_help": " help - このヘルプを表示",
"console_help_setgenerate": " setgenerate - マイニングを制御",
"console_help_stop": " stop - デーモンを停止",
"console_line_count": "%zu 行",
"console_new_lines": "%d 新しい行",
"console_no_daemon": "デーモンなし",
"console_not_connected": "エラー:デーモンに接続されていません",
"console_rpc_reference": "RPCコマンドリファレンス",
"console_scanline": "コンソールスキャンライン",
"console_search_commands": "コマンドを検索...",
"console_select_all": "すべて選択",
"console_show_daemon_output": "デーモン出力を表示",
"console_show_errors_only": "エラーのみ表示",
"console_show_rpc_ref": "RPCコマンドリファレンスを表示",
"console_showing_lines": "%zu / %zu 行を表示中",
"console_starting_node": "ノードを起動中...",
"console_status_error": "エラー",
"console_status_running": "実行中",
"console_status_starting": "起動中",
"console_status_stopped": "停止済み",
"console_status_stopping": "停止中",
"console_status_unknown": "不明",
"console_tab_completion": "Tabで補完",
"console_type_help": "'help'と入力して利用可能なコマンドを表示",
"console_welcome": "ObsidianDragonコンソールへようこそ",
"console_zoom_in": "拡大",
"console_zoom_out": "縮小",
"copy": "コピー",
"copy_address": "完全なアドレスをコピー",
"copy_error": "エラーをコピー",
"copy_to_clipboard": "クリップボードにコピー",
"copy_txid": "TxIDをコピー",
"copy_uri": "URIをコピー",
"current_price": "現在の価格",
"custom_fees": "カスタム手数料",
"dark": "ダーク",
"date": "日付",
"date_label": "日付:",
"delete": "削除",
"difficulty": "難易度",
"disconnected": "切断済み",
"dismiss": "閉じる",
"display": "表示",
"dragonx_green": "DragonX(グリーン)",
"edit": "編集",
"error": "エラー",
"est_time_to_block": "予測ブロック時間",
"exit": "終了",
"explorer": "エクスプローラー",
"export": "エクスポート",
"export_csv": "CSVエクスポート",
"export_keys_btn": "鍵をエクスポート",
"export_keys_danger": "危険:ウォレットからすべての秘密鍵がエクスポートされます!このファイルにアクセスできる人は誰でもあなたの資金を盗めます。安全に保管し、使用後は削除してください。",
"export_keys_include_t": "Tアドレスを含める(透明)",
"export_keys_include_z": "Zアドレスを含める(シールド)",
"export_keys_options": "エクスポートオプション:",
"export_keys_success": "鍵のエクスポートに成功しました",
"export_keys_title": "すべての秘密鍵をエクスポート",
"export_private_key": "秘密鍵をエクスポート",
"export_tx_count": "%zu件の取引をCSVファイルにエクスポート。",
"export_tx_file_fail": "CSVファイルの作成に失敗しました",
"export_tx_none": "エクスポートする取引がありません",
"export_tx_success": "取引のエクスポートに成功しました",
"export_tx_title": "取引をCSVにエクスポート",
"export_viewing_key": "閲覧鍵をエクスポート",
"failed_create_shielded": "シールドアドレスの作成に失敗しました",
"failed_create_transparent": "透明アドレスの作成に失敗しました",
"fee": "手数料",
"fee_high": "高い",
"fee_label": "手数料:",
"fee_low": "低い",
"fee_normal": "通常",
"fetch_prices": "価格を取得",
"file": "ファイル",
"file_save_location": "ファイルの保存先:~/.config/ObsidianDragon/",
"font_scale": "フォントサイズ",
"from": "送信元",
"from_upper": "送信元",
"full_details": "詳細情報",
"general": "一般",
"go_to_receive": "受信へ移動",
"height": "高さ",
"help": "ヘルプ",
"hide": "非表示",
"history": "履歴",
"immature_type": "未成熟",
"import": "インポート",
"import_key_btn": "鍵をインポート",
"import_key_formats": "サポートされる鍵形式:",
"import_key_full_rescan": "(0 = 完全再スキャン)",
"import_key_label": "秘密鍵:",
"import_key_no_valid": "入力に有効な鍵が見つかりません",
"import_key_rescan": "インポート後にブロックチェーンを再スキャン",
"import_key_start_height": "開始高:",
"import_key_success": "鍵のインポートに成功しました",
"import_key_t_format": "TアドレスWIF秘密鍵",
"import_key_title": "秘密鍵をインポート",
"import_key_tooltip": "1行に1つずつ秘密鍵を入力してください。\nzアドレスとtアドレスの鍵の両方に対応しています。\n#で始まる行はコメントとして扱われます。",
"import_key_warning": "警告:秘密鍵を決して共有しないでください!信頼できないソースからの鍵のインポートはウォレットを危険にさらす可能性があります。",
"import_key_z_format": "Zアドレス支出鍵 (secret-extended-key-...)",
"import_private_key": "秘密鍵をインポート...",
"invalid_address": "無効なアドレス形式",
"ip_address": "IPアドレス",
"keep": "保持",
"keep_daemon": "デーモンを実行し続ける",
"key_export_fetching": "ウォレットから鍵を取得中...",
"key_export_private_key": "秘密鍵:",
"key_export_private_warning": "この鍵は秘密にしてください!この鍵を持つ人は誰でもあなたの資金を使えます。オンラインや信頼できない相手と共有しないでください。",
"key_export_reveal": "鍵を表示",
"key_export_viewing_key": "閲覧鍵:",
"key_export_viewing_warning": "この閲覧鍵を使うと、他者があなたの受信取引と残高を見ることができますが、資金を使うことはできません。信頼できる相手とのみ共有してください。",
"label": "ラベル:",
"language": "言語",
"light": "ライト",
"loading": "読み込み中...",
"loading_addresses": "アドレスを読み込み中...",
"local_hashrate": "ローカルハッシュレート",
"low_spec_mode": "省電力モード",
"market": "市場",
"market_12h": "12時間",
"market_18h": "18時間",
"market_24h": "24時間",
"market_24h_volume": "24時間出来高",
"market_6h": "6時間",
"market_attribution": "価格データ:NonKYC提供",
"market_btc_price": "BTC価格",
"market_cap": "時価総額",
"market_no_history": "価格履歴がありません",
"market_no_price": "価格データなし",
"market_now": "現在",
"market_pct_shielded": "%.0f%% シールド済み",
"market_portfolio": "ポートフォリオ",
"market_price_unavailable": "価格データが利用できません",
"market_refresh_price": "価格データを更新",
"market_trade_on": "%s で取引",
"mature": "成熟済み",
"max": "最大",
"memo": "メモ(任意、暗号化)",
"memo_label": "メモ:",
"memo_optional": "メモ(任意)",
"memo_upper": "メモ",
"memo_z_only": "注:メモはシールド (z) アドレスへの送金時のみ利用可能です",
"merge_description": "複数のUTXOを単一のシールドアドレスに統合します。ウォレットサイズの縮小とプライバシーの向上に役立ちます。",
"merge_funds": "資金を統合",
"merge_started": "統合操作を開始しました",
"merge_title": "アドレスに統合",
"mine_when_idle": "アイドル時にマイニング",
"mined": "採掘済み",
"mined_filter": "採掘済み",
"mined_type": "採掘済み",
"mined_upper": "採掘済み",
"miner_fee": "マイナー手数料",
"mining": "マイニング",
"mining_active": "アクティブ",
"mining_address_copied": "マイニングアドレスをコピーしました",
"mining_all_time": "全期間",
"mining_already_saved": "プールURLは既に保存済みです",
"mining_block_copied": "ブロックハッシュをコピーしました",
"mining_chart_1m_ago": "1分前",
"mining_chart_5m_ago": "5分前",
"mining_chart_now": "現在",
"mining_chart_start": "開始",
"mining_click": "クリック",
"mining_click_copy_address": "クリックしてアドレスをコピー",
"mining_click_copy_block": "クリックしてブロックハッシュをコピー",
"mining_click_copy_difficulty": "クリックして難易度をコピー",
"mining_connected": "接続済み",
"mining_connecting": "接続中...",
"mining_control": "マイニング制御",
"mining_difficulty_copied": "難易度をコピーしました",
"mining_est_block": "予測ブロック",
"mining_est_daily": "予測日収",
"mining_filter_all": "すべて",
"mining_filter_tip_all": "すべての収益を表示",
"mining_filter_tip_pool": "プール収益のみ表示",
"mining_filter_tip_solo": "ソロ収益のみ表示",
"mining_idle_off_tooltip": "アイドルマイニングを有効にする",
"mining_idle_on_tooltip": "アイドルマイニングを無効にする",
"mining_local_hashrate": "ローカルハッシュレート",
"mining_mine": "マイニング",
"mining_mining_addr": "マイニングアドレス",
"mining_network": "ネットワーク",
"mining_no_blocks_yet": "まだブロックが見つかっていません",
"mining_no_payouts_yet": "まだプール支払いがありません",
"mining_no_saved_addresses": "保存されたアドレスがありません",
"mining_no_saved_pools": "保存されたプールがありません",
"mining_off": "マイニングはオフです",
"mining_on": "マイニングはオンです",
"mining_open_in_explorer": "エクスプローラーで開く",
"mining_payout_address": "支払いアドレス",
"mining_payout_tooltip": "マイニング報酬の受取アドレス",
"mining_pool": "プール",
"mining_pool_hashrate": "プールハッシュレート",
"mining_pool_url": "プールURL",
"mining_recent_blocks": "最近のブロック",
"mining_recent_payouts": "最近のプール支払い",
"mining_remove": "削除",
"mining_reset_defaults": "デフォルトにリセット",
"mining_save_payout_address": "支払いアドレスを保存",
"mining_save_pool_url": "プールURLを保存",
"mining_saved_addresses": "保存済みアドレス:",
"mining_saved_pools": "保存済みプール:",
"mining_shares": "シェア",
"mining_show_chart": "チャート",
"mining_show_log": "ログ",
"mining_solo": "ソロ",
"mining_starting": "起動中...",
"mining_starting_tooltip": "マイナーを起動中...",
"mining_statistics": "マイニング統計",
"mining_stop": "停止",
"mining_stop_solo_for_pool": "プールマイニングを開始する前にソロマイニングを停止してください",
"mining_stop_solo_for_pool_settings": "プール設定を変更するにはソロマイニングを停止してください",
"mining_stopping": "停止中...",
"mining_stopping_tooltip": "マイナーを停止中...",
"mining_syncing_tooltip": "ブロックチェーン同期中...",
"mining_threads": "マイニングスレッド",
"mining_to_save": "保存する",
"mining_today": "今日",
"mining_uptime": "稼働時間",
"mining_yesterday": "昨日",
"network": "ネットワーク",
"network_fee": "ネットワーク手数料",
"network_hashrate": "ネットワークハッシュレート",
"new": "+ 新規",
"new_shielded_created": "新しいシールドアドレスを作成しました",
"new_t_address": "新しいTアドレス",
"new_t_transparent": "新しいtアドレス(透明)",
"new_transparent_created": "新しい透明アドレスを作成しました",
"new_z_address": "新しいZアドレス",
"new_z_shielded": "新しいzアドレス(シールド)",
"no_addresses": "アドレスが見つかりません。上のボタンを使用して作成してください。",
"no_addresses_available": "利用可能なアドレスがありません",
"no_addresses_match": "フィルタに一致するアドレスがありません",
"no_addresses_with_balance": "残高のあるアドレスがありません",
"no_matching": "一致する取引がありません",
"no_recent_receives": "最近の受信がありません",
"no_recent_sends": "最近の送信がありません",
"no_transactions": "取引が見つかりません",
"node": "ノード",
"node_security": "ノードとセキュリティ",
"noise": "ノイズ",
"not_connected": "デーモンに未接続...",
"not_connected_to_daemon": "デーモンに未接続",
"notes": "メモ",
"notes_optional": "メモ(任意):",
"output_filename": "出力ファイル名:",
"overview": "概要",
"paste": "貼り付け",
"paste_from_clipboard": "クリップボードから貼り付け",
"pay_from": "支払い元",
"payment_request": "支払い請求",
"payment_request_copied": "支払い請求をコピーしました",
"payment_uri_copied": "支払いURIをコピーしました",
"peers": "ピア",
"peers_avg_ping": "平均Ping",
"peers_ban_24h": "ピアを24時間ブロック",
"peers_ban_score": "ブロックスコア:%d",
"peers_banned": "ブロック済み",
"peers_banned_count": "ブロック済み:%d",
"peers_best_block": "最良ブロック",
"peers_blockchain": "ブロックチェーン",
"peers_blocks": "ブロック",
"peers_blocks_left": "残り %d ブロック",
"peers_clear_all_bans": "すべてのブロックを解除",
"peers_click_copy": "クリックしてコピー",
"peers_connected": "接続済み",
"peers_connected_count": "接続済み:%d",
"peers_copy_ip": "IPをコピー",
"peers_dir_in": "入",
"peers_dir_out": "出",
"peers_hash_copied": "ハッシュをコピーしました",
"peers_hashrate": "ハッシュレート",
"peers_in_out": "入/出",
"peers_longest": "最長",
"peers_longest_chain": "最長チェーン",
"peers_memory": "メモリ",
"peers_no_banned": "ブロック済みピアなし",
"peers_no_connected": "接続済みピアなし",
"peers_no_tls": "TLSなし",
"peers_notarized": "公証済み",
"peers_p2p_port": "P2Pポート",
"peers_protocol": "プロトコル",
"peers_received": "受信",
"peers_refresh": "更新",
"peers_refresh_tooltip": "ピアリストを更新",
"peers_refreshing": "更新中...",
"peers_sent": "送信",
"peers_tt_id": "ID:%d",
"peers_tt_received": "受信:%s",
"peers_tt_sent": "送信:%s",
"peers_tt_services": "サービス:%s",
"peers_tt_start_height": "開始高:%d",
"peers_tt_synced": "同期済み H/B:%d/%d",
"peers_tt_tls_cipher": "TLS:%s",
"peers_unban": "ブロック解除",
"peers_upper": "ピア",
"peers_version": "バージョン",
"pending": "保留中",
"ping": "Ping",
"price_chart": "価格チャート",
"qr_code": "QRコード",
"qr_failed": "QRコードの生成に失敗しました",
"qr_title": "QRコード",
"qr_unavailable": "QR利用不可",
"receive": "受信",
"received": "受信済み",
"received_filter": "受信済み",
"received_label": "受信済み",
"received_upper": "受信済み",
"receiving_addresses": "あなたの受信アドレス",
"recent_received": "最近の受信",
"recent_sends": "最近の送信",
"recipient": "受取人",
"recv_type": "受信",
"refresh": "更新",
"refresh_now": "今すぐ更新",
"report_bug": "バグを報告",
"request_amount": "金額(任意):",
"request_copy_uri": "URIをコピー",
"request_description": "他の人がスキャンまたはコピーできる支払い請求を生成します。QRコードにはアドレスとオプションの金額/メモが含まれます。",
"request_label": "ラベル(任意):",
"request_memo": "メモ(任意):",
"request_payment": "支払いを請求",
"request_payment_uri": "支払いURI:",
"request_receive_address": "受信アドレス:",
"request_select_address": "アドレスを選択...",
"request_shielded_addrs": "-- シールドアドレス --",
"request_title": "支払いを請求",
"request_transparent_addrs": "-- 透明アドレス --",
"request_uri_copied": "支払いURIをクリップボードにコピーしました",
"rescan": "再スキャン",
"reset_to_defaults": "デフォルトにリセット",
"review_send": "送金を確認",
"rpc_host": "RPCホスト",
"rpc_pass": "パスワード",
"rpc_port": "ポート",
"rpc_user": "ユーザー名",
"save": "保存",
"save_settings": "設定を保存",
"save_z_transactions": "Z取引を取引リストに保存",
"search_placeholder": "検索...",
"security": "セキュリティ",
"select_address": "アドレスを選択...",
"select_receiving_address": "受信アドレスを選択...",
"select_source_address": "送信元アドレスを選択...",
"send": "送金",
"send_amount": "金額",
"send_amount_details": "金額の詳細",
"send_amount_upper": "金額",
"send_clear_fields": "すべてのフォームフィールドをクリアしますか?",
"send_copy_error": "エラーをコピー",
"send_dismiss": "閉じる",
"send_error_copied": "エラーをクリップボードにコピーしました",
"send_error_prefix": "エラー:%s",
"send_exceeds_available": "利用可能額を超過 (%.8f)",
"send_fee": "手数料",
"send_fee_high": "高い",
"send_fee_low": "低い",
"send_fee_normal": "通常",
"send_form_restored": "フォームが復元されました",
"send_from_this_address": "このアドレスから送金",
"send_go_to_receive": "受信へ移動",
"send_keep": "保持",
"send_network_fee": "ネットワーク手数料",
"send_no_balance": "残高なし",
"send_no_recent": "最近の送信なし",
"send_recent_sends": "最近の送信",
"send_recipient": "受取人",
"send_select_source": "送信元アドレスを選択...",
"send_sending_from": "送信元",
"send_submitting": "取引を送信中...",
"send_switch_to_receive": "受信に切り替えてアドレスを取得し、資金の受け取りを開始してください。",
"send_to": "送金先",
"send_tooltip_enter_amount": "送金額を入力してください",
"send_tooltip_exceeds_balance": "金額が利用可能残高を超えています",
"send_tooltip_in_progress": "取引は既に進行中です",
"send_tooltip_invalid_address": "有効な受取人アドレスを入力してください",
"send_tooltip_not_connected": "デーモンに未接続",
"send_tooltip_select_source": "まず送信元アドレスを選択してください",
"send_tooltip_syncing": "ブロックチェーンの同期をお待ちください",
"send_total": "合計",
"send_transaction": "取引を送信",
"send_tx_failed": "取引に失敗しました",
"send_tx_sent": "取引を送信しました!",
"send_tx_success": "取引の送信に成功しました!",
"send_txid_copied": "TxIDをクリップボードにコピーしました",
"send_txid_label": "TxID:%s",
"send_valid_shielded": "有効なシールドアドレス",
"send_valid_transparent": "有効な透明アドレス",
"send_wallet_empty": "ウォレットは空です",
"send_yes_clear": "はい、クリア",
"sending": "取引を送信中",
"sending_from": "送信元",
"sent": "送信済み",
"sent_filter": "送信済み",
"sent_type": "送信済み",
"sent_upper": "送信済み",
"settings": "設定",
"setup_wizard": "セットアップウィザード",
"share": "共有",
"shield_check_status": "ステータスを確認",
"shield_completed": "操作が正常に完了しました!",
"shield_description": "透明アドレスのcoinbase出力をシールドアドレスに送信して、マイニング報酬をシールドします。マイニング収入を隠すことでプライバシーが向上します。",
"shield_from_address": "送信元アドレス:",
"shield_funds": "資金をシールド",
"shield_in_progress": "操作進行中...",
"shield_max_utxos": "1回の操作あたりの最大UTXO数",
"shield_merge_done": "シールド/統合が完了しました!",
"shield_select_z": "zアドレスを選択...",
"shield_started": "シールド操作を開始しました",
"shield_title": "Coinbase報酬をシールド",
"shield_to_address": "送信先アドレス(シールド):",
"shield_utxo_limit": "UTXO制限:",
"shield_wildcard_hint": "'*' を使用してすべての透明アドレスからシールド",
"shielded": "シールド",
"shielded_to": "シールド先",
"shielded_type": "シールド",
"show": "表示",
"show_qr_code": "QRコードを表示",
"showing_transactions": "%d\xe2\x80\x93%d / %d 件の取引を表示中(合計:%zu)",
"simple_background": "シンプル背景",
"start_mining": "マイニング開始",
"status": "ステータス",
"stop_external": "外部デーモンを停止",
"stop_mining": "マイニング停止",
"submitting_transaction": "取引を送信中...",
"success": "成功",
"summary": "概要",
"syncing": "同期中...",
"t_addresses": "Tアドレス",
"test_connection": "テスト",
"theme": "テーマ",
"theme_effects": "テーマ効果",
"time_days_ago": "%d日前",
"time_hours_ago": "%d時間前",
"time_minutes_ago": "%d分前",
"time_seconds_ago": "%d秒前",
"to": "宛先",
"to_upper": "宛先",
"tools": "ツール",
"total": "合計",
"transaction_id": "取引ID",
"transaction_sent": "取引の送信に成功しました",
"transaction_sent_msg": "取引を送信しました!",
"transaction_url": "取引URL",
"transactions": "取引",
"transactions_upper": "取引",
"transparent": "透明",
"tx_confirmations": "%d 確認",
"tx_details_title": "取引の詳細",
"tx_from_address": "送信元アドレス:",
"tx_id_label": "取引ID:",
"tx_immature": "未成熟",
"tx_mined": "採掘済み",
"tx_received": "受信済み",
"tx_sent": "送信済み",
"tx_to_address": "送信先アドレス:",
"tx_view_explorer": "エクスプローラーで表示",
"txs_count": "%d 件",
"type": "タイプ",
"ui_opacity": "UI透明度",
"unban": "ブロック解除",
"unconfirmed": "未確認",
"undo_clear": "クリアを元に戻す",
"unknown": "不明",
"use_embedded_daemon": "内蔵dragonxdを使用",
"use_tor": "Torを使用",
"validate_btn": "検証",
"validate_description": "DragonXアドレスを入力して、有効かどうか、そしてこのウォレットに属しているかどうかを確認します。",
"validate_invalid": "無効",
"validate_is_mine": "このウォレットがこのアドレスを所有しています",
"validate_not_mine": "このウォレットに属していません",
"validate_ownership": "所有者:",
"validate_results": "結果:",
"validate_shielded_type": "シールド(zアドレス)",
"validate_status": "ステータス:",
"validate_title": "アドレスを検証",
"validate_transparent_type": "透明(tアドレス)",
"validate_type": "タイプ:",
"validate_valid": "有効",
"validating": "検証中...",
"verbose_logging": "詳細ログ",
"version": "バージョン",
"view": "表示",
"view_details": "詳細を表示",
"view_on_explorer": "エクスプローラーで表示",
"waiting_for_daemon": "デーモン接続を待機中...",
"wallet": "ウォレット",
"wallet_empty": "ウォレットは空です",
"wallet_empty_hint": "受信に切り替えてアドレスを取得し、資金の受け取りを開始してください。",
"warning": "警告",
"warning_upper": "警告!",
"website": "ウェブサイト",
"window_opacity": "ウィンドウ透明度",
"yes_clear": "はい、クリア",
"your_addresses": "あなたのアドレス",
"z_addresses": "Zアドレス",
}
out = os.path.join(os.path.dirname(__file__), "..", "res", "lang", "ja.json")
with open(out, "w", encoding="utf-8") as f:
json.dump(translations, f, indent=4, ensure_ascii=False, sort_keys=True)
print(f"Wrote {len(translations)} Japanese translations to {os.path.abspath(out)}")
+646
View File
@@ -0,0 +1,646 @@
#!/usr/bin/env python3
"""Generate Korean (ko) translations for ObsidianDragon wallet."""
import json, os
translations = {
"24h_change": "24시간 변동",
"24h_volume": "24시간 거래량",
"about": "정보",
"about_block_explorer": "블록 탐색기",
"about_block_height": "블록 높이:",
"about_build_date": "빌드 날짜:",
"about_build_type": "빌드 유형:",
"about_chain": "체인:",
"about_connections": "연결:",
"about_credits": "크레딧",
"about_daemon": "데몬:",
"about_debug": "디버그",
"about_dragonx": "ObsidianDragon 정보",
"about_edition": "ImGui 에디션",
"about_github": "GitHub",
"about_imgui": "ImGui:",
"about_license": "라이선스",
"about_license_text": "본 소프트웨어는 GNU General Public License v3 (GPLv3) 하에 배포됩니다. 라이선스 조건에 따라 자유롭게 사용, 수정 및 배포할 수 있습니다.",
"about_peers_count": "%zu 피어",
"about_release": "릴리스",
"about_title": "ObsidianDragon 정보",
"about_version": "버전:",
"about_website": "웹사이트",
"acrylic": "아크릴",
"add": "추가",
"address": "주소",
"address_book_add": "주소 추가",
"address_book_add_new": "새로 추가",
"address_book_added": "주소록에 주소를 추가했습니다",
"address_book_count": "저장된 주소 %zu개",
"address_book_deleted": "항목이 삭제되었습니다",
"address_book_edit": "주소 편집",
"address_book_empty": "저장된 주소가 없습니다. '새로 추가'를 클릭하여 추가하세요.",
"address_book_exists": "주소가 이미 주소록에 있습니다",
"address_book_title": "주소록",
"address_book_update_failed": "업데이트 실패 — 주소가 중복될 수 있습니다",
"address_book_updated": "주소가 업데이트되었습니다",
"address_copied": "주소가 클립보드에 복사되었습니다",
"address_details": "주소 상세",
"address_label": "주소:",
"address_upper": "주소",
"address_url": "주소 URL",
"addresses_appear_here": "연결 후 수신 주소가 여기에 표시됩니다.",
"advanced": "고급 설정",
"all_filter": "전체",
"allow_custom_fees": "사용자 정의 수수료 허용",
"amount": "금액",
"amount_details": "금액 상세",
"amount_exceeds_balance": "금액이 잔액을 초과합니다",
"amount_label": "금액:",
"appearance": "외관",
"auto_shield": "채굴 자동 차폐",
"available": "사용 가능",
"backup_backing_up": "백업 중...",
"backup_create": "백업 생성",
"backup_created": "지갑 백업이 생성되었습니다",
"backup_data": "백업 및 데이터",
"backup_description": "wallet.dat 파일의 백업을 생성합니다. 이 파일에는 모든 개인 키와 거래 내역이 포함되어 있습니다. 백업을 안전한 곳에 보관하세요.",
"backup_destination": "백업 위치:",
"backup_tip_external": "외장 드라이브 또는 클라우드 스토리지에 백업 저장",
"backup_tip_multiple": "서로 다른 위치에 여러 백업 생성",
"backup_tip_test": "정기적으로 백업 복원 테스트",
"backup_tips": "팁:",
"backup_title": "지갑 백업",
"backup_wallet": "지갑 백업...",
"backup_wallet_not_found": "경고: 예상 위치에서 wallet.dat를 찾을 수 없습니다",
"balance": "잔액",
"balance_layout": "잔액 레이아웃",
"ban": "차단",
"banned_peers": "차단된 피어",
"block": "블록",
"block_bits": "비트:",
"block_click_next": "클릭하여 다음 블록 보기",
"block_click_prev": "클릭하여 이전 블록 보기",
"block_explorer": "블록 탐색기",
"block_get_info": "블록 정보 조회",
"block_hash": "블록 해시:",
"block_height": "블록 높이:",
"block_info_title": "블록 정보",
"block_merkle_root": "머클 루트:",
"block_nav_next": "다음 >>",
"block_nav_prev": "<< 이전",
"block_next": "다음 블록:",
"block_previous": "이전 블록:",
"block_size": "크기:",
"block_timestamp": "타임스탬프:",
"block_transactions": "트랜잭션:",
"blockchain_syncing": "블록체인 동기화 중 (%.1f%%)... 잔액이 정확하지 않을 수 있습니다.",
"cancel": "취소",
"characters": "문자",
"clear": "지우기",
"clear_all_bans": "모든 차단 해제",
"clear_form_confirm": "모든 양식 필드를 지우시겠습니까?",
"clear_request": "요청 지우기",
"click_copy_address": "클릭하여 주소 복사",
"click_copy_uri": "클릭하여 URI 복사",
"close": "닫기",
"conf_count": "%d 확인",
"confirm_and_send": "확인 후 전송",
"confirm_send": "전송 확인",
"confirm_transaction": "거래 확인",
"confirmations": "확인 수",
"confirmations_display": "%d 확인 | %s",
"confirmed": "확인됨",
"connected": "연결됨",
"connected_peers": "연결된 피어",
"connecting": "연결 중...",
"console": "콘솔",
"console_auto_scroll": "자동 스크롤",
"console_available_commands": "사용 가능한 명령어:",
"console_capturing_output": "데몬 출력 캡처 중...",
"console_clear": "지우기",
"console_clear_console": "콘솔 지우기",
"console_cleared": "콘솔이 지워졌습니다",
"console_click_commands": "위의 명령어를 클릭하여 삽입",
"console_click_insert": "클릭하여 삽입",
"console_click_insert_params": "클릭하여 매개변수와 함께 삽입",
"console_close": "닫기",
"console_commands": "명령어",
"console_common_rpc": "일반 RPC 명령어:",
"console_completions": "자동 완성:",
"console_connected": "데몬에 연결됨",
"console_copy_all": "모두 복사",
"console_copy_selected": "복사",
"console_daemon": "데몬",
"console_daemon_error": "데몬 오류!",
"console_daemon_started": "데몬이 시작되었습니다",
"console_daemon_stopped": "데몬이 중지되었습니다",
"console_disconnected": "데몬 연결이 끊어졌습니다",
"console_errors": "오류",
"console_filter_hint": "출력 필터...",
"console_help_clear": " clear - 콘솔 지우기",
"console_help_getbalance": " getbalance - 투명 잔액 표시",
"console_help_getblockcount": " getblockcount - 현재 블록 높이 표시",
"console_help_getinfo": " getinfo - 노드 정보 표시",
"console_help_getmininginfo": " getmininginfo - 채굴 상태 표시",
"console_help_getpeerinfo": " getpeerinfo - 연결된 피어 표시",
"console_help_gettotalbalance": " gettotalbalance - 총 잔액 표시",
"console_help_help": " help - 도움말 표시",
"console_help_setgenerate": " setgenerate - 채굴 제어",
"console_help_stop": " stop - 데몬 중지",
"console_line_count": "%zu줄",
"console_new_lines": "%d 새 줄",
"console_no_daemon": "데몬 없음",
"console_not_connected": "오류: 데몬에 연결되지 않았습니다",
"console_rpc_reference": "RPC 명령어 참조",
"console_scanline": "콘솔 스캔라인",
"console_search_commands": "명령어 검색...",
"console_select_all": "모두 선택",
"console_show_daemon_output": "데몬 출력 표시",
"console_show_errors_only": "오류만 표시",
"console_show_rpc_ref": "RPC 명령어 참조 표시",
"console_showing_lines": "%zu / %zu줄 표시 중",
"console_starting_node": "노드 시작 중...",
"console_status_error": "오류",
"console_status_running": "실행 중",
"console_status_starting": "시작 중",
"console_status_stopped": "중지됨",
"console_status_stopping": "중지 중",
"console_status_unknown": "알 수 없음",
"console_tab_completion": "Tab으로 자동 완성",
"console_type_help": "'help'를 입력하여 사용 가능한 명령어 보기",
"console_welcome": "ObsidianDragon 콘솔에 오신 것을 환영합니다",
"console_zoom_in": "확대",
"console_zoom_out": "축소",
"copy": "복사",
"copy_address": "전체 주소 복사",
"copy_error": "오류 복사",
"copy_to_clipboard": "클립보드에 복사",
"copy_txid": "TxID 복사",
"copy_uri": "URI 복사",
"current_price": "현재 가격",
"custom_fees": "사용자 정의 수수료",
"dark": "다크",
"date": "날짜",
"date_label": "날짜:",
"delete": "삭제",
"difficulty": "난이도",
"disconnected": "연결 끊김",
"dismiss": "닫기",
"display": "디스플레이",
"dragonx_green": "DragonX(그린)",
"edit": "편집",
"error": "오류",
"est_time_to_block": "예상 블록 시간",
"exit": "종료",
"explorer": "탐색기",
"export": "내보내기",
"export_csv": "CSV 내보내기",
"export_keys_btn": "키 내보내기",
"export_keys_danger": "위험: 지갑의 모든 개인 키가 내보내집니다! 이 파일에 접근할 수 있는 사람은 누구나 자금을 훔칠 수 있습니다. 안전하게 보관하고 사용 후 삭제하세요.",
"export_keys_include_t": "T 주소 포함 (투명)",
"export_keys_include_z": "Z 주소 포함 (차폐)",
"export_keys_options": "내보내기 옵션:",
"export_keys_success": "키 내보내기 성공",
"export_keys_title": "모든 개인 키 내보내기",
"export_private_key": "개인 키 내보내기",
"export_tx_count": "%zu건의 거래를 CSV 파일로 내보냈습니다.",
"export_tx_file_fail": "CSV 파일 생성 실패",
"export_tx_none": "내보낼 거래가 없습니다",
"export_tx_success": "거래 내보내기 성공",
"export_tx_title": "거래를 CSV로 내보내기",
"export_viewing_key": "조회 키 내보내기",
"failed_create_shielded": "차폐 주소 생성 실패",
"failed_create_transparent": "투명 주소 생성 실패",
"fee": "수수료",
"fee_high": "높음",
"fee_label": "수수료:",
"fee_low": "낮음",
"fee_normal": "보통",
"fetch_prices": "가격 조회",
"file": "파일",
"file_save_location": "파일 저장 위치: ~/.config/ObsidianDragon/",
"font_scale": "글꼴 크기",
"from": "보낸 곳",
"from_upper": "보낸 곳",
"full_details": "전체 세부 정보",
"general": "일반",
"go_to_receive": "수신으로 이동",
"height": "높이",
"help": "도움말",
"hide": "숨기기",
"history": "내역",
"immature_type": "미성숙",
"import": "가져오기",
"import_key_btn": "키 가져오기",
"import_key_formats": "지원되는 키 형식:",
"import_key_full_rescan": "(0 = 전체 재스캔)",
"import_key_label": "개인 키:",
"import_key_no_valid": "입력에서 유효한 키를 찾을 수 없습니다",
"import_key_rescan": "가져오기 후 블록체인 재스캔",
"import_key_start_height": "시작 높이:",
"import_key_success": "키 가져오기 성공",
"import_key_t_format": "T 주소 WIF 개인 키",
"import_key_title": "개인 키 가져오기",
"import_key_tooltip": "한 줄에 하나의 개인 키를 입력하세요.\nz 주소와 t 주소 키 모두 지원됩니다.\n#으로 시작하는 줄은 주석으로 처리됩니다.",
"import_key_warning": "경고: 개인 키를 절대 공유하지 마세요! 신뢰할 수 없는 소스의 키를 가져오면 지갑이 위험해질 수 있습니다.",
"import_key_z_format": "Z 주소 지출 키 (secret-extended-key-...)",
"import_private_key": "개인 키 가져오기...",
"invalid_address": "잘못된 주소 형식",
"ip_address": "IP 주소",
"keep": "유지",
"keep_daemon": "데몬 계속 실행",
"key_export_fetching": "지갑에서 키를 가져오는 중...",
"key_export_private_key": "개인 키:",
"key_export_private_warning": "이 키를 비밀로 유지하세요! 이 키를 가진 사람은 누구나 자금을 사용할 수 있습니다. 온라인이나 신뢰할 수 없는 사람과 공유하지 마세요.",
"key_export_reveal": "키 표시",
"key_export_viewing_key": "조회 키:",
"key_export_viewing_warning": "이 조회 키를 사용하면 다른 사람이 수신 거래와 잔액을 볼 수 있지만 자금을 사용할 수는 없습니다. 신뢰할 수 있는 사람에게만 공유하세요.",
"label": "라벨:",
"language": "언어",
"light": "라이트",
"loading": "로딩 중...",
"loading_addresses": "주소 로딩 중...",
"local_hashrate": "로컬 해시레이트",
"low_spec_mode": "저사양 모드",
"market": "시장",
"market_12h": "12시간",
"market_18h": "18시간",
"market_24h": "24시간",
"market_24h_volume": "24시간 거래량",
"market_6h": "6시간",
"market_attribution": "가격 데이터: NonKYC 제공",
"market_btc_price": "BTC 가격",
"market_cap": "시가총액",
"market_no_history": "가격 내역 없음",
"market_no_price": "가격 데이터 없음",
"market_now": "현재",
"market_pct_shielded": "%.0f%% 차폐됨",
"market_portfolio": "포트폴리오",
"market_price_unavailable": "가격 데이터를 사용할 수 없습니다",
"market_refresh_price": "가격 데이터 새로고침",
"market_trade_on": "%s에서 거래",
"mature": "성숙됨",
"max": "최대",
"memo": "메모 (선택, 암호화)",
"memo_label": "메모:",
"memo_optional": "메모 (선택)",
"memo_upper": "메모",
"memo_z_only": "참고: 메모는 차폐 (z) 주소로 전송할 때만 사용할 수 있습니다",
"merge_description": "여러 UTXO를 단일 차폐 주소로 통합합니다. 지갑 크기를 줄이고 프라이버시를 향상시킵니다.",
"merge_funds": "자금 통합",
"merge_started": "통합 작업이 시작되었습니다",
"merge_title": "주소로 통합",
"mine_when_idle": "유휴 시 채굴",
"mined": "채굴됨",
"mined_filter": "채굴됨",
"mined_type": "채굴됨",
"mined_upper": "채굴됨",
"miner_fee": "채굴 수수료",
"mining": "채굴",
"mining_active": "활성",
"mining_address_copied": "채굴 주소가 복사되었습니다",
"mining_all_time": "전체 기간",
"mining_already_saved": "풀 URL이 이미 저장되어 있습니다",
"mining_block_copied": "블록 해시가 복사되었습니다",
"mining_chart_1m_ago": "1분 전",
"mining_chart_5m_ago": "5분 전",
"mining_chart_now": "현재",
"mining_chart_start": "시작",
"mining_click": "클릭",
"mining_click_copy_address": "클릭하여 주소 복사",
"mining_click_copy_block": "클릭하여 블록 해시 복사",
"mining_click_copy_difficulty": "클릭하여 난이도 복사",
"mining_connected": "연결됨",
"mining_connecting": "연결 중...",
"mining_control": "채굴 제어",
"mining_difficulty_copied": "난이도가 복사되었습니다",
"mining_est_block": "예상 블록",
"mining_est_daily": "예상 일일 수익",
"mining_filter_all": "전체",
"mining_filter_tip_all": "모든 수익 표시",
"mining_filter_tip_pool": "풀 수익만 표시",
"mining_filter_tip_solo": "솔로 수익만 표시",
"mining_idle_off_tooltip": "유휴 채굴 활성화",
"mining_idle_on_tooltip": "유휴 채굴 비활성화",
"mining_local_hashrate": "로컬 해시레이트",
"mining_mine": "채굴",
"mining_mining_addr": "채굴 주소",
"mining_network": "네트워크",
"mining_no_blocks_yet": "아직 블록을 찾지 못했습니다",
"mining_no_payouts_yet": "아직 풀 지급이 없습니다",
"mining_no_saved_addresses": "저장된 주소 없음",
"mining_no_saved_pools": "저장된 풀 없음",
"mining_off": "채굴이 꺼져 있습니다",
"mining_on": "채굴이 켜져 있습니다",
"mining_open_in_explorer": "탐색기에서 열기",
"mining_payout_address": "지급 주소",
"mining_payout_tooltip": "채굴 보상 수신 주소",
"mining_pool": "풀",
"mining_pool_hashrate": "풀 해시레이트",
"mining_pool_url": "풀 URL",
"mining_recent_blocks": "최근 블록",
"mining_recent_payouts": "최근 풀 지급",
"mining_remove": "제거",
"mining_reset_defaults": "기본값으로 재설정",
"mining_save_payout_address": "지급 주소 저장",
"mining_save_pool_url": "풀 URL 저장",
"mining_saved_addresses": "저장된 주소:",
"mining_saved_pools": "저장된 풀:",
"mining_shares": "셰어",
"mining_show_chart": "차트",
"mining_show_log": "로그",
"mining_solo": "솔로",
"mining_starting": "시작 중...",
"mining_starting_tooltip": "채굴기 시작 중...",
"mining_statistics": "채굴 통계",
"mining_stop": "중지",
"mining_stop_solo_for_pool": "풀 채굴을 시작하려면 솔로 채굴을 먼저 중지하세요",
"mining_stop_solo_for_pool_settings": "풀 설정을 변경하려면 솔로 채굴을 중지하세요",
"mining_stopping": "중지 중...",
"mining_stopping_tooltip": "채굴기 중지 중...",
"mining_syncing_tooltip": "블록체인 동기화 중...",
"mining_threads": "채굴 스레드",
"mining_to_save": "저장하려면",
"mining_today": "오늘",
"mining_uptime": "가동 시간",
"mining_yesterday": "어제",
"network": "네트워크",
"network_fee": "네트워크 수수료",
"network_hashrate": "네트워크 해시레이트",
"new": "+ 새로 만들기",
"new_shielded_created": "새 차폐 주소가 생성되었습니다",
"new_t_address": "새 T 주소",
"new_t_transparent": "새 t 주소 (투명)",
"new_transparent_created": "새 투명 주소가 생성되었습니다",
"new_z_address": "새 Z 주소",
"new_z_shielded": "새 z 주소 (차폐)",
"no_addresses": "주소가 없습니다. 위의 버튼을 사용하여 생성하세요.",
"no_addresses_available": "사용 가능한 주소 없음",
"no_addresses_match": "필터와 일치하는 주소가 없습니다",
"no_addresses_with_balance": "잔액이 있는 주소가 없습니다",
"no_matching": "일치하는 거래가 없습니다",
"no_recent_receives": "최근 수신 내역 없음",
"no_recent_sends": "최근 전송 내역 없음",
"no_transactions": "거래 내역이 없습니다",
"node": "노드",
"node_security": "노드 및 보안",
"noise": "노이즈",
"not_connected": "데몬에 연결되지 않음...",
"not_connected_to_daemon": "데몬에 연결되지 않음",
"notes": "메모",
"notes_optional": "메모 (선택):",
"output_filename": "출력 파일명:",
"overview": "개요",
"paste": "붙여넣기",
"paste_from_clipboard": "클립보드에서 붙여넣기",
"pay_from": "보낼 곳",
"payment_request": "결제 요청",
"payment_request_copied": "결제 요청이 복사되었습니다",
"payment_uri_copied": "결제 URI가 복사되었습니다",
"peers": "피어",
"peers_avg_ping": "평균 Ping",
"peers_ban_24h": "피어 24시간 차단",
"peers_ban_score": "차단 점수: %d",
"peers_banned": "차단됨",
"peers_banned_count": "차단됨: %d",
"peers_best_block": "최고 블록",
"peers_blockchain": "블록체인",
"peers_blocks": "블록",
"peers_blocks_left": "남은 블록: %d",
"peers_clear_all_bans": "모든 차단 해제",
"peers_click_copy": "클릭하여 복사",
"peers_connected": "연결됨",
"peers_connected_count": "연결됨: %d",
"peers_copy_ip": "IP 복사",
"peers_dir_in": "수신",
"peers_dir_out": "송신",
"peers_hash_copied": "해시가 복사되었습니다",
"peers_hashrate": "해시레이트",
"peers_in_out": "수신/송신",
"peers_longest": "최장",
"peers_longest_chain": "최장 체인",
"peers_memory": "메모리",
"peers_no_banned": "차단된 피어 없음",
"peers_no_connected": "연결된 피어 없음",
"peers_no_tls": "TLS 없음",
"peers_notarized": "공증됨",
"peers_p2p_port": "P2P 포트",
"peers_protocol": "프로토콜",
"peers_received": "수신됨",
"peers_refresh": "새로고침",
"peers_refresh_tooltip": "피어 목록 새로고침",
"peers_refreshing": "새로고침 중...",
"peers_sent": "전송됨",
"peers_tt_id": "ID: %d",
"peers_tt_received": "수신: %s",
"peers_tt_sent": "전송: %s",
"peers_tt_services": "서비스: %s",
"peers_tt_start_height": "시작 높이: %d",
"peers_tt_synced": "동기화 H/B: %d/%d",
"peers_tt_tls_cipher": "TLS: %s",
"peers_unban": "차단 해제",
"peers_upper": "피어",
"peers_version": "버전",
"pending": "대기 중",
"ping": "Ping",
"price_chart": "가격 차트",
"qr_code": "QR 코드",
"qr_failed": "QR 코드 생성 실패",
"qr_title": "QR 코드",
"qr_unavailable": "QR 사용 불가",
"receive": "수신",
"received": "수신됨",
"received_filter": "수신됨",
"received_label": "수신됨",
"received_upper": "수신됨",
"receiving_addresses": "수신 주소",
"recent_received": "최근 수신",
"recent_sends": "최근 전송",
"recipient": "수신자",
"recv_type": "수신",
"refresh": "새로고침",
"refresh_now": "지금 새로고침",
"report_bug": "버그 신고",
"request_amount": "금액 (선택):",
"request_copy_uri": "URI 복사",
"request_description": "다른 사람이 스캔하거나 복사할 수 있는 결제 요청을 생성합니다. QR 코드에는 주소와 선택적 금액/메모가 포함됩니다.",
"request_label": "라벨 (선택):",
"request_memo": "메모 (선택):",
"request_payment": "결제 요청",
"request_payment_uri": "결제 URI:",
"request_receive_address": "수신 주소:",
"request_select_address": "주소 선택...",
"request_shielded_addrs": "-- 차폐 주소 --",
"request_title": "결제 요청",
"request_transparent_addrs": "-- 투명 주소 --",
"request_uri_copied": "결제 URI가 클립보드에 복사되었습니다",
"rescan": "재스캔",
"reset_to_defaults": "기본값으로 재설정",
"review_send": "전송 검토",
"rpc_host": "RPC 호스트",
"rpc_pass": "비밀번호",
"rpc_port": "포트",
"rpc_user": "사용자명",
"save": "저장",
"save_settings": "설정 저장",
"save_z_transactions": "Z 거래를 거래 목록에 저장",
"search_placeholder": "검색...",
"security": "보안",
"select_address": "주소 선택...",
"select_receiving_address": "수신 주소 선택...",
"select_source_address": "보낼 주소 선택...",
"send": "전송",
"send_amount": "금액",
"send_amount_details": "금액 상세",
"send_amount_upper": "금액",
"send_clear_fields": "모든 양식 필드를 지우시겠습니까?",
"send_copy_error": "오류 복사",
"send_dismiss": "닫기",
"send_error_copied": "오류가 클립보드에 복사되었습니다",
"send_error_prefix": "오류: %s",
"send_exceeds_available": "사용 가능 금액 초과 (%.8f)",
"send_fee": "수수료",
"send_fee_high": "높음",
"send_fee_low": "낮음",
"send_fee_normal": "보통",
"send_form_restored": "양식이 복원되었습니다",
"send_from_this_address": "이 주소에서 전송",
"send_go_to_receive": "수신으로 이동",
"send_keep": "유지",
"send_network_fee": "네트워크 수수료",
"send_no_balance": "잔액 없음",
"send_no_recent": "최근 전송 없음",
"send_recent_sends": "최근 전송",
"send_recipient": "수신자",
"send_select_source": "보낼 주소 선택...",
"send_sending_from": "보내는 곳",
"send_submitting": "거래 제출 중...",
"send_switch_to_receive": "수신으로 전환하여 주소를 받고 자금 수신을 시작하세요.",
"send_to": "받는 곳",
"send_tooltip_enter_amount": "전송할 금액을 입력하세요",
"send_tooltip_exceeds_balance": "금액이 사용 가능 잔액을 초과합니다",
"send_tooltip_in_progress": "거래가 이미 진행 중입니다",
"send_tooltip_invalid_address": "유효한 수신자 주소를 입력하세요",
"send_tooltip_not_connected": "데몬에 연결되지 않음",
"send_tooltip_select_source": "먼저 보낼 주소를 선택하세요",
"send_tooltip_syncing": "블록체인 동기화를 기다려 주세요",
"send_total": "합계",
"send_transaction": "거래 전송",
"send_tx_failed": "거래 실패",
"send_tx_sent": "거래가 전송되었습니다!",
"send_tx_success": "거래 전송 성공!",
"send_txid_copied": "TxID가 클립보드에 복사되었습니다",
"send_txid_label": "TxID: %s",
"send_valid_shielded": "유효한 차폐 주소",
"send_valid_transparent": "유효한 투명 주소",
"send_wallet_empty": "지갑이 비어 있습니다",
"send_yes_clear": "예, 지우기",
"sending": "거래 전송 중",
"sending_from": "보내는 곳",
"sent": "전송됨",
"sent_filter": "전송됨",
"sent_type": "전송됨",
"sent_upper": "전송됨",
"settings": "설정",
"setup_wizard": "설정 마법사",
"share": "공유",
"shield_check_status": "상태 확인",
"shield_completed": "작업이 성공적으로 완료되었습니다!",
"shield_description": "투명 주소의 코인베이스 출력을 차폐 주소로 전송하여 채굴 보상을 차폐합니다. 채굴 수입을 숨겨 프라이버시가 향상됩니다.",
"shield_from_address": "보내는 주소:",
"shield_funds": "자금 차폐",
"shield_in_progress": "작업 진행 중...",
"shield_max_utxos": "작업당 최대 UTXO 수",
"shield_merge_done": "차폐/통합이 완료되었습니다!",
"shield_select_z": "z 주소 선택...",
"shield_started": "차폐 작업이 시작되었습니다",
"shield_title": "코인베이스 보상 차폐",
"shield_to_address": "받는 주소 (차폐):",
"shield_utxo_limit": "UTXO 제한:",
"shield_wildcard_hint": "'*'를 사용하여 모든 투명 주소에서 차폐",
"shielded": "차폐",
"shielded_to": "차폐 대상",
"shielded_type": "차폐",
"show": "표시",
"show_qr_code": "QR 코드 표시",
"showing_transactions": "%d\xe2\x80\x93%d / %d건의 거래 표시 중 (총: %zu)",
"simple_background": "단순 배경",
"start_mining": "채굴 시작",
"status": "상태",
"stop_external": "외부 데몬 중지",
"stop_mining": "채굴 중지",
"submitting_transaction": "거래 제출 중...",
"success": "성공",
"summary": "요약",
"syncing": "동기화 중...",
"t_addresses": "T 주소",
"test_connection": "테스트",
"theme": "테마",
"theme_effects": "테마 효과",
"time_days_ago": "%d일 전",
"time_hours_ago": "%d시간 전",
"time_minutes_ago": "%d분 전",
"time_seconds_ago": "%d초 전",
"to": "받는 곳",
"to_upper": "받는 곳",
"tools": "도구",
"total": "합계",
"transaction_id": "거래 ID",
"transaction_sent": "거래 전송 성공",
"transaction_sent_msg": "거래가 전송되었습니다!",
"transaction_url": "거래 URL",
"transactions": "거래",
"transactions_upper": "거래",
"transparent": "투명",
"tx_confirmations": "%d 확인",
"tx_details_title": "거래 상세",
"tx_from_address": "보낸 주소:",
"tx_id_label": "거래 ID:",
"tx_immature": "미성숙",
"tx_mined": "채굴됨",
"tx_received": "수신됨",
"tx_sent": "전송됨",
"tx_to_address": "받는 주소:",
"tx_view_explorer": "탐색기에서 보기",
"txs_count": "%d건",
"type": "유형",
"ui_opacity": "UI 투명도",
"unban": "차단 해제",
"unconfirmed": "미확인",
"undo_clear": "지우기 취소",
"unknown": "알 수 없음",
"use_embedded_daemon": "내장 dragonxd 사용",
"use_tor": "Tor 사용",
"validate_btn": "검증",
"validate_description": "DragonX 주소를 입력하여 유효한지 그리고 이 지갑에 속하는지 확인합니다.",
"validate_invalid": "유효하지 않음",
"validate_is_mine": "이 지갑이 이 주소를 소유합니다",
"validate_not_mine": "이 지갑에 속하지 않음",
"validate_ownership": "소유자:",
"validate_results": "결과:",
"validate_shielded_type": "차폐 (z 주소)",
"validate_status": "상태:",
"validate_title": "주소 검증",
"validate_transparent_type": "투명 (t 주소)",
"validate_type": "유형:",
"validate_valid": "유효함",
"validating": "검증 중...",
"verbose_logging": "상세 로깅",
"version": "버전",
"view": "보기",
"view_details": "상세 보기",
"view_on_explorer": "탐색기에서 보기",
"waiting_for_daemon": "데몬 연결 대기 중...",
"wallet": "지갑",
"wallet_empty": "지갑이 비어 있습니다",
"wallet_empty_hint": "수신으로 전환하여 주소를 받고 자금 수신을 시작하세요.",
"warning": "경고",
"warning_upper": "경고!",
"website": "웹사이트",
"window_opacity": "창 투명도",
"yes_clear": "예, 지우기",
"your_addresses": "내 주소",
"z_addresses": "Z 주소",
}
out = os.path.join(os.path.dirname(__file__), "..", "res", "lang", "ko.json")
with open(out, "w", encoding="utf-8") as f:
json.dump(translations, f, indent=4, ensure_ascii=False, sort_keys=True)
print(f"Wrote {len(translations)} Korean translations to {os.path.abspath(out)}")
+646
View File
@@ -0,0 +1,646 @@
#!/usr/bin/env python3
"""Generate Portuguese (pt) translations for ObsidianDragon wallet."""
import json, os
translations = {
"24h_change": "Variação 24h",
"24h_volume": "Volume 24h",
"about": "Sobre",
"about_block_explorer": "Explorador de Blocos",
"about_block_height": "Altura do Bloco:",
"about_build_date": "Data de Compilação:",
"about_build_type": "Tipo de Build:",
"about_chain": "Chain:",
"about_connections": "Conexões:",
"about_credits": "Créditos",
"about_daemon": "Daemon:",
"about_debug": "Depuração",
"about_dragonx": "Sobre o ObsidianDragon",
"about_edition": "Edição ImGui",
"about_github": "GitHub",
"about_imgui": "ImGui:",
"about_license": "Licença",
"about_license_text": "Este software é disponibilizado sob a Licença Pública Geral GNU v3 (GPLv3). Você é livre para usar, modificar e distribuir este software sob os termos da licença.",
"about_peers_count": "%zu pares",
"about_release": "Versão",
"about_title": "Sobre o ObsidianDragon",
"about_version": "Versão:",
"about_website": "Website",
"acrylic": "Acrílico",
"add": "Adicionar",
"address": "Endereço",
"address_book_add": "Adicionar Endereço",
"address_book_add_new": "Adicionar Novo",
"address_book_added": "Endereço adicionado ao livro",
"address_book_count": "%zu endereços salvos",
"address_book_deleted": "Entrada excluída",
"address_book_edit": "Editar Endereço",
"address_book_empty": "Nenhum endereço salvo. Clique em 'Adicionar Novo' para criar um.",
"address_book_exists": "Endereço já existe no livro",
"address_book_title": "Livro de Endereços",
"address_book_update_failed": "Falha na atualização - endereço pode ser duplicado",
"address_book_updated": "Endereço atualizado",
"address_copied": "Endereço copiado para a área de transferência",
"address_details": "Detalhes do Endereço",
"address_label": "Endereço:",
"address_upper": "ENDEREÇO",
"address_url": "URL do Endereço",
"addresses_appear_here": "Seus endereços de recebimento aparecerão aqui após a conexão.",
"advanced": "AVANÇADO",
"all_filter": "Todos",
"allow_custom_fees": "Permitir taxas personalizadas",
"amount": "Valor",
"amount_details": "DETALHES DO VALOR",
"amount_exceeds_balance": "Valor excede o saldo",
"amount_label": "Valor:",
"appearance": "APARÊNCIA",
"auto_shield": "Auto-blindar mineração",
"available": "Disponível",
"backup_backing_up": "Fazendo backup...",
"backup_create": "Criar Backup",
"backup_created": "Backup da carteira criado",
"backup_data": "BACKUP & DADOS",
"backup_description": "Crie um backup do seu arquivo wallet.dat. Este arquivo contém todas as suas chaves privadas e histórico de transações. Guarde o backup em um local seguro.",
"backup_destination": "Destino do backup:",
"backup_tip_external": "Armazene backups em unidades externas ou armazenamento em nuvem",
"backup_tip_multiple": "Crie múltiplos backups em diferentes locais",
"backup_tip_test": "Teste a restauração do backup periodicamente",
"backup_tips": "Dicas:",
"backup_title": "Backup da Carteira",
"backup_wallet": "Fazer Backup da Carteira...",
"backup_wallet_not_found": "Aviso: wallet.dat não encontrado no local esperado",
"balance": "Saldo",
"balance_layout": "Layout do Saldo",
"ban": "Banir",
"banned_peers": "Pares Banidos",
"block": "Bloco",
"block_bits": "Bits:",
"block_click_next": "Clique para ver o próximo bloco",
"block_click_prev": "Clique para ver o bloco anterior",
"block_explorer": "Explorador de Blocos",
"block_get_info": "Obter Info do Bloco",
"block_hash": "Hash do Bloco:",
"block_height": "Altura do Bloco:",
"block_info_title": "Informações do Bloco",
"block_merkle_root": "Raiz Merkle:",
"block_nav_next": "Próximo >>",
"block_nav_prev": "<< Anterior",
"block_next": "Próximo Bloco:",
"block_previous": "Bloco Anterior:",
"block_size": "Tamanho:",
"block_timestamp": "Carimbo de Data:",
"block_transactions": "Transações:",
"blockchain_syncing": "Blockchain sincronizando (%.1f%%)... Os saldos podem ser imprecisos.",
"cancel": "Cancelar",
"characters": "caracteres",
"clear": "Limpar",
"clear_all_bans": "Remover Todos os Banimentos",
"clear_form_confirm": "Limpar todos os campos do formulário?",
"clear_request": "Limpar Solicitação",
"click_copy_address": "Clique para copiar o endereço",
"click_copy_uri": "Clique para copiar a URI",
"close": "Fechar",
"conf_count": "%d conf.",
"confirm_and_send": "Confirmar & Enviar",
"confirm_send": "Confirmar Envio",
"confirm_transaction": "Confirmar Transação",
"confirmations": "Confirmações",
"confirmations_display": "%d confirmações | %s",
"confirmed": "Confirmado",
"connected": "Conectado",
"connected_peers": "Pares Conectados",
"connecting": "Conectando...",
"console": "Console",
"console_auto_scroll": "Rolagem automática",
"console_available_commands": "Comandos disponíveis:",
"console_capturing_output": "Capturando saída do daemon...",
"console_clear": "Limpar",
"console_clear_console": "Limpar Console",
"console_cleared": "Console limpo",
"console_click_commands": "Clique nos comandos acima para inseri-los",
"console_click_insert": "Clique para inserir",
"console_click_insert_params": "Clique para inserir com parâmetros",
"console_close": "Fechar",
"console_commands": "Comandos",
"console_common_rpc": "Comandos RPC comuns:",
"console_completions": "Completações:",
"console_connected": "Conectado ao daemon",
"console_copy_all": "Copiar Tudo",
"console_copy_selected": "Copiar",
"console_daemon": "Daemon",
"console_daemon_error": "Erro do daemon!",
"console_daemon_started": "Daemon iniciado",
"console_daemon_stopped": "Daemon parado",
"console_disconnected": "Desconectado do daemon",
"console_errors": "Erros",
"console_filter_hint": "Filtrar saída...",
"console_help_clear": " clear - Limpar o console",
"console_help_getbalance": " getbalance - Mostrar saldo transparente",
"console_help_getblockcount": " getblockcount - Mostrar altura atual do bloco",
"console_help_getinfo": " getinfo - Mostrar informações do nó",
"console_help_getmininginfo": " getmininginfo - Mostrar status da mineração",
"console_help_getpeerinfo": " getpeerinfo - Mostrar pares conectados",
"console_help_gettotalbalance": " gettotalbalance - Mostrar saldo total",
"console_help_help": " help - Mostrar esta mensagem de ajuda",
"console_help_setgenerate": " setgenerate - Controlar mineração",
"console_help_stop": " stop - Parar o daemon",
"console_line_count": "%zu linhas",
"console_new_lines": "%d novas linhas",
"console_no_daemon": "Sem daemon",
"console_not_connected": "Erro: Não conectado ao daemon",
"console_rpc_reference": "Referência de Comandos RPC",
"console_scanline": "Scanline do console",
"console_search_commands": "Pesquisar comandos...",
"console_select_all": "Selecionar Tudo",
"console_show_daemon_output": "Mostrar saída do daemon",
"console_show_errors_only": "Mostrar apenas erros",
"console_show_rpc_ref": "Mostrar referência de comandos RPC",
"console_showing_lines": "Mostrando %zu de %zu linhas",
"console_starting_node": "Iniciando nó...",
"console_status_error": "Erro",
"console_status_running": "Em execução",
"console_status_starting": "Iniciando",
"console_status_stopped": "Parado",
"console_status_stopping": "Parando",
"console_status_unknown": "Desconhecido",
"console_tab_completion": "Tab para completar",
"console_type_help": "Digite 'help' para comandos disponíveis",
"console_welcome": "Bem-vindo ao Console ObsidianDragon",
"console_zoom_in": "Aumentar zoom",
"console_zoom_out": "Diminuir zoom",
"copy": "Copiar",
"copy_address": "Copiar Endereço Completo",
"copy_error": "Copiar Erro",
"copy_to_clipboard": "Copiar para Área de Transferência",
"copy_txid": "Copiar TxID",
"copy_uri": "Copiar URI",
"current_price": "Preço Atual",
"custom_fees": "Taxas personalizadas",
"dark": "Escuro",
"date": "Data",
"date_label": "Data:",
"delete": "Excluir",
"difficulty": "Dificuldade",
"disconnected": "Desconectado",
"dismiss": "Dispensar",
"display": "Exibição",
"dragonx_green": "DragonX (Verde)",
"edit": "Editar",
"error": "Erro",
"est_time_to_block": "Tempo Est. por Bloco",
"exit": "Sair",
"explorer": "EXPLORADOR",
"export": "Exportar",
"export_csv": "Exportar CSV",
"export_keys_btn": "Exportar Chaves",
"export_keys_danger": "PERIGO: Isto exportará TODAS as chaves privadas da sua carteira! Qualquer pessoa com acesso a este arquivo pode roubar seus fundos. Guarde com segurança e exclua após o uso.",
"export_keys_include_t": "Incluir endereços T (transparentes)",
"export_keys_include_z": "Incluir endereços Z (blindados)",
"export_keys_options": "Opções de exportação:",
"export_keys_success": "Chaves exportadas com sucesso",
"export_keys_title": "Exportar Todas as Chaves Privadas",
"export_private_key": "Exportar Chave Privada",
"export_tx_count": "Exportar %zu transações para arquivo CSV.",
"export_tx_file_fail": "Falha ao criar arquivo CSV",
"export_tx_none": "Nenhuma transação para exportar",
"export_tx_success": "Transações exportadas com sucesso",
"export_tx_title": "Exportar Transações para CSV",
"export_viewing_key": "Exportar Chave de Visualização",
"failed_create_shielded": "Falha ao criar endereço blindado",
"failed_create_transparent": "Falha ao criar endereço transparente",
"fee": "Taxa",
"fee_high": "Alta",
"fee_label": "Taxa:",
"fee_low": "Baixa",
"fee_normal": "Normal",
"fetch_prices": "Buscar preços",
"file": "Arquivo",
"file_save_location": "O arquivo será salvo em: ~/.config/ObsidianDragon/",
"font_scale": "Escala da Fonte",
"from": "De",
"from_upper": "DE",
"full_details": "Detalhes Completos",
"general": "Geral",
"go_to_receive": "Ir para Receber",
"height": "Altura",
"help": "Ajuda",
"hide": "Ocultar",
"history": "Histórico",
"immature_type": "Imaturo",
"import": "Importar",
"import_key_btn": "Importar Chave(s)",
"import_key_formats": "Formatos de chave suportados:",
"import_key_full_rescan": "(0 = rescan completo)",
"import_key_label": "Chave(s) Privada(s):",
"import_key_no_valid": "Nenhuma chave válida encontrada na entrada",
"import_key_rescan": "Reescanear blockchain após importação",
"import_key_start_height": "Altura inicial:",
"import_key_success": "Chaves importadas com sucesso",
"import_key_t_format": "Chaves privadas WIF de endereços T",
"import_key_title": "Importar Chave Privada",
"import_key_tooltip": "Digite uma ou mais chaves privadas, uma por linha.\nSuporta chaves de z-endereço e t-endereço.\nLinhas começando com # são tratadas como comentários.",
"import_key_warning": "Aviso: Nunca compartilhe suas chaves privadas! Importar chaves de fontes não confiáveis pode comprometer sua carteira.",
"import_key_z_format": "Chaves de gasto de z-endereço (secret-extended-key-...)",
"import_private_key": "Importar Chave Privada...",
"invalid_address": "Formato de endereço inválido",
"ip_address": "Endereço IP",
"keep": "Manter",
"keep_daemon": "Manter daemon em execução",
"key_export_fetching": "Buscando chave da carteira...",
"key_export_private_key": "Chave Privada:",
"key_export_private_warning": "Mantenha esta chave em SEGREDO! Qualquer pessoa com esta chave pode gastar seus fundos. Nunca a compartilhe online ou com terceiros não confiáveis.",
"key_export_reveal": "Revelar Chave",
"key_export_viewing_key": "Chave de Visualização:",
"key_export_viewing_warning": "Esta chave de visualização permite que outros vejam suas transações recebidas e saldo, mas NÃO gastem seus fundos. Compartilhe apenas com partes confiáveis.",
"label": "Rótulo:",
"language": "Idioma",
"light": "Claro",
"loading": "Carregando...",
"loading_addresses": "Carregando endereços...",
"local_hashrate": "Hashrate Local",
"low_spec_mode": "Modo econômico",
"market": "Mercado",
"market_12h": "12h",
"market_18h": "18h",
"market_24h": "24h",
"market_24h_volume": "VOLUME 24H",
"market_6h": "6h",
"market_attribution": "Dados de preço do NonKYC",
"market_btc_price": "PREÇO BTC",
"market_cap": "Capitalização",
"market_no_history": "Nenhum histórico de preços disponível",
"market_no_price": "Sem dados de preço",
"market_now": "Agora",
"market_pct_shielded": "%.0f%% Blindado",
"market_portfolio": "PORTFÓLIO",
"market_price_unavailable": "Dados de preço indisponíveis",
"market_refresh_price": "Atualizar dados de preço",
"market_trade_on": "Negociar no %s",
"mature": "Maduro",
"max": "Máx",
"memo": "Memo (opcional, criptografado)",
"memo_label": "Memo:",
"memo_optional": "MEMO (OPCIONAL)",
"memo_upper": "MEMO",
"memo_z_only": "Nota: Memos só estão disponíveis ao enviar para endereços blindados (z)",
"merge_description": "Fundir múltiplos UTXOs em um único endereço blindado. Isso pode ajudar a reduzir o tamanho da carteira e melhorar a privacidade.",
"merge_funds": "Fundir Fundos",
"merge_started": "Operação de fusão iniciada",
"merge_title": "Fundir para Endereço",
"mine_when_idle": "Minerar quando ocioso",
"mined": "minerado",
"mined_filter": "Minerado",
"mined_type": "Minerado",
"mined_upper": "MINERADO",
"miner_fee": "Taxa de Minerador",
"mining": "Mineração",
"mining_active": "Ativo",
"mining_address_copied": "Endereço de mineração copiado",
"mining_all_time": "Todo o Tempo",
"mining_already_saved": "URL do pool já salva",
"mining_block_copied": "Hash do bloco copiado",
"mining_chart_1m_ago": "1m atrás",
"mining_chart_5m_ago": "5m atrás",
"mining_chart_now": "Agora",
"mining_chart_start": "Início",
"mining_click": "Clique",
"mining_click_copy_address": "Clique para copiar o endereço",
"mining_click_copy_block": "Clique para copiar o hash do bloco",
"mining_click_copy_difficulty": "Clique para copiar a dificuldade",
"mining_connected": "Conectado",
"mining_connecting": "Conectando...",
"mining_control": "Controle de Mineração",
"mining_difficulty_copied": "Dificuldade copiada",
"mining_est_block": "Bloco Est.",
"mining_est_daily": "Est. Diário",
"mining_filter_all": "Todos",
"mining_filter_tip_all": "Mostrar todos os ganhos",
"mining_filter_tip_pool": "Mostrar apenas ganhos do pool",
"mining_filter_tip_solo": "Mostrar apenas ganhos solo",
"mining_idle_off_tooltip": "Ativar mineração ociosa",
"mining_idle_on_tooltip": "Desativar mineração ociosa",
"mining_local_hashrate": "Hashrate Local",
"mining_mine": "Minerar",
"mining_mining_addr": "End. Mineração",
"mining_network": "Rede",
"mining_no_blocks_yet": "Nenhum bloco encontrado ainda",
"mining_no_payouts_yet": "Nenhum pagamento de pool ainda",
"mining_no_saved_addresses": "Nenhum endereço salvo",
"mining_no_saved_pools": "Nenhum pool salvo",
"mining_off": "Mineração está DESLIGADA",
"mining_on": "Mineração está LIGADA",
"mining_open_in_explorer": "Abrir no explorador",
"mining_payout_address": "Endereço de Pagamento",
"mining_payout_tooltip": "Endereço para receber recompensas de mineração",
"mining_pool": "Pool",
"mining_pool_hashrate": "Hashrate do Pool",
"mining_pool_url": "URL do Pool",
"mining_recent_blocks": "BLOCOS RECENTES",
"mining_recent_payouts": "PAGAMENTOS DE POOL RECENTES",
"mining_remove": "Remover",
"mining_reset_defaults": "Redefinir Padrões",
"mining_save_payout_address": "Salvar endereço de pagamento",
"mining_save_pool_url": "Salvar URL do pool",
"mining_saved_addresses": "Endereços Salvos:",
"mining_saved_pools": "Pools Salvos:",
"mining_shares": "Shares",
"mining_show_chart": "Gráfico",
"mining_show_log": "Log",
"mining_solo": "Solo",
"mining_starting": "Iniciando...",
"mining_starting_tooltip": "Minerador está iniciando...",
"mining_statistics": "Estatísticas de Mineração",
"mining_stop": "Parar",
"mining_stop_solo_for_pool": "Pare a mineração solo antes de iniciar a mineração em pool",
"mining_stop_solo_for_pool_settings": "Pare a mineração solo para alterar as configurações do pool",
"mining_stopping": "Parando...",
"mining_stopping_tooltip": "Minerador está parando...",
"mining_syncing_tooltip": "Blockchain está sincronizando...",
"mining_threads": "Threads de Mineração",
"mining_to_save": "para salvar",
"mining_today": "Hoje",
"mining_uptime": "Tempo Ativo",
"mining_yesterday": "Ontem",
"network": "Rede",
"network_fee": "TAXA DA REDE",
"network_hashrate": "Hashrate da Rede",
"new": "+ Novo",
"new_shielded_created": "Novo endereço blindado criado",
"new_t_address": "Novo Endereço T",
"new_t_transparent": "Novo endereço t (Transparente)",
"new_transparent_created": "Novo endereço transparente criado",
"new_z_address": "Novo Endereço Z",
"new_z_shielded": "Novo endereço z (Blindado)",
"no_addresses": "Nenhum endereço encontrado. Crie um usando os botões acima.",
"no_addresses_available": "Nenhum endereço disponível",
"no_addresses_match": "Nenhum endereço corresponde ao filtro",
"no_addresses_with_balance": "Nenhum endereço com saldo",
"no_matching": "Nenhuma transação correspondente",
"no_recent_receives": "Nenhum recebimento recente",
"no_recent_sends": "Nenhum envio recente",
"no_transactions": "Nenhuma transação encontrada",
"node": "NÓ",
"node_security": "NÓ & SEGURANÇA",
"noise": "Ruído",
"not_connected": "Não conectado ao daemon...",
"not_connected_to_daemon": "Não conectado ao daemon",
"notes": "Notas",
"notes_optional": "Notas (opcional):",
"output_filename": "Nome do arquivo de saída:",
"overview": "Visão Geral",
"paste": "Colar",
"paste_from_clipboard": "Colar da Área de Transferência",
"pay_from": "Pagar de",
"payment_request": "SOLICITAÇÃO DE PAGAMENTO",
"payment_request_copied": "Solicitação de pagamento copiada",
"payment_uri_copied": "URI de pagamento copiada",
"peers": "Pares",
"peers_avg_ping": "Ping Médio",
"peers_ban_24h": "Banir Par 24h",
"peers_ban_score": "Score de Ban: %d",
"peers_banned": "Banidos",
"peers_banned_count": "Banidos: %d",
"peers_best_block": "Melhor Bloco",
"peers_blockchain": "BLOCKCHAIN",
"peers_blocks": "Blocos",
"peers_blocks_left": "%d blocos restantes",
"peers_clear_all_bans": "Remover Todos os Banimentos",
"peers_click_copy": "Clique para copiar",
"peers_connected": "Conectados",
"peers_connected_count": "Conectados: %d",
"peers_copy_ip": "Copiar IP",
"peers_dir_in": "Ent.",
"peers_dir_out": "Saí.",
"peers_hash_copied": "Hash copiado",
"peers_hashrate": "Hashrate",
"peers_in_out": "Ent./Saí.",
"peers_longest": "Mais longa",
"peers_longest_chain": "Chain Mais Longa",
"peers_memory": "Memória",
"peers_no_banned": "Nenhum par banido",
"peers_no_connected": "Nenhum par conectado",
"peers_no_tls": "Sem TLS",
"peers_notarized": "Notarizado",
"peers_p2p_port": "Porta P2P",
"peers_protocol": "Protocolo",
"peers_received": "Recebido",
"peers_refresh": "Atualizar",
"peers_refresh_tooltip": "Atualizar lista de pares",
"peers_refreshing": "Atualizando...",
"peers_sent": "Enviado",
"peers_tt_id": "ID: %d",
"peers_tt_received": "Recebido: %s",
"peers_tt_sent": "Enviado: %s",
"peers_tt_services": "Serviços: %s",
"peers_tt_start_height": "Altura Inicial: %d",
"peers_tt_synced": "Sincronizado H/B: %d/%d",
"peers_tt_tls_cipher": "TLS: %s",
"peers_unban": "Desbanir",
"peers_upper": "PARES",
"peers_version": "Versão",
"pending": "Pendente",
"ping": "Ping",
"price_chart": "Gráfico de Preços",
"qr_code": "Código QR",
"qr_failed": "Falha ao gerar código QR",
"qr_title": "Código QR",
"qr_unavailable": "QR indisponível",
"receive": "Receber",
"received": "recebido",
"received_filter": "Recebido",
"received_label": "Recebido",
"received_upper": "RECEBIDO",
"receiving_addresses": "Seus Endereços de Recebimento",
"recent_received": "RECEBIDOS RECENTES",
"recent_sends": "ENVIOS RECENTES",
"recipient": "DESTINATÁRIO",
"recv_type": "Receb.",
"refresh": "Atualizar",
"refresh_now": "Atualizar Agora",
"report_bug": "Reportar Bug",
"request_amount": "Valor (opcional):",
"request_copy_uri": "Copiar URI",
"request_description": "Gere uma solicitação de pagamento que outros podem escanear ou copiar. O código QR contém seu endereço e valor/memo opcionais.",
"request_label": "Rótulo (opcional):",
"request_memo": "Memo (opcional):",
"request_payment": "Solicitar Pagamento",
"request_payment_uri": "URI de Pagamento:",
"request_receive_address": "Endereço de Recebimento:",
"request_select_address": "Selecionar endereço...",
"request_shielded_addrs": "-- Endereços Blindados --",
"request_title": "Solicitar Pagamento",
"request_transparent_addrs": "-- Endereços Transparentes --",
"request_uri_copied": "URI de pagamento copiada para a área de transferência",
"rescan": "Reescanear",
"reset_to_defaults": "Redefinir Padrões",
"review_send": "Revisar Envio",
"rpc_host": "Host RPC",
"rpc_pass": "Senha",
"rpc_port": "Porta",
"rpc_user": "Usuário",
"save": "Salvar",
"save_settings": "Salvar Configurações",
"save_z_transactions": "Salvar Z-tx na lista de tx",
"search_placeholder": "Pesquisar...",
"security": "SEGURANÇA",
"select_address": "Selecionar endereço...",
"select_receiving_address": "Selecionar endereço de recebimento...",
"select_source_address": "Selecionar endereço de origem...",
"send": "Enviar",
"send_amount": "Valor",
"send_amount_details": "DETALHES DO VALOR",
"send_amount_upper": "VALOR",
"send_clear_fields": "Limpar todos os campos do formulário?",
"send_copy_error": "Copiar Erro",
"send_dismiss": "Dispensar",
"send_error_copied": "Erro copiado para a área de transferência",
"send_error_prefix": "Erro: %s",
"send_exceeds_available": "Excede o disponível (%.8f)",
"send_fee": "Taxa",
"send_fee_high": "Alta",
"send_fee_low": "Baixa",
"send_fee_normal": "Normal",
"send_form_restored": "Formulário restaurado",
"send_from_this_address": "Enviar deste endereço",
"send_go_to_receive": "Ir para Receber",
"send_keep": "Manter",
"send_network_fee": "TAXA DA REDE",
"send_no_balance": "Sem saldo",
"send_no_recent": "Nenhum envio recente",
"send_recent_sends": "ENVIOS RECENTES",
"send_recipient": "DESTINATÁRIO",
"send_select_source": "Selecionar endereço de origem...",
"send_sending_from": "ENVIANDO DE",
"send_submitting": "Enviando transação...",
"send_switch_to_receive": "Mude para Receber para obter seu endereço e começar a receber fundos.",
"send_to": "Enviar para",
"send_tooltip_enter_amount": "Digite um valor para enviar",
"send_tooltip_exceeds_balance": "Valor excede o saldo disponível",
"send_tooltip_in_progress": "Transação já em andamento",
"send_tooltip_invalid_address": "Digite um endereço de destinatário válido",
"send_tooltip_not_connected": "Não conectado ao daemon",
"send_tooltip_select_source": "Selecione primeiro um endereço de origem",
"send_tooltip_syncing": "Aguarde a sincronização da blockchain",
"send_total": "Total",
"send_transaction": "Enviar Transação",
"send_tx_failed": "Transação falhou",
"send_tx_sent": "Transação enviada!",
"send_tx_success": "Transação enviada com sucesso!",
"send_txid_copied": "TxID copiado para a área de transferência",
"send_txid_label": "TxID: %s",
"send_valid_shielded": "Endereço blindado válido",
"send_valid_transparent": "Endereço transparente válido",
"send_wallet_empty": "Sua carteira está vazia",
"send_yes_clear": "Sim, Limpar",
"sending": "Enviando transação",
"sending_from": "ENVIANDO DE",
"sent": "enviado",
"sent_filter": "Enviado",
"sent_type": "Enviado",
"sent_upper": "ENVIADO",
"settings": "Configurações",
"setup_wizard": "Assistente de Configuração",
"share": "Compartilhar",
"shield_check_status": "Verificar Status",
"shield_completed": "Operação concluída com sucesso!",
"shield_description": "Blinde suas recompensas de mineração enviando saídas coinbase de endereços transparentes para um endereço blindado. Isso melhora a privacidade ocultando sua renda de mineração.",
"shield_from_address": "Do Endereço:",
"shield_funds": "Blindar Fundos",
"shield_in_progress": "Operação em andamento...",
"shield_max_utxos": "Máx. UTXOs por operação",
"shield_merge_done": "Blindagem/fusão concluída!",
"shield_select_z": "Selecionar z-endereço...",
"shield_started": "Operação de blindagem iniciada",
"shield_title": "Blindar Recompensas Coinbase",
"shield_to_address": "Para Endereço (Blindado):",
"shield_utxo_limit": "Limite UTXO:",
"shield_wildcard_hint": "Use '*' para blindar de todos os endereços transparentes",
"shielded": "Blindado",
"shielded_to": "BLINDADO PARA",
"shielded_type": "Blindado",
"show": "Mostrar",
"show_qr_code": "Mostrar Código QR",
"showing_transactions": "Mostrando %d\xe2\x80\x93%d de %d transações (total: %zu)",
"simple_background": "Fundo simples",
"start_mining": "Iniciar Mineração",
"status": "Status",
"stop_external": "Parar daemon externo",
"stop_mining": "Parar Mineração",
"submitting_transaction": "Enviando transação...",
"success": "Sucesso",
"summary": "Resumo",
"syncing": "Sincronizando...",
"t_addresses": "Endereços T",
"test_connection": "Testar",
"theme": "Tema",
"theme_effects": "Efeitos de tema",
"time_days_ago": "há %d dias",
"time_hours_ago": "há %d horas",
"time_minutes_ago": "há %d minutos",
"time_seconds_ago": "há %d segundos",
"to": "Para",
"to_upper": "PARA",
"tools": "FERRAMENTAS",
"total": "Total",
"transaction_id": "ID DA TRANSAÇÃO",
"transaction_sent": "Transação enviada com sucesso",
"transaction_sent_msg": "Transação enviada!",
"transaction_url": "URL da Transação",
"transactions": "Transações",
"transactions_upper": "TRANSAÇÕES",
"transparent": "Transparente",
"tx_confirmations": "%d confirmações",
"tx_details_title": "Detalhes da Transação",
"tx_from_address": "Endereço de Origem:",
"tx_id_label": "ID da Transação:",
"tx_immature": "IMATURO",
"tx_mined": "MINERADO",
"tx_received": "RECEBIDO",
"tx_sent": "ENVIADO",
"tx_to_address": "Endereço de Destino:",
"tx_view_explorer": "Ver no Explorador",
"txs_count": "%d txs",
"type": "Tipo",
"ui_opacity": "Opacidade da Interface",
"unban": "Desbanir",
"unconfirmed": "Não confirmado",
"undo_clear": "Desfazer Limpeza",
"unknown": "Desconhecido",
"use_embedded_daemon": "Usar dragonxd integrado",
"use_tor": "Usar Tor",
"validate_btn": "Validar",
"validate_description": "Digite um endereço DragonX para verificar se é válido e se pertence a esta carteira.",
"validate_invalid": "INVÁLIDO",
"validate_is_mine": "Esta carteira possui este endereço",
"validate_not_mine": "Não pertence a esta carteira",
"validate_ownership": "Propriedade:",
"validate_results": "Resultados:",
"validate_shielded_type": "Blindado (z-endereço)",
"validate_status": "Status:",
"validate_title": "Validar Endereço",
"validate_transparent_type": "Transparente (t-endereço)",
"validate_type": "Tipo:",
"validate_valid": "VÁLIDO",
"validating": "Validando...",
"verbose_logging": "Log detalhado",
"version": "Versão",
"view": "Visualizar",
"view_details": "Ver Detalhes",
"view_on_explorer": "Ver no Explorador",
"waiting_for_daemon": "Aguardando conexão com o daemon...",
"wallet": "CARTEIRA",
"wallet_empty": "Sua carteira está vazia",
"wallet_empty_hint": "Mude para Receber para obter seu endereço e começar a receber fundos.",
"warning": "Aviso",
"warning_upper": "AVISO!",
"website": "Website",
"window_opacity": "Opacidade da Janela",
"yes_clear": "Sim, Limpar",
"your_addresses": "Seus Endereços",
"z_addresses": "Endereços Z",
}
out = os.path.join(os.path.dirname(__file__), "..", "res", "lang", "pt.json")
with open(out, "w", encoding="utf-8") as f:
json.dump(translations, f, indent=4, ensure_ascii=False, sort_keys=True)
print(f"Wrote {len(translations)} Portuguese translations to {os.path.abspath(out)}")
+646
View File
@@ -0,0 +1,646 @@
#!/usr/bin/env python3
"""Generate Russian (ru) translations for ObsidianDragon wallet."""
import json, os
translations = {
"24h_change": "Изменение за 24ч",
"24h_volume": "Объём за 24ч",
"about": "О программе",
"about_block_explorer": "Обозреватель блоков",
"about_block_height": "Высота блока:",
"about_build_date": "Дата сборки:",
"about_build_type": "Тип сборки:",
"about_chain": "Цепочка:",
"about_connections": "Подключения:",
"about_credits": "Благодарности",
"about_daemon": "Daemon:",
"about_debug": "Отладка",
"about_dragonx": "Об ObsidianDragon",
"about_edition": "Редакция ImGui",
"about_github": "GitHub",
"about_imgui": "ImGui:",
"about_license": "Лицензия",
"about_license_text": "Это программное обеспечение выпущено под лицензией GNU General Public License v3 (GPLv3). Вы можете свободно использовать, изменять и распространять это ПО в соответствии с условиями лицензии.",
"about_peers_count": "%zu узлов",
"about_release": "Релиз",
"about_title": "Об ObsidianDragon",
"about_version": "Версия:",
"about_website": "Веб-сайт",
"acrylic": "Акрил",
"add": "Добавить",
"address": "Адрес",
"address_book_add": "Добавить адрес",
"address_book_add_new": "Добавить новый",
"address_book_added": "Адрес добавлен в книгу",
"address_book_count": "%zu адресов сохранено",
"address_book_deleted": "Запись удалена",
"address_book_edit": "Редактировать адрес",
"address_book_empty": "Нет сохранённых адресов. Нажмите 'Добавить новый', чтобы создать.",
"address_book_exists": "Адрес уже существует в книге",
"address_book_title": "Адресная книга",
"address_book_update_failed": "Не удалось обновить — адрес может быть дубликатом",
"address_book_updated": "Адрес обновлён",
"address_copied": "Адрес скопирован в буфер обмена",
"address_details": "Детали адреса",
"address_label": "Адрес:",
"address_upper": "АДРЕС",
"address_url": "URL адреса",
"addresses_appear_here": "Ваши адреса для получения появятся здесь после подключения.",
"advanced": "РАСШИРЕННЫЕ",
"all_filter": "Все",
"allow_custom_fees": "Разрешить пользовательские комиссии",
"amount": "Сумма",
"amount_details": "ДЕТАЛИ СУММЫ",
"amount_exceeds_balance": "Сумма превышает баланс",
"amount_label": "Сумма:",
"appearance": "ВНЕШНИЙ ВИД",
"auto_shield": "Авто-экранирование майнинга",
"available": "Доступно",
"backup_backing_up": "Создание резервной копии...",
"backup_create": "Создать резервную копию",
"backup_created": "Резервная копия кошелька создана",
"backup_data": "РЕЗЕРВНОЕ КОПИРОВАНИЕ И ДАННЫЕ",
"backup_description": "Создайте резервную копию файла wallet.dat. Этот файл содержит все ваши приватные ключи и историю транзакций. Храните копию в безопасном месте.",
"backup_destination": "Место сохранения:",
"backup_tip_external": "Храните резервные копии на внешних дисках или в облаке",
"backup_tip_multiple": "Создавайте несколько копий в разных местах",
"backup_tip_test": "Периодически проверяйте восстановление из резервной копии",
"backup_tips": "Советы:",
"backup_title": "Резервное копирование кошелька",
"backup_wallet": "Создать резервную копию...",
"backup_wallet_not_found": "Предупреждение: wallet.dat не найден в ожидаемом расположении",
"balance": "Баланс",
"balance_layout": "Макет баланса",
"ban": "Заблокировать",
"banned_peers": "Заблокированные узлы",
"block": "Блок",
"block_bits": "Биты:",
"block_click_next": "Нажмите для следующего блока",
"block_click_prev": "Нажмите для предыдущего блока",
"block_explorer": "Обозреватель блоков",
"block_get_info": "Получить информацию о блоке",
"block_hash": "Хэш блока:",
"block_height": "Высота блока:",
"block_info_title": "Информация о блоке",
"block_merkle_root": "Корень Меркла:",
"block_nav_next": "Далее >>",
"block_nav_prev": "<< Назад",
"block_next": "Следующий блок:",
"block_previous": "Предыдущий блок:",
"block_size": "Размер:",
"block_timestamp": "Временная метка:",
"block_transactions": "Транзакции:",
"blockchain_syncing": "Синхронизация блокчейна (%.1f%%)... Балансы могут быть неточными.",
"cancel": "Отмена",
"characters": "символов",
"clear": "Очистить",
"clear_all_bans": "Снять все блокировки",
"clear_form_confirm": "Очистить все поля формы?",
"clear_request": "Очистить запрос",
"click_copy_address": "Нажмите, чтобы скопировать адрес",
"click_copy_uri": "Нажмите, чтобы скопировать URI",
"close": "Закрыть",
"conf_count": "%d подтв.",
"confirm_and_send": "Подтвердить и отправить",
"confirm_send": "Подтвердить отправку",
"confirm_transaction": "Подтвердить транзакцию",
"confirmations": "Подтверждения",
"confirmations_display": "%d подтверждений | %s",
"confirmed": "Подтверждено",
"connected": "Подключено",
"connected_peers": "Подключённые узлы",
"connecting": "Подключение...",
"console": "Консоль",
"console_auto_scroll": "Авто-прокрутка",
"console_available_commands": "Доступные команды:",
"console_capturing_output": "Захват вывода daemon...",
"console_clear": "Очистить",
"console_clear_console": "Очистить консоль",
"console_cleared": "Консоль очищена",
"console_click_commands": "Нажмите на команды выше, чтобы вставить их",
"console_click_insert": "Нажмите для вставки",
"console_click_insert_params": "Нажмите для вставки с параметрами",
"console_close": "Закрыть",
"console_commands": "Команды",
"console_common_rpc": "Частые RPC-команды:",
"console_completions": "Дополнения:",
"console_connected": "Подключено к daemon",
"console_copy_all": "Копировать всё",
"console_copy_selected": "Копировать",
"console_daemon": "Daemon",
"console_daemon_error": "Ошибка daemon!",
"console_daemon_started": "Daemon запущен",
"console_daemon_stopped": "Daemon остановлен",
"console_disconnected": "Отключено от daemon",
"console_errors": "Ошибки",
"console_filter_hint": "Фильтр вывода...",
"console_help_clear": " clear - Очистить консоль",
"console_help_getbalance": " getbalance - Показать прозрачный баланс",
"console_help_getblockcount": " getblockcount - Показать текущую высоту блока",
"console_help_getinfo": " getinfo - Показать информацию об узле",
"console_help_getmininginfo": " getmininginfo - Показать статус майнинга",
"console_help_getpeerinfo": " getpeerinfo - Показать подключённые узлы",
"console_help_gettotalbalance": " gettotalbalance - Показать общий баланс",
"console_help_help": " help - Показать эту справку",
"console_help_setgenerate": " setgenerate - Управление майнингом",
"console_help_stop": " stop - Остановить daemon",
"console_line_count": "%zu строк",
"console_new_lines": "%d новых строк",
"console_no_daemon": "Нет daemon",
"console_not_connected": "Ошибка: Не подключено к daemon",
"console_rpc_reference": "Справочник RPC-команд",
"console_scanline": "Скан-линия консоли",
"console_search_commands": "Поиск команд...",
"console_select_all": "Выбрать всё",
"console_show_daemon_output": "Показать вывод daemon",
"console_show_errors_only": "Показать только ошибки",
"console_show_rpc_ref": "Показать справочник RPC-команд",
"console_showing_lines": "Показано %zu из %zu строк",
"console_starting_node": "Запуск узла...",
"console_status_error": "Ошибка",
"console_status_running": "Работает",
"console_status_starting": "Запуск",
"console_status_stopped": "Остановлен",
"console_status_stopping": "Остановка",
"console_status_unknown": "Неизвестно",
"console_tab_completion": "Tab для дополнения",
"console_type_help": "Введите 'help' для списка команд",
"console_welcome": "Добро пожаловать в консоль ObsidianDragon",
"console_zoom_in": "Увеличить",
"console_zoom_out": "Уменьшить",
"copy": "Копировать",
"copy_address": "Копировать полный адрес",
"copy_error": "Копировать ошибку",
"copy_to_clipboard": "Копировать в буфер обмена",
"copy_txid": "Копировать TxID",
"copy_uri": "Копировать URI",
"current_price": "Текущая цена",
"custom_fees": "Пользовательские комиссии",
"dark": "Тёмная",
"date": "Дата",
"date_label": "Дата:",
"delete": "Удалить",
"difficulty": "Сложность",
"disconnected": "Отключено",
"dismiss": "Отклонить",
"display": "Отображение",
"dragonx_green": "DragonX (Зелёная)",
"edit": "Редактировать",
"error": "Ошибка",
"est_time_to_block": "Расч. время до блока",
"exit": "Выход",
"explorer": "ОБОЗРЕВАТЕЛЬ",
"export": "Экспорт",
"export_csv": "Экспорт в CSV",
"export_keys_btn": "Экспорт ключей",
"export_keys_danger": "ОПАСНОСТЬ: Будут экспортированы ВСЕ приватные ключи из вашего кошелька! Любой, кто получит доступ к этому файлу, сможет украсть ваши средства. Храните его в безопасности и удалите после использования.",
"export_keys_include_t": "Включить T-адреса (прозрачные)",
"export_keys_include_z": "Включить Z-адреса (экранированные)",
"export_keys_options": "Параметры экспорта:",
"export_keys_success": "Ключи успешно экспортированы",
"export_keys_title": "Экспорт всех приватных ключей",
"export_private_key": "Экспорт приватного ключа",
"export_tx_count": "Экспортировать %zu транзакций в файл CSV.",
"export_tx_file_fail": "Не удалось создать файл CSV",
"export_tx_none": "Нет транзакций для экспорта",
"export_tx_success": "Транзакции успешно экспортированы",
"export_tx_title": "Экспорт транзакций в CSV",
"export_viewing_key": "Экспорт ключа просмотра",
"failed_create_shielded": "Не удалось создать экранированный адрес",
"failed_create_transparent": "Не удалось создать прозрачный адрес",
"fee": "Комиссия",
"fee_high": "Высокая",
"fee_label": "Комиссия:",
"fee_low": "Низкая",
"fee_normal": "Обычная",
"fetch_prices": "Получить цены",
"file": "Файл",
"file_save_location": "Файл будет сохранён в: ~/.config/ObsidianDragon/",
"font_scale": "Масштаб шрифта",
"from": "От",
"from_upper": "ОТ",
"full_details": "Полные детали",
"general": "Общие",
"go_to_receive": "Перейти к получению",
"height": "Высота",
"help": "Справка",
"hide": "Скрыть",
"history": "История",
"immature_type": "Незрелая",
"import": "Импорт",
"import_key_btn": "Импорт ключей",
"import_key_formats": "Поддерживаемые форматы ключей:",
"import_key_full_rescan": "(0 = полное сканирование)",
"import_key_label": "Приватный ключ(и):",
"import_key_no_valid": "В введённых данных не найдено действительных ключей",
"import_key_rescan": "Пересканировать блокчейн после импорта",
"import_key_start_height": "Начальная высота:",
"import_key_success": "Ключи успешно импортированы",
"import_key_t_format": "Приватные ключи WIF для T-адресов",
"import_key_title": "Импорт приватного ключа",
"import_key_tooltip": "Введите один или несколько приватных ключей, по одному на строку.\nПоддерживаются ключи z-адресов и t-адресов.\nСтроки, начинающиеся с #, считаются комментариями.",
"import_key_warning": "Предупреждение: Никогда не делитесь своими приватными ключами! Импорт ключей из ненадёжных источников может скомпрометировать ваш кошелёк.",
"import_key_z_format": "Ключи расходования z-адресов (secret-extended-key-...)",
"import_private_key": "Импорт приватного ключа...",
"invalid_address": "Неверный формат адреса",
"ip_address": "IP-адрес",
"keep": "Сохранить",
"keep_daemon": "Оставить daemon работающим",
"key_export_fetching": "Получение ключа из кошелька...",
"key_export_private_key": "Приватный ключ:",
"key_export_private_warning": "Держите этот ключ в ТАЙНЕ! Любой, кто владеет этим ключом, может потратить ваши средства. Никогда не делитесь им в интернете или с ненадёжными лицами.",
"key_export_reveal": "Показать ключ",
"key_export_viewing_key": "Ключ просмотра:",
"key_export_viewing_warning": "Этот ключ просмотра позволяет другим видеть входящие транзакции и баланс, но НЕ тратить ваши средства. Делитесь только с доверенными лицами.",
"label": "Метка:",
"language": "Язык",
"light": "Светлая",
"loading": "Загрузка...",
"loading_addresses": "Загрузка адресов...",
"local_hashrate": "Локальный хешрейт",
"low_spec_mode": "Режим экономии",
"market": "Рынок",
"market_12h": "12ч",
"market_18h": "18ч",
"market_24h": "24ч",
"market_24h_volume": "ОБЪЁМ 24Ч",
"market_6h": "6ч",
"market_attribution": "Данные о ценах с NonKYC",
"market_btc_price": "ЦЕНА BTC",
"market_cap": "Рыночная капитализация",
"market_no_history": "Нет истории цен",
"market_no_price": "Нет данных о ценах",
"market_now": "Сейчас",
"market_pct_shielded": "%.0f%% Экранировано",
"market_portfolio": "ПОРТФЕЛЬ",
"market_price_unavailable": "Данные о ценах недоступны",
"market_refresh_price": "Обновить данные о ценах",
"market_trade_on": "Торговать на %s",
"mature": "Зрелая",
"max": "Макс",
"memo": "Заметка (необязательно, зашифровано)",
"memo_label": "Заметка:",
"memo_optional": "ЗАМЕТКА (НЕОБЯЗАТЕЛЬНО)",
"memo_upper": "ЗАМЕТКА",
"memo_z_only": "Примечание: Заметки доступны только при отправке на экранированные (z) адреса",
"merge_description": "Объедините несколько UTXO в один экранированный адрес. Это может уменьшить размер кошелька и улучшить конфиденциальность.",
"merge_funds": "Объединить средства",
"merge_started": "Операция объединения начата",
"merge_title": "Объединить на адрес",
"mine_when_idle": "Майнить в простое",
"mined": "добыто",
"mined_filter": "Добытые",
"mined_type": "Добытая",
"mined_upper": "ДОБЫТО",
"miner_fee": "Комиссия майнера",
"mining": "Майнинг",
"mining_active": "Активен",
"mining_address_copied": "Адрес майнинга скопирован",
"mining_all_time": "За всё время",
"mining_already_saved": "URL пула уже сохранён",
"mining_block_copied": "Хэш блока скопирован",
"mining_chart_1m_ago": "1м назад",
"mining_chart_5m_ago": "5м назад",
"mining_chart_now": "Сейчас",
"mining_chart_start": "Старт",
"mining_click": "Нажмите",
"mining_click_copy_address": "Нажмите, чтобы скопировать адрес",
"mining_click_copy_block": "Нажмите, чтобы скопировать хэш блока",
"mining_click_copy_difficulty": "Нажмите, чтобы скопировать сложность",
"mining_connected": "Подключено",
"mining_connecting": "Подключение...",
"mining_control": "Управление майнингом",
"mining_difficulty_copied": "Сложность скопирована",
"mining_est_block": "Расч. блок",
"mining_est_daily": "Расч. за день",
"mining_filter_all": "Все",
"mining_filter_tip_all": "Показать все доходы",
"mining_filter_tip_pool": "Показать только доходы пула",
"mining_filter_tip_solo": "Показать только доходы соло",
"mining_idle_off_tooltip": "Включить майнинг в простое",
"mining_idle_on_tooltip": "Отключить майнинг в простое",
"mining_local_hashrate": "Локальный хешрейт",
"mining_mine": "Майнить",
"mining_mining_addr": "Адрес майн.",
"mining_network": "Сеть",
"mining_no_blocks_yet": "Блоки пока не найдены",
"mining_no_payouts_yet": "Выплат пула пока нет",
"mining_no_saved_addresses": "Нет сохранённых адресов",
"mining_no_saved_pools": "Нет сохранённых пулов",
"mining_off": "Майнинг ВЫКЛЮЧЕН",
"mining_on": "Майнинг ВКЛЮЧЁН",
"mining_open_in_explorer": "Открыть в обозревателе",
"mining_payout_address": "Адрес выплат",
"mining_payout_tooltip": "Адрес для получения вознаграждений за майнинг",
"mining_pool": "Пул",
"mining_pool_hashrate": "Хешрейт пула",
"mining_pool_url": "URL пула",
"mining_recent_blocks": "ПОСЛЕДНИЕ БЛОКИ",
"mining_recent_payouts": "ПОСЛЕДНИЕ ВЫПЛАТЫ ПУЛА",
"mining_remove": "Удалить",
"mining_reset_defaults": "Сбросить настройки",
"mining_save_payout_address": "Сохранить адрес выплат",
"mining_save_pool_url": "Сохранить URL пула",
"mining_saved_addresses": "Сохранённые адреса:",
"mining_saved_pools": "Сохранённые пулы:",
"mining_shares": "Шары",
"mining_show_chart": "График",
"mining_show_log": "Журнал",
"mining_solo": "Соло",
"mining_starting": "Запуск...",
"mining_starting_tooltip": "Майнер запускается...",
"mining_statistics": "Статистика майнинга",
"mining_stop": "Стоп",
"mining_stop_solo_for_pool": "Остановите соло-майнинг перед запуском пул-майнинга",
"mining_stop_solo_for_pool_settings": "Остановите соло-майнинг для изменения настроек пула",
"mining_stopping": "Остановка...",
"mining_stopping_tooltip": "Майнер останавливается...",
"mining_syncing_tooltip": "Блокчейн синхронизируется...",
"mining_threads": "Потоки майнинга",
"mining_to_save": "для сохранения",
"mining_today": "Сегодня",
"mining_uptime": "Время работы",
"mining_yesterday": "Вчера",
"network": "Сеть",
"network_fee": "СЕТЕВАЯ КОМИССИЯ",
"network_hashrate": "Хешрейт сети",
"new": "+ Новый",
"new_shielded_created": "Создан новый экранированный адрес",
"new_t_address": "Новый T-адрес",
"new_t_transparent": "Новый t-адрес (Прозрачный)",
"new_transparent_created": "Создан новый прозрачный адрес",
"new_z_address": "Новый Z-адрес",
"new_z_shielded": "Новый z-адрес (Экранированный)",
"no_addresses": "Адреса не найдены. Создайте один, используя кнопки выше.",
"no_addresses_available": "Нет доступных адресов",
"no_addresses_match": "Нет адресов, соответствующих фильтру",
"no_addresses_with_balance": "Нет адресов с балансом",
"no_matching": "Нет подходящих транзакций",
"no_recent_receives": "Нет недавних получений",
"no_recent_sends": "Нет недавних отправлений",
"no_transactions": "Транзакции не найдены",
"node": "УЗЕЛ",
"node_security": "УЗЕЛ И БЕЗОПАСНОСТЬ",
"noise": "Шум",
"not_connected": "Не подключено к daemon...",
"not_connected_to_daemon": "Не подключено к daemon",
"notes": "Заметки",
"notes_optional": "Заметки (необязательно):",
"output_filename": "Имя выходного файла:",
"overview": "Обзор",
"paste": "Вставить",
"paste_from_clipboard": "Вставить из буфера обмена",
"pay_from": "Оплатить с",
"payment_request": "ЗАПРОС НА ОПЛАТУ",
"payment_request_copied": "Запрос на оплату скопирован",
"payment_uri_copied": "URI платежа скопирован",
"peers": "Узлы",
"peers_avg_ping": "Средний пинг",
"peers_ban_24h": "Заблокировать узел на 24ч",
"peers_ban_score": "Очки блокировки: %d",
"peers_banned": "Заблокированные",
"peers_banned_count": "Заблокировано: %d",
"peers_best_block": "Лучший блок",
"peers_blockchain": "БЛОКЧЕЙН",
"peers_blocks": "Блоки",
"peers_blocks_left": "Осталось %d блоков",
"peers_clear_all_bans": "Снять все блокировки",
"peers_click_copy": "Нажмите, чтобы скопировать",
"peers_connected": "Подключено",
"peers_connected_count": "Подключено: %d",
"peers_copy_ip": "Копировать IP",
"peers_dir_in": "Вх.",
"peers_dir_out": "Исх.",
"peers_hash_copied": "Хэш скопирован",
"peers_hashrate": "Хешрейт",
"peers_in_out": "Вх./Исх.",
"peers_longest": "Длиннейшая",
"peers_longest_chain": "Длиннейшая цепь",
"peers_memory": "Память",
"peers_no_banned": "Нет заблокированных узлов",
"peers_no_connected": "Нет подключённых узлов",
"peers_no_tls": "Без TLS",
"peers_notarized": "Нотаризован",
"peers_p2p_port": "P2P-порт",
"peers_protocol": "Протокол",
"peers_received": "Получено",
"peers_refresh": "Обновить",
"peers_refresh_tooltip": "Обновить список узлов",
"peers_refreshing": "Обновление...",
"peers_sent": "Отправлено",
"peers_tt_id": "ID: %d",
"peers_tt_received": "Получено: %s",
"peers_tt_sent": "Отправлено: %s",
"peers_tt_services": "Сервисы: %s",
"peers_tt_start_height": "Начальная высота: %d",
"peers_tt_synced": "Синхронизировано В/Б: %d/%d",
"peers_tt_tls_cipher": "TLS: %s",
"peers_unban": "Разблокировать",
"peers_upper": "УЗЛЫ",
"peers_version": "Версия",
"pending": "Ожидание",
"ping": "Пинг",
"price_chart": "График цен",
"qr_code": "QR-код",
"qr_failed": "Не удалось сгенерировать QR-код",
"qr_title": "QR-код",
"qr_unavailable": "QR недоступен",
"receive": "Получить",
"received": "получено",
"received_filter": "Получено",
"received_label": "Получено",
"received_upper": "ПОЛУЧЕНО",
"receiving_addresses": "Ваши адреса для получения",
"recent_received": "НЕДАВНО ПОЛУЧЕНО",
"recent_sends": "НЕДАВНО ОТПРАВЛЕНО",
"recipient": "ПОЛУЧАТЕЛЬ",
"recv_type": "Получ.",
"refresh": "Обновить",
"refresh_now": "Обновить сейчас",
"report_bug": "Сообщить об ошибке",
"request_amount": "Сумма (необязательно):",
"request_copy_uri": "Копировать URI",
"request_description": "Создайте запрос на оплату, который другие могут отсканировать или скопировать. QR-код содержит ваш адрес и опциональную сумму/заметку.",
"request_label": "Метка (необязательно):",
"request_memo": "Заметка (необязательно):",
"request_payment": "Запрос оплаты",
"request_payment_uri": "URI платежа:",
"request_receive_address": "Адрес получения:",
"request_select_address": "Выбрать адрес...",
"request_shielded_addrs": "-- Экранированные адреса --",
"request_title": "Запрос оплаты",
"request_transparent_addrs": "-- Прозрачные адреса --",
"request_uri_copied": "URI платежа скопирован в буфер обмена",
"rescan": "Пересканировать",
"reset_to_defaults": "Сбросить настройки",
"review_send": "Проверить отправку",
"rpc_host": "RPC-хост",
"rpc_pass": "Пароль",
"rpc_port": "Порт",
"rpc_user": "Имя пользователя",
"save": "Сохранить",
"save_settings": "Сохранить настройки",
"save_z_transactions": "Сохранять Z-tx в списке транзакций",
"search_placeholder": "Поиск...",
"security": "БЕЗОПАСНОСТЬ",
"select_address": "Выбрать адрес...",
"select_receiving_address": "Выбрать адрес получения...",
"select_source_address": "Выбрать адрес-источник...",
"send": "Отправить",
"send_amount": "Сумма",
"send_amount_details": "ДЕТАЛИ СУММЫ",
"send_amount_upper": "СУММА",
"send_clear_fields": "Очистить все поля формы?",
"send_copy_error": "Копировать ошибку",
"send_dismiss": "Отклонить",
"send_error_copied": "Ошибка скопирована в буфер обмена",
"send_error_prefix": "Ошибка: %s",
"send_exceeds_available": "Превышает доступное (%.8f)",
"send_fee": "Комиссия",
"send_fee_high": "Высокая",
"send_fee_low": "Низкая",
"send_fee_normal": "Обычная",
"send_form_restored": "Форма восстановлена",
"send_from_this_address": "Отправить с этого адреса",
"send_go_to_receive": "Перейти к получению",
"send_keep": "Сохранить",
"send_network_fee": "СЕТЕВАЯ КОМИССИЯ",
"send_no_balance": "Нет баланса",
"send_no_recent": "Нет недавних отправлений",
"send_recent_sends": "НЕДАВНО ОТПРАВЛЕНО",
"send_recipient": "ПОЛУЧАТЕЛЬ",
"send_select_source": "Выбрать адрес-источник...",
"send_sending_from": "ОТПРАВКА С",
"send_submitting": "Отправка транзакции...",
"send_switch_to_receive": "Перейдите к получению, чтобы получить свой адрес и начать получать средства.",
"send_to": "Отправить на",
"send_tooltip_enter_amount": "Введите сумму для отправки",
"send_tooltip_exceeds_balance": "Сумма превышает доступный баланс",
"send_tooltip_in_progress": "Транзакция уже выполняется",
"send_tooltip_invalid_address": "Введите действительный адрес получателя",
"send_tooltip_not_connected": "Не подключено к daemon",
"send_tooltip_select_source": "Сначала выберите адрес-источник",
"send_tooltip_syncing": "Дождитесь синхронизации блокчейна",
"send_total": "Итого",
"send_transaction": "Отправить транзакцию",
"send_tx_failed": "Транзакция не удалась",
"send_tx_sent": "Транзакция отправлена!",
"send_tx_success": "Транзакция успешно отправлена!",
"send_txid_copied": "TxID скопирован в буфер обмена",
"send_txid_label": "TxID: %s",
"send_valid_shielded": "Действительный экранированный адрес",
"send_valid_transparent": "Действительный прозрачный адрес",
"send_wallet_empty": "Ваш кошелёк пуст",
"send_yes_clear": "Да, очистить",
"sending": "Отправка транзакции",
"sending_from": "ОТПРАВКА С",
"sent": "отправлено",
"sent_filter": "Отправлено",
"sent_type": "Отправлено",
"sent_upper": "ОТПРАВЛЕНО",
"settings": "Настройки",
"setup_wizard": "Мастер настройки",
"share": "Поделиться",
"shield_check_status": "Проверить статус",
"shield_completed": "Операция успешно завершена!",
"shield_description": "Экранируйте вознаграждения за майнинг, отправив coinbase-выходы с прозрачных адресов на экранированный адрес. Это улучшает конфиденциальность, скрывая ваш доход от майнинга.",
"shield_from_address": "С адреса:",
"shield_funds": "Экранировать средства",
"shield_in_progress": "Операция выполняется...",
"shield_max_utxos": "Макс. UTXO за операцию",
"shield_merge_done": "Экранирование/объединение завершено!",
"shield_select_z": "Выбрать z-адрес...",
"shield_started": "Операция экранирования начата",
"shield_title": "Экранировать вознаграждения coinbase",
"shield_to_address": "На адрес (экранированный):",
"shield_utxo_limit": "Лимит UTXO:",
"shield_wildcard_hint": "Используйте '*' для экранирования со всех прозрачных адресов",
"shielded": "Экранированный",
"shielded_to": "ЭКРАНИРОВАНО НА",
"shielded_type": "Экранированный",
"show": "Показать",
"show_qr_code": "Показать QR-код",
"showing_transactions": "Показано %d\xe2\x80\x93%d из %d транзакций (всего: %zu)",
"simple_background": "Простой фон",
"start_mining": "Начать майнинг",
"status": "Статус",
"stop_external": "Остановить внешний daemon",
"stop_mining": "Остановить майнинг",
"submitting_transaction": "Отправка транзакции...",
"success": "Успешно",
"summary": "Итоги",
"syncing": "Синхронизация...",
"t_addresses": "T-адреса",
"test_connection": "Тест",
"theme": "Тема",
"theme_effects": "Эффекты темы",
"time_days_ago": "%d дней назад",
"time_hours_ago": "%d часов назад",
"time_minutes_ago": "%d минут назад",
"time_seconds_ago": "%d секунд назад",
"to": "Кому",
"to_upper": "КОМУ",
"tools": "ИНСТРУМЕНТЫ",
"total": "Итого",
"transaction_id": "ID ТРАНЗАКЦИИ",
"transaction_sent": "Транзакция успешно отправлена",
"transaction_sent_msg": "Транзакция отправлена!",
"transaction_url": "URL транзакции",
"transactions": "Транзакции",
"transactions_upper": "ТРАНЗАКЦИИ",
"transparent": "Прозрачный",
"tx_confirmations": "%d подтверждений",
"tx_details_title": "Детали транзакции",
"tx_from_address": "Адрес отправителя:",
"tx_id_label": "ID транзакции:",
"tx_immature": "НЕЗРЕЛАЯ",
"tx_mined": "ДОБЫТА",
"tx_received": "ПОЛУЧЕНО",
"tx_sent": "ОТПРАВЛЕНО",
"tx_to_address": "Адрес получателя:",
"tx_view_explorer": "Посмотреть в обозревателе",
"txs_count": "%d тр.",
"type": "Тип",
"ui_opacity": "Прозрачность интерфейса",
"unban": "Разблокировать",
"unconfirmed": "Не подтверждено",
"undo_clear": "Отменить очистку",
"unknown": "Неизвестно",
"use_embedded_daemon": "Использовать встроенный dragonxd",
"use_tor": "Использовать Tor",
"validate_btn": "Проверить",
"validate_description": "Введите адрес DragonX, чтобы проверить его действительность и принадлежность к этому кошельку.",
"validate_invalid": "НЕДЕЙСТВИТЕЛЕН",
"validate_is_mine": "Этот кошелёк владеет этим адресом",
"validate_not_mine": "Не принадлежит этому кошельку",
"validate_ownership": "Принадлежность:",
"validate_results": "Результаты:",
"validate_shielded_type": "Экранированный (z-адрес)",
"validate_status": "Статус:",
"validate_title": "Проверить адрес",
"validate_transparent_type": "Прозрачный (t-адрес)",
"validate_type": "Тип:",
"validate_valid": "ДЕЙСТВИТЕЛЕН",
"validating": "Проверка...",
"verbose_logging": "Подробное логирование",
"version": "Версия",
"view": "Просмотр",
"view_details": "Подробнее",
"view_on_explorer": "Посмотреть в обозревателе",
"waiting_for_daemon": "Ожидание подключения к daemon...",
"wallet": "КОШЕЛЁК",
"wallet_empty": "Ваш кошелёк пуст",
"wallet_empty_hint": "Перейдите к получению, чтобы получить свой адрес и начать получать средства.",
"warning": "Предупреждение",
"warning_upper": "ПРЕДУПРЕЖДЕНИЕ!",
"website": "Веб-сайт",
"window_opacity": "Прозрачность окна",
"yes_clear": "Да, очистить",
"your_addresses": "Ваши адреса",
"z_addresses": "Z-адреса",
}
out = os.path.join(os.path.dirname(__file__), "..", "res", "lang", "ru.json")
with open(out, "w", encoding="utf-8") as f:
json.dump(translations, f, indent=4, ensure_ascii=False, sort_keys=True)
print(f"Wrote {len(translations)} Russian translations to {os.path.abspath(out)}")
+646
View File
@@ -0,0 +1,646 @@
#!/usr/bin/env python3
"""Generate Chinese Simplified (zh) translations for ObsidianDragon wallet."""
import json, os
translations = {
"24h_change": "24小时变化",
"24h_volume": "24小时交易量",
"about": "关于",
"about_block_explorer": "区块浏览器",
"about_block_height": "区块高度:",
"about_build_date": "构建日期:",
"about_build_type": "构建类型:",
"about_chain": "链:",
"about_connections": "连接数:",
"about_credits": "致谢",
"about_daemon": "守护进程:",
"about_debug": "调试",
"about_dragonx": "关于 ObsidianDragon",
"about_edition": "ImGui 版本",
"about_github": "GitHub",
"about_imgui": "ImGui:",
"about_license": "许可证",
"about_license_text": "本软件根据 GNU 通用公共许可证 v3 (GPLv3) 发布。您可以根据许可证条款自由使用、修改和分发本软件。",
"about_peers_count": "%zu 个节点",
"about_release": "发布版",
"about_title": "关于 ObsidianDragon",
"about_version": "版本:",
"about_website": "网站",
"acrylic": "亚克力",
"add": "添加",
"address": "地址",
"address_book_add": "添加地址",
"address_book_add_new": "添加新地址",
"address_book_added": "地址已添加到通讯录",
"address_book_count": "已保存 %zu 个地址",
"address_book_deleted": "条目已删除",
"address_book_edit": "编辑地址",
"address_book_empty": "没有保存的地址。点击'添加新地址'创建一个。",
"address_book_exists": "地址已存在于通讯录中",
"address_book_title": "地址簿",
"address_book_update_failed": "更新失败——地址可能重复",
"address_book_updated": "地址已更新",
"address_copied": "地址已复制到剪贴板",
"address_details": "地址详情",
"address_label": "地址:",
"address_upper": "地址",
"address_url": "地址 URL",
"addresses_appear_here": "连接后,您的接收地址将显示在此处。",
"advanced": "高级",
"all_filter": "全部",
"allow_custom_fees": "允许自定义手续费",
"amount": "金额",
"amount_details": "金额详情",
"amount_exceeds_balance": "金额超过余额",
"amount_label": "金额:",
"appearance": "外观",
"auto_shield": "自动屏蔽挖矿",
"available": "可用",
"backup_backing_up": "正在备份...",
"backup_create": "创建备份",
"backup_created": "钱包备份已创建",
"backup_data": "备份与数据",
"backup_description": "创建 wallet.dat 文件的备份。此文件包含您所有的私钥和交易历史。请将备份存放在安全的地方。",
"backup_destination": "备份目标:",
"backup_tip_external": "将备份存储在外部驱动器或云存储中",
"backup_tip_multiple": "在不同位置创建多个备份",
"backup_tip_test": "定期测试从备份恢复",
"backup_tips": "提示:",
"backup_title": "备份钱包",
"backup_wallet": "备份钱包...",
"backup_wallet_not_found": "警告:在预期位置未找到 wallet.dat",
"balance": "余额",
"balance_layout": "余额布局",
"ban": "封禁",
"banned_peers": "已封禁节点",
"block": "区块",
"block_bits": "比特:",
"block_click_next": "点击查看下一个区块",
"block_click_prev": "点击查看上一个区块",
"block_explorer": "区块浏览器",
"block_get_info": "获取区块信息",
"block_hash": "区块哈希:",
"block_height": "区块高度:",
"block_info_title": "区块信息",
"block_merkle_root": "默克尔根:",
"block_nav_next": "下一个 >>",
"block_nav_prev": "<< 上一个",
"block_next": "下一个区块:",
"block_previous": "上一个区块:",
"block_size": "大小:",
"block_timestamp": "时间戳:",
"block_transactions": "交易:",
"blockchain_syncing": "区块链同步中 (%.1f%%)... 余额可能不准确。",
"cancel": "取消",
"characters": "字符",
"clear": "清除",
"clear_all_bans": "解除所有封禁",
"clear_form_confirm": "清除所有表单字段?",
"clear_request": "清除请求",
"click_copy_address": "点击复制地址",
"click_copy_uri": "点击复制 URI",
"close": "关闭",
"conf_count": "%d 确认",
"confirm_and_send": "确认并发送",
"confirm_send": "确认发送",
"confirm_transaction": "确认交易",
"confirmations": "确认数",
"confirmations_display": "%d 次确认 | %s",
"confirmed": "已确认",
"connected": "已连接",
"connected_peers": "已连接节点",
"connecting": "连接中...",
"console": "控制台",
"console_auto_scroll": "自动滚动",
"console_available_commands": "可用命令:",
"console_capturing_output": "正在捕获守护进程输出...",
"console_clear": "清除",
"console_clear_console": "清除控制台",
"console_cleared": "控制台已清除",
"console_click_commands": "点击上方命令以插入",
"console_click_insert": "点击插入",
"console_click_insert_params": "点击插入(含参数)",
"console_close": "关闭",
"console_commands": "命令",
"console_common_rpc": "常用 RPC 命令:",
"console_completions": "补全:",
"console_connected": "已连接到守护进程",
"console_copy_all": "全部复制",
"console_copy_selected": "复制",
"console_daemon": "守护进程",
"console_daemon_error": "守护进程错误!",
"console_daemon_started": "守护进程已启动",
"console_daemon_stopped": "守护进程已停止",
"console_disconnected": "已断开与守护进程的连接",
"console_errors": "错误",
"console_filter_hint": "过滤输出...",
"console_help_clear": " clear - 清除控制台",
"console_help_getbalance": " getbalance - 显示透明余额",
"console_help_getblockcount": " getblockcount - 显示当前区块高度",
"console_help_getinfo": " getinfo - 显示节点信息",
"console_help_getmininginfo": " getmininginfo - 显示挖矿状态",
"console_help_getpeerinfo": " getpeerinfo - 显示已连接节点",
"console_help_gettotalbalance": " gettotalbalance - 显示总余额",
"console_help_help": " help - 显示此帮助信息",
"console_help_setgenerate": " setgenerate - 控制挖矿",
"console_help_stop": " stop - 停止守护进程",
"console_line_count": "%zu 行",
"console_new_lines": "%d 新行",
"console_no_daemon": "无守护进程",
"console_not_connected": "错误:未连接到守护进程",
"console_rpc_reference": "RPC 命令参考",
"console_scanline": "控制台扫描线",
"console_search_commands": "搜索命令...",
"console_select_all": "全选",
"console_show_daemon_output": "显示守护进程输出",
"console_show_errors_only": "仅显示错误",
"console_show_rpc_ref": "显示 RPC 命令参考",
"console_showing_lines": "显示 %zu / %zu 行",
"console_starting_node": "正在启动节点...",
"console_status_error": "错误",
"console_status_running": "运行中",
"console_status_starting": "启动中",
"console_status_stopped": "已停止",
"console_status_stopping": "停止中",
"console_status_unknown": "未知",
"console_tab_completion": "Tab 补全",
"console_type_help": "输入 'help' 查看可用命令",
"console_welcome": "欢迎使用 ObsidianDragon 控制台",
"console_zoom_in": "放大",
"console_zoom_out": "缩小",
"copy": "复制",
"copy_address": "复制完整地址",
"copy_error": "复制错误",
"copy_to_clipboard": "复制到剪贴板",
"copy_txid": "复制交易ID",
"copy_uri": "复制 URI",
"current_price": "当前价格",
"custom_fees": "自定义手续费",
"dark": "深色",
"date": "日期",
"date_label": "日期:",
"delete": "删除",
"difficulty": "难度",
"disconnected": "已断开",
"dismiss": "关闭",
"display": "显示",
"dragonx_green": "DragonX(绿色)",
"edit": "编辑",
"error": "错误",
"est_time_to_block": "预计出块时间",
"exit": "退出",
"explorer": "浏览器",
"export": "导出",
"export_csv": "导出 CSV",
"export_keys_btn": "导出密钥",
"export_keys_danger": "危险:这将导出您钱包中的所有私钥!任何获得此文件的人都可以窃取您的资金。请安全保管并在使用后删除。",
"export_keys_include_t": "包含 T 地址(透明)",
"export_keys_include_z": "包含 Z 地址(屏蔽)",
"export_keys_options": "导出选项:",
"export_keys_success": "密钥导出成功",
"export_keys_title": "导出所有私钥",
"export_private_key": "导出私钥",
"export_tx_count": "导出 %zu 笔交易到 CSV 文件。",
"export_tx_file_fail": "无法创建 CSV 文件",
"export_tx_none": "没有交易可导出",
"export_tx_success": "交易导出成功",
"export_tx_title": "导出交易到 CSV",
"export_viewing_key": "导出查看密钥",
"failed_create_shielded": "无法创建屏蔽地址",
"failed_create_transparent": "无法创建透明地址",
"fee": "手续费",
"fee_high": "高",
"fee_label": "手续费:",
"fee_low": "低",
"fee_normal": "普通",
"fetch_prices": "获取价格",
"file": "文件",
"file_save_location": "文件将保存至:~/.config/ObsidianDragon/",
"font_scale": "字体大小",
"from": "从",
"from_upper": "从",
"full_details": "完整详情",
"general": "常规",
"go_to_receive": "前往接收",
"height": "高度",
"help": "帮助",
"hide": "隐藏",
"history": "历史",
"immature_type": "未成熟",
"import": "导入",
"import_key_btn": "导入密钥",
"import_key_formats": "支持的密钥格式:",
"import_key_full_rescan": "(0 = 完整重扫)",
"import_key_label": "私钥:",
"import_key_no_valid": "输入中未找到有效密钥",
"import_key_rescan": "导入后重新扫描区块链",
"import_key_start_height": "起始高度:",
"import_key_success": "密钥导入成功",
"import_key_t_format": "T 地址 WIF 私钥",
"import_key_title": "导入私钥",
"import_key_tooltip": "输入一个或多个私钥,每行一个。\n支持 z 地址和 t 地址密钥。\n以 # 开头的行视为注释。",
"import_key_warning": "警告:切勿分享您的私钥!从不可信来源导入密钥可能会危及您的钱包安全。",
"import_key_z_format": "Z 地址花费密钥 (secret-extended-key-...)",
"import_private_key": "导入私钥...",
"invalid_address": "无效的地址格式",
"ip_address": "IP 地址",
"keep": "保留",
"keep_daemon": "保持守护进程运行",
"key_export_fetching": "正在从钱包获取密钥...",
"key_export_private_key": "私钥:",
"key_export_private_warning": "请保密此密钥!任何拥有此密钥的人都可以花费您的资金。切勿在网上或与不可信的人分享。",
"key_export_reveal": "显示密钥",
"key_export_viewing_key": "查看密钥:",
"key_export_viewing_warning": "此查看密钥允许他人查看您的入账交易和余额,但不能花费您的资金。仅与信任的人分享。",
"label": "标签:",
"language": "语言",
"light": "浅色",
"loading": "加载中...",
"loading_addresses": "正在加载地址...",
"local_hashrate": "本地算力",
"low_spec_mode": "低配模式",
"market": "市场",
"market_12h": "12小时",
"market_18h": "18小时",
"market_24h": "24小时",
"market_24h_volume": "24小时交易量",
"market_6h": "6小时",
"market_attribution": "价格数据来自 NonKYC",
"market_btc_price": "BTC 价格",
"market_cap": "市值",
"market_no_history": "无价格历史",
"market_no_price": "无价格数据",
"market_now": "现在",
"market_pct_shielded": "%.0f%% 屏蔽",
"market_portfolio": "投资组合",
"market_price_unavailable": "价格数据不可用",
"market_refresh_price": "刷新价格数据",
"market_trade_on": "在 %s 交易",
"mature": "已成熟",
"max": "最大",
"memo": "备注(可选,加密)",
"memo_label": "备注:",
"memo_optional": "备注(可选)",
"memo_upper": "备注",
"memo_z_only": "注意:备注仅在发送到屏蔽 (z) 地址时可用",
"merge_description": "将多个 UTXO 合并到一个屏蔽地址。这可以帮助减小钱包大小并提高隐私性。",
"merge_funds": "合并资金",
"merge_started": "合并操作已开始",
"merge_title": "合并到地址",
"mine_when_idle": "空闲时挖矿",
"mined": "已挖得",
"mined_filter": "已挖得",
"mined_type": "已挖得",
"mined_upper": "已挖得",
"miner_fee": "矿工费",
"mining": "挖矿",
"mining_active": "活跃",
"mining_address_copied": "挖矿地址已复制",
"mining_all_time": "所有时间",
"mining_already_saved": "矿池 URL 已保存",
"mining_block_copied": "区块哈希已复制",
"mining_chart_1m_ago": "1分钟前",
"mining_chart_5m_ago": "5分钟前",
"mining_chart_now": "现在",
"mining_chart_start": "开始",
"mining_click": "点击",
"mining_click_copy_address": "点击复制地址",
"mining_click_copy_block": "点击复制区块哈希",
"mining_click_copy_difficulty": "点击复制难度",
"mining_connected": "已连接",
"mining_connecting": "连接中...",
"mining_control": "挖矿控制",
"mining_difficulty_copied": "难度已复制",
"mining_est_block": "预计区块",
"mining_est_daily": "预计日收益",
"mining_filter_all": "全部",
"mining_filter_tip_all": "显示所有收益",
"mining_filter_tip_pool": "仅显示矿池收益",
"mining_filter_tip_solo": "仅显示单人收益",
"mining_idle_off_tooltip": "启用空闲挖矿",
"mining_idle_on_tooltip": "禁用空闲挖矿",
"mining_local_hashrate": "本地算力",
"mining_mine": "挖矿",
"mining_mining_addr": "挖矿地址",
"mining_network": "网络",
"mining_no_blocks_yet": "尚未找到区块",
"mining_no_payouts_yet": "尚无矿池支付",
"mining_no_saved_addresses": "没有保存的地址",
"mining_no_saved_pools": "没有保存的矿池",
"mining_off": "挖矿已关闭",
"mining_on": "挖矿已开启",
"mining_open_in_explorer": "在浏览器中打开",
"mining_payout_address": "支付地址",
"mining_payout_tooltip": "接收挖矿奖励的地址",
"mining_pool": "矿池",
"mining_pool_hashrate": "矿池算力",
"mining_pool_url": "矿池 URL",
"mining_recent_blocks": "最近区块",
"mining_recent_payouts": "最近矿池支付",
"mining_remove": "移除",
"mining_reset_defaults": "重置默认值",
"mining_save_payout_address": "保存支付地址",
"mining_save_pool_url": "保存矿池 URL",
"mining_saved_addresses": "已保存地址:",
"mining_saved_pools": "已保存矿池:",
"mining_shares": "份额",
"mining_show_chart": "图表",
"mining_show_log": "日志",
"mining_solo": "单人",
"mining_starting": "启动中...",
"mining_starting_tooltip": "矿工正在启动...",
"mining_statistics": "挖矿统计",
"mining_stop": "停止",
"mining_stop_solo_for_pool": "启动矿池挖矿前请先停止单人挖矿",
"mining_stop_solo_for_pool_settings": "请停止单人挖矿以更改矿池设置",
"mining_stopping": "停止中...",
"mining_stopping_tooltip": "矿工正在停止...",
"mining_syncing_tooltip": "区块链同步中...",
"mining_threads": "挖矿线程",
"mining_to_save": "保存",
"mining_today": "今天",
"mining_uptime": "运行时间",
"mining_yesterday": "昨天",
"network": "网络",
"network_fee": "网络手续费",
"network_hashrate": "全网算力",
"new": "+ 新建",
"new_shielded_created": "新屏蔽地址已创建",
"new_t_address": "新 T 地址",
"new_t_transparent": "新 t 地址(透明)",
"new_transparent_created": "新透明地址已创建",
"new_z_address": "新 Z 地址",
"new_z_shielded": "新 z 地址(屏蔽)",
"no_addresses": "未找到地址。请使用上方按钮创建一个。",
"no_addresses_available": "无可用地址",
"no_addresses_match": "没有匹配过滤器的地址",
"no_addresses_with_balance": "没有有余额的地址",
"no_matching": "没有匹配的交易",
"no_recent_receives": "没有最近的接收",
"no_recent_sends": "没有最近的发送",
"no_transactions": "未找到交易",
"node": "节点",
"node_security": "节点与安全",
"noise": "噪点",
"not_connected": "未连接到守护进程...",
"not_connected_to_daemon": "未连接到守护进程",
"notes": "备注",
"notes_optional": "备注(可选):",
"output_filename": "输出文件名:",
"overview": "概览",
"paste": "粘贴",
"paste_from_clipboard": "从剪贴板粘贴",
"pay_from": "付款来源",
"payment_request": "付款请求",
"payment_request_copied": "付款请求已复制",
"payment_uri_copied": "付款 URI 已复制",
"peers": "节点",
"peers_avg_ping": "平均延迟",
"peers_ban_24h": "封禁节点 24 小时",
"peers_ban_score": "封禁评分:%d",
"peers_banned": "已封禁",
"peers_banned_count": "已封禁:%d",
"peers_best_block": "最佳区块",
"peers_blockchain": "区块链",
"peers_blocks": "区块",
"peers_blocks_left": "剩余 %d 个区块",
"peers_clear_all_bans": "解除所有封禁",
"peers_click_copy": "点击复制",
"peers_connected": "已连接",
"peers_connected_count": "已连接:%d",
"peers_copy_ip": "复制 IP",
"peers_dir_in": "入",
"peers_dir_out": "出",
"peers_hash_copied": "哈希已复制",
"peers_hashrate": "算力",
"peers_in_out": "入/出",
"peers_longest": "最长",
"peers_longest_chain": "最长链",
"peers_memory": "内存",
"peers_no_banned": "无已封禁节点",
"peers_no_connected": "无已连接节点",
"peers_no_tls": "无 TLS",
"peers_notarized": "已公证",
"peers_p2p_port": "P2P 端口",
"peers_protocol": "协议",
"peers_received": "已接收",
"peers_refresh": "刷新",
"peers_refresh_tooltip": "刷新节点列表",
"peers_refreshing": "刷新中...",
"peers_sent": "已发送",
"peers_tt_id": "ID:%d",
"peers_tt_received": "已接收:%s",
"peers_tt_sent": "已发送:%s",
"peers_tt_services": "服务:%s",
"peers_tt_start_height": "起始高度:%d",
"peers_tt_synced": "已同步 H/B:%d/%d",
"peers_tt_tls_cipher": "TLS:%s",
"peers_unban": "解除封禁",
"peers_upper": "节点",
"peers_version": "版本",
"pending": "待处理",
"ping": "延迟",
"price_chart": "价格图表",
"qr_code": "二维码",
"qr_failed": "无法生成二维码",
"qr_title": "二维码",
"qr_unavailable": "二维码不可用",
"receive": "接收",
"received": "已接收",
"received_filter": "已接收",
"received_label": "已接收",
"received_upper": "已接收",
"receiving_addresses": "您的接收地址",
"recent_received": "最近接收",
"recent_sends": "最近发送",
"recipient": "收款方",
"recv_type": "接收",
"refresh": "刷新",
"refresh_now": "立即刷新",
"report_bug": "报告错误",
"request_amount": "金额(可选):",
"request_copy_uri": "复制 URI",
"request_description": "生成一个付款请求,他人可以扫描或复制。二维码包含您的地址和可选的金额/备注。",
"request_label": "标签(可选):",
"request_memo": "备注(可选):",
"request_payment": "请求付款",
"request_payment_uri": "付款 URI:",
"request_receive_address": "接收地址:",
"request_select_address": "选择地址...",
"request_shielded_addrs": "-- 屏蔽地址 --",
"request_title": "请求付款",
"request_transparent_addrs": "-- 透明地址 --",
"request_uri_copied": "付款 URI 已复制到剪贴板",
"rescan": "重新扫描",
"reset_to_defaults": "重置为默认值",
"review_send": "审核发送",
"rpc_host": "RPC 主机",
"rpc_pass": "密码",
"rpc_port": "端口",
"rpc_user": "用户名",
"save": "保存",
"save_settings": "保存设置",
"save_z_transactions": "将 Z 交易保存到列表",
"search_placeholder": "搜索...",
"security": "安全",
"select_address": "选择地址...",
"select_receiving_address": "选择接收地址...",
"select_source_address": "选择来源地址...",
"send": "发送",
"send_amount": "金额",
"send_amount_details": "金额详情",
"send_amount_upper": "金额",
"send_clear_fields": "清除所有表单字段?",
"send_copy_error": "复制错误",
"send_dismiss": "关闭",
"send_error_copied": "错误已复制到剪贴板",
"send_error_prefix": "错误:%s",
"send_exceeds_available": "超过可用额 (%.8f)",
"send_fee": "手续费",
"send_fee_high": "高",
"send_fee_low": "低",
"send_fee_normal": "普通",
"send_form_restored": "表单已恢复",
"send_from_this_address": "从此地址发送",
"send_go_to_receive": "前往接收",
"send_keep": "保留",
"send_network_fee": "网络手续费",
"send_no_balance": "无余额",
"send_no_recent": "没有最近的发送",
"send_recent_sends": "最近发送",
"send_recipient": "收款方",
"send_select_source": "选择来源地址...",
"send_sending_from": "发送来源",
"send_submitting": "正在提交交易...",
"send_switch_to_receive": "切换到接收页面获取您的地址并开始接收资金。",
"send_to": "发送至",
"send_tooltip_enter_amount": "请输入发送金额",
"send_tooltip_exceeds_balance": "金额超过可用余额",
"send_tooltip_in_progress": "交易正在进行中",
"send_tooltip_invalid_address": "请输入有效的收款地址",
"send_tooltip_not_connected": "未连接到守护进程",
"send_tooltip_select_source": "请先选择来源地址",
"send_tooltip_syncing": "请等待区块链同步",
"send_total": "合计",
"send_transaction": "发送交易",
"send_tx_failed": "交易失败",
"send_tx_sent": "交易已发送!",
"send_tx_success": "交易发送成功!",
"send_txid_copied": "交易ID 已复制到剪贴板",
"send_txid_label": "TxID:%s",
"send_valid_shielded": "有效的屏蔽地址",
"send_valid_transparent": "有效的透明地址",
"send_wallet_empty": "您的钱包是空的",
"send_yes_clear": "是,清除",
"sending": "正在发送交易",
"sending_from": "发送来源",
"sent": "已发送",
"sent_filter": "已发送",
"sent_type": "已发送",
"sent_upper": "已发送",
"settings": "设置",
"setup_wizard": "设置向导",
"share": "分享",
"shield_check_status": "检查状态",
"shield_completed": "操作成功完成!",
"shield_description": "通过将透明地址的 coinbase 输出发送到屏蔽地址来屏蔽您的挖矿奖励。这可以隐藏您的挖矿收入,提高隐私性。",
"shield_from_address": "从地址:",
"shield_funds": "屏蔽资金",
"shield_in_progress": "操作进行中...",
"shield_max_utxos": "每次操作最大 UTXO 数",
"shield_merge_done": "屏蔽/合并完成!",
"shield_select_z": "选择 z 地址...",
"shield_started": "屏蔽操作已开始",
"shield_title": "屏蔽 Coinbase 奖励",
"shield_to_address": "至地址(屏蔽):",
"shield_utxo_limit": "UTXO 限制:",
"shield_wildcard_hint": "使用 '*' 从所有透明地址屏蔽",
"shielded": "屏蔽",
"shielded_to": "屏蔽至",
"shielded_type": "屏蔽",
"show": "显示",
"show_qr_code": "显示二维码",
"showing_transactions": "显示第 %d\xe2\x80\x93%d 笔,共 %d 笔交易(总计:%zu)",
"simple_background": "简单背景",
"start_mining": "开始挖矿",
"status": "状态",
"stop_external": "停止外部守护进程",
"stop_mining": "停止挖矿",
"submitting_transaction": "正在提交交易...",
"success": "成功",
"summary": "摘要",
"syncing": "同步中...",
"t_addresses": "T 地址",
"test_connection": "测试",
"theme": "主题",
"theme_effects": "主题效果",
"time_days_ago": "%d 天前",
"time_hours_ago": "%d 小时前",
"time_minutes_ago": "%d 分钟前",
"time_seconds_ago": "%d 秒前",
"to": "至",
"to_upper": "至",
"tools": "工具",
"total": "合计",
"transaction_id": "交易 ID",
"transaction_sent": "交易发送成功",
"transaction_sent_msg": "交易已发送!",
"transaction_url": "交易 URL",
"transactions": "交易",
"transactions_upper": "交易",
"transparent": "透明",
"tx_confirmations": "%d 次确认",
"tx_details_title": "交易详情",
"tx_from_address": "发送地址:",
"tx_id_label": "交易 ID:",
"tx_immature": "未成熟",
"tx_mined": "已挖得",
"tx_received": "已接收",
"tx_sent": "已发送",
"tx_to_address": "接收地址:",
"tx_view_explorer": "在浏览器中查看",
"txs_count": "%d 笔交易",
"type": "类型",
"ui_opacity": "界面透明度",
"unban": "解除封禁",
"unconfirmed": "未确认",
"undo_clear": "撤销清除",
"unknown": "未知",
"use_embedded_daemon": "使用内置 dragonxd",
"use_tor": "使用 Tor",
"validate_btn": "验证",
"validate_description": "输入一个 DragonX 地址来检查它是否有效以及是否属于此钱包。",
"validate_invalid": "无效",
"validate_is_mine": "此钱包拥有该地址",
"validate_not_mine": "不属于此钱包",
"validate_ownership": "所有权:",
"validate_results": "结果:",
"validate_shielded_type": "屏蔽(z 地址)",
"validate_status": "状态:",
"validate_title": "验证地址",
"validate_transparent_type": "透明(t 地址)",
"validate_type": "类型:",
"validate_valid": "有效",
"validating": "验证中...",
"verbose_logging": "详细日志",
"version": "版本",
"view": "查看",
"view_details": "查看详情",
"view_on_explorer": "在浏览器中查看",
"waiting_for_daemon": "等待守护进程连接...",
"wallet": "钱包",
"wallet_empty": "您的钱包是空的",
"wallet_empty_hint": "切换到接收页面获取您的地址并开始接收资金。",
"warning": "警告",
"warning_upper": "警告!",
"website": "网站",
"window_opacity": "窗口透明度",
"yes_clear": "是,清除",
"your_addresses": "您的地址",
"z_addresses": "Z 地址",
}
out = os.path.join(os.path.dirname(__file__), "..", "res", "lang", "zh.json")
with open(out, "w", encoding="utf-8") as f:
json.dump(translations, f, indent=4, ensure_ascii=False, sort_keys=True)
print(f"Wrote {len(translations)} Chinese translations to {os.path.abspath(out)}")
+45 -34
View File
@@ -248,8 +248,18 @@ void App::preFrame()
ui::schema::UISchema::instance().applyIfDirty();
}
// Refresh balance layout config after schema reload
// Refresh the per-frame layout cache (reads TOML values once)
ui::Layout::beginFrame();
// Refresh balance layout config only when schema changes
{
static uint32_t s_balanceLayoutGen = 0;
uint32_t gen = ui::schema::UISchema::instance().generation();
if (gen != s_balanceLayoutGen) {
s_balanceLayoutGen = gen;
ui::RefreshBalanceLayoutConfig();
}
}
// If font sizes changed in the TOML, rebuild the font atlas
if (ui::schema::UISchema::instance().consumeFontsChanged()) {
@@ -374,6 +384,7 @@ void App::update()
double memMB = xmrig_manager_->getMemoryUsageMB();
ps.memory_used = static_cast<int64_t>(memMB * 1024.0 * 1024.0);
ps.threads_active = xs.threads_active;
ps.pool_hashrate = xs.pool_hashrate;
ps.log_lines = xmrig_manager_->getRecentLines(30);
// Record hashrate sample for the chart
@@ -390,92 +401,91 @@ void App::update()
state_.mining.log_lines = embedded_daemon_->getRecentLines(50);
}
// Check daemon output for rescan progress
// Check daemon output for rescan progress (offloaded to worker)
if (embedded_daemon_ && embedded_daemon_->isRunning()) {
std::string newOutput = embedded_daemon_->getOutputSince(daemon_output_offset_);
if (!newOutput.empty()) {
// Look for rescan progress patterns in new output
// Hush patterns: "Still rescanning. At block X. Progress=Y" or "Rescanning..." with percentage
if (!newOutput.empty() && fast_worker_) {
fast_worker_->post([this, output = std::move(newOutput)]() -> rpc::RPCWorker::MainCb {
// Parse on worker thread — pure string work, no shared state access
bool foundRescan = false;
bool finished = false;
float rescanPct = 0.0f;
std::string lastStatus;
// Search line by line for rescan info
size_t pos = 0;
while (pos < newOutput.size()) {
size_t eol = newOutput.find('\n', pos);
if (eol == std::string::npos) eol = newOutput.size();
std::string line = newOutput.substr(pos, eol - pos);
while (pos < output.size()) {
size_t eol = output.find('\n', pos);
if (eol == std::string::npos) eol = output.size();
std::string line = output.substr(pos, eol - pos);
pos = eol + 1;
// Check for "Rescanning from height" (rescan starting)
if (line.find("Rescanning from height") != std::string::npos ||
line.find("Rescanning last") != std::string::npos) {
foundRescan = true;
state_.sync.rescan_status = line;
lastStatus = line;
}
// Check for "Still rescanning" with progress
auto stillIdx = line.find("Still rescanning");
if (stillIdx != std::string::npos) {
foundRescan = true;
// Try to extract progress (Progress=0.XXXX)
auto progIdx = line.find("Progress=");
if (progIdx != std::string::npos) {
size_t numStart = progIdx + 9; // strlen("Progress=")
size_t numStart = progIdx + 9;
size_t numEnd = numStart;
while (numEnd < line.size() && (std::isdigit(line[numEnd]) || line[numEnd] == '.')) {
numEnd++;
}
if (numEnd > numStart) {
try {
rescanPct = std::stof(line.substr(numStart, numEnd - numStart)) * 100.0f;
} catch (...) {}
try { rescanPct = std::stof(line.substr(numStart, numEnd - numStart)) * 100.0f; } catch (...) {}
}
}
state_.sync.rescan_status = line;
lastStatus = line;
}
// Check for "Rescanning..." with percentage (ShowProgress output)
auto rescIdx = line.find("Rescanning...");
if (rescIdx != std::string::npos) {
foundRescan = true;
// Try to extract percentage
auto pctIdx = line.find('%');
if (pctIdx != std::string::npos && pctIdx > 0) {
// Walk backwards to find the number
size_t numEnd = pctIdx;
size_t numStart = numEnd;
while (numStart > 0 && (std::isdigit(line[numStart - 1]) || line[numStart - 1] == '.')) {
numStart--;
}
if (numStart < numEnd) {
try {
rescanPct = std::stof(line.substr(numStart, numEnd - numStart));
} catch (...) {}
try { rescanPct = std::stof(line.substr(numStart, numEnd - numStart)); } catch (...) {}
}
}
state_.sync.rescan_status = line;
lastStatus = line;
}
// Check for "Done rescanning" (rescan complete)
if (line.find("Done rescanning") != std::string::npos ||
line.find("Rescan complete") != std::string::npos) {
finished = true;
}
}
// Return callback to apply results on main thread
return [this, foundRescan, finished, rescanPct, status = std::move(lastStatus)]() {
if (finished) {
if (state_.sync.rescanning) {
ui::Notifications::instance().success("Blockchain rescan complete");
}
state_.sync.rescanning = false;
state_.sync.rescan_progress = 1.0f;
state_.sync.rescan_status.clear();
}
}
if (foundRescan) {
} else if (foundRescan) {
state_.sync.rescanning = true;
if (rescanPct > 0.0f) {
state_.sync.rescan_progress = rescanPct / 100.0f;
}
if (!status.empty()) {
state_.sync.rescan_status = status;
}
}
};
});
}
} else if (!embedded_daemon_ || !embedded_daemon_->isRunning()) {
// Clear rescan state if daemon is not running (but preserve during restart)
if (state_.sync.rescanning && state_.sync.rescan_progress >= 0.99f) {
@@ -899,11 +909,11 @@ void App::render()
if (gradient_tex_ != 0) {
sbStatus.gradientTexID = gradient_tex_;
}
// Count unconfirmed transactions
// Count unconfirmed transactions (pending in mempool, not conflicted/orphaned)
{
int unconf = 0;
for (const auto& tx : state_.transactions) {
if (!tx.isConfirmed()) ++unconf;
if (tx.confirmations == 0) ++unconf;
}
sbStatus.unconfirmedTxCount = unconf;
}
@@ -1350,7 +1360,8 @@ void App::renderStatusBar()
ImGui::TextColored(ImVec4(0.6f, 0.8f, 1.0f, 1.0f), "Rescanning%s", dotStr);
}
} else if (state_.sync.syncing) {
int blocksLeft = state_.sync.headers - state_.sync.blocks;
int chainTip = state_.longestchain > 0 ? state_.longestchain : state_.sync.headers;
int blocksLeft = chainTip - state_.sync.blocks;
if (blocksLeft < 0) blocksLeft = 0;
ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.0f, 1.0f), "Syncing %.1f%% (%d left)",
state_.sync.verification_progress * 100.0, blocksLeft);
+13 -8
View File
@@ -742,9 +742,14 @@ void App::refreshData()
state_.sync.headers = blockInfo["headers"].get<int>();
if (blockInfo.contains("verificationprogress"))
state_.sync.verification_progress = blockInfo["verificationprogress"].get<double>();
state_.sync.syncing = (state_.sync.blocks < state_.sync.headers - 2);
if (blockInfo.contains("longestchain"))
state_.longestchain = blockInfo["longestchain"].get<int>();
// Use longestchain (actual network tip) for sync check when available,
// since headers can be inflated by misbehaving peers.
if (state_.longestchain > 0)
state_.sync.syncing = (state_.sync.blocks < state_.longestchain - 2);
else
state_.sync.syncing = (state_.sync.blocks < state_.sync.headers - 2);
if (blockInfo.contains("notarized"))
state_.notarized = blockInfo["notarized"].get<int>();
}
@@ -886,12 +891,12 @@ void App::refreshBalance()
state_.sync.headers = blockInfo["headers"].get<int>();
if (blockInfo.contains("verificationprogress"))
state_.sync.verification_progress = blockInfo["verificationprogress"].get<double>();
state_.sync.syncing = (state_.sync.blocks < state_.sync.headers - 2);
// Consolidate chain-tip fields that were previously fetched
// via a separate getinfo call in refreshMiningInfo.
if (blockInfo.contains("longestchain"))
state_.longestchain = blockInfo["longestchain"].get<int>();
if (state_.longestchain > 0)
state_.sync.syncing = (state_.sync.blocks < state_.longestchain - 2);
else
state_.sync.syncing = (state_.sync.blocks < state_.sync.headers - 2);
if (blockInfo.contains("notarized"))
state_.notarized = blockInfo["notarized"].get<int>();
}
@@ -1182,7 +1187,7 @@ void App::refreshPrice()
}
std::string response_data;
const char* url = "https://api.coingecko.com/api/v3/simple/price?ids=hush&vs_currencies=usd,btc&include_24hr_change=true&include_24hr_vol=true&include_market_cap=true";
const char* url = "https://api.coingecko.com/api/v3/simple/price?ids=dragonx-2&vs_currencies=usd,btc&include_24hr_change=true&include_24hr_vol=true&include_market_cap=true";
auto write_callback = [](void* contents, size_t size, size_t nmemb, std::string* userp) -> size_t {
size_t totalSize = size * nmemb;
@@ -1205,8 +1210,8 @@ void App::refreshPrice()
if (res == CURLE_OK && http_code == 200) {
auto j = json::parse(response_data);
if (j.contains("hush")) {
const auto& data = j["hush"];
if (j.contains("dragonx-2")) {
const auto& data = j["dragonx-2"];
market.price_usd = data.value("usd", 0.0);
market.price_btc = data.value("btc", 0.0);
market.change_24h = data.value("usd_24h_change", 0.0);
+67
View File
@@ -244,6 +244,18 @@ bool XmrigManager::start(const Config& cfg) {
}
stats_ = PoolStats{};
// Extract pool hostname for stats API queries
{
std::string url = cfg.pool_url;
// Strip protocol prefix if present
auto pos = url.find("://");
if (pos != std::string::npos) url = url.substr(pos + 3);
// Strip port suffix
pos = url.find(':');
if (pos != std::string::npos) url = url.substr(0, pos);
pool_host_ = url;
}
// Find binary
std::string binary = findXmrigBinary();
if (binary.empty()) {
@@ -572,6 +584,7 @@ void XmrigManager::monitorProcess() {
}
int poll_counter = 0;
int pool_api_counter = 0;
while (!should_stop_) {
drainOutput();
@@ -605,6 +618,12 @@ void XmrigManager::monitorProcess() {
fetchStatsHttp();
}
// Poll pool-side stats every ~30 seconds (300 * 100ms)
if (++pool_api_counter >= 300) {
pool_api_counter = 0;
fetchPoolApiStats();
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
drainOutput(); // Final drain
@@ -711,5 +730,53 @@ void XmrigManager::fetchStatsHttp() {
}
}
// ============================================================================
// Pool-side stats (hashrate reported by the pool)
// ============================================================================
void XmrigManager::fetchPoolApiStats() {
if (state_ != State::Running || pool_host_.empty()) return;
// Query the pool's public stats API
std::string url = "https://" + pool_host_ + "/api/stats";
std::string responseData;
CURL* curl = curl_easy_init();
if (!curl) return;
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlWriteCb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 5000L);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 3000L);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
CURLcode res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if (res != CURLE_OK) return;
try {
json resp = json::parse(responseData);
// Pool stats API format: { "pools": { "<name>": { "hashrate": ... } } }
double poolHR = 0;
if (resp.contains("pools") && resp["pools"].is_object()) {
for (auto& [key, pool] : resp["pools"].items()) {
if (pool.contains("hashrate") && pool["hashrate"].is_number()) {
poolHR = pool["hashrate"].get<double>();
break; // Use the first pool entry
}
}
}
std::lock_guard<std::mutex> lk(stats_mutex_);
stats_.pool_hashrate = poolHR;
} catch (...) {
// Malformed response — ignore
}
}
} // namespace daemon
} // namespace dragonx
+4
View File
@@ -49,6 +49,8 @@ public:
int64_t memory_total = 0; // bytes
int64_t memory_used = 0; // bytes (resident set size)
int threads_active = 0; // actual mining threads
// Pool-side hashrate (from pool stats API, not xmrig)
double pool_hashrate = 0;
};
/// User-facing config (maps 1:1 to UI fields / Settings)
@@ -138,6 +140,7 @@ private:
void drainOutput();
void appendOutput(const char* data, size_t len);
void fetchStatsHttp(); // Blocking HTTP call — runs on monitor thread only
void fetchPoolApiStats(); // Fetch pool-side stats (hashrate) from pool HTTP API
std::atomic<State> state_{State::Stopped};
std::string last_error_;
@@ -149,6 +152,7 @@ private:
int api_port_ = 0;
std::string api_token_;
int threads_ = 0; // Thread count for mining
std::string pool_host_; // Pool hostname for stats API
PoolStats stats_;
mutable std::mutex stats_mutex_;
+3 -12
View File
@@ -11,19 +11,10 @@ const std::vector<ExchangeInfo>& getExchangeRegistry()
{
static const std::vector<ExchangeInfo> registry = {
{
"TradeOgre",
"https://tradeogre.com",
"Nonkyc.io",
"https://nonkyc.io",
{
{"DRGX", "BTC", "DRGX/BTC", "https://tradeogre.com/exchange/DRGX-BTC"},
{"DRGX", "LTC", "DRGX/LTC", "https://tradeogre.com/exchange/DRGX-LTC"},
{"DRGX", "USDT", "DRGX/USDT", "https://tradeogre.com/exchange/DRGX-USDT"},
}
},
{
"Exbitron",
"https://www.exbitron.com",
{
{"DRGX", "USDT", "DRGX/USDT", "https://www.exbitron.com/trading/drgxusdt"},
{"DRGX", "USDT", "DRGX/USDT", "https://nonkyc.io/market/DRGX_USDT"},
}
},
};
+3
View File
@@ -162,6 +162,9 @@ struct PoolMiningState {
int64_t memory_used = 0;
int threads_active = 0;
// Pool-side hashrate (from pool stats API)
double pool_hashrate = 0;
// Hashrate history for chart (mirrors MiningInfo::hashrate_history)
std::vector<double> hashrate_history;
static constexpr int MAX_HISTORY = 60; // 5 minutes at ~5s intervals
+1
View File
@@ -12,3 +12,4 @@ INCBIN(ubuntu_regular, "@CMAKE_SOURCE_DIR@/res/fonts/Ubuntu-R.ttf");
INCBIN(ubuntu_light, "@CMAKE_SOURCE_DIR@/res/fonts/Ubuntu-Light.ttf");
INCBIN(ubuntu_medium, "@CMAKE_SOURCE_DIR@/res/fonts/Ubuntu-Medium.ttf");
INCBIN(material_icons, "@CMAKE_SOURCE_DIR@/res/fonts/MaterialIcons-Regular.ttf");
INCBIN(noto_cjk_subset, "@CMAKE_SOURCE_DIR@/res/fonts/NotoSansCJK-Subset.otf");
+3
View File
@@ -26,4 +26,7 @@ extern "C" {
extern const unsigned char g_material_icons_data[];
extern const unsigned int g_material_icons_size;
extern const unsigned char g_noto_cjk_subset_data[];
extern const unsigned int g_noto_cjk_subset_size;
}
+3389 -366
View File
File diff suppressed because it is too large Load Diff
+3389 -366
View File
File diff suppressed because it is too large Load Diff
+3496 -366
View File
File diff suppressed because it is too large Load Diff
+3763 -403
View File
File diff suppressed because it is too large Load Diff
+3335 -352
View File
File diff suppressed because it is too large Load Diff
+3363 -364
View File
File diff suppressed because it is too large Load Diff
+4560 -477
View File
File diff suppressed because it is too large Load Diff
+3047 -337
View File
File diff suppressed because it is too large Load Diff
+12 -12
View File
@@ -572,12 +572,12 @@ void AcrylicMaterial::drawRect(ImDrawList* drawList, const ImVec2& pMin, const I
float u1 = localX1 / viewportWidth_;
float v1 = 1.0f - localY1 / viewportHeight_; // V at bottom-right (low)
// Draw the blurred background. The glass opacity comes from
// fallbackColor.w — blur always renders at full strength.
// UI opacity is handled separately by card surface alpha.
// Draw the blurred background. Scale by both the glass preset
// opacity (fallbackColor.w) AND the user's UI opacity slider so
// that lowering card opacity lets the sharp background through.
ImTextureID blurTex = getBlurredTexture();
uint8_t glassAlpha = static_cast<uint8_t>(
std::min(255.0f, std::max(0.0f, params.fallbackColor.w * 255.0f)));
std::min(255.0f, std::max(0.0f, params.fallbackColor.w * settings_.uiOpacity * 255.0f)));
if (blurTex) {
drawList->AddImageRounded(
@@ -774,11 +774,11 @@ AcrylicFallback AcrylicMaterial::detectFallback() const
void AcrylicMaterial::drawTintedRect(ImDrawList* drawList, const ImVec2& pMin, const ImVec2& pMax,
const AcrylicParams& params, float rounding)
{
// Draw semi-transparent tint without blur
// This is the "Tinted Only" fallback mode (not affected by UI opacity)
// Draw semi-transparent tint without blur — scale by UI opacity
// so the tinted fallback also respects the card transparency slider.
ImU32 tintCol = ImGui::ColorConvertFloat4ToU32(
ImVec4(params.tintColor.x, params.tintColor.y, params.tintColor.z,
params.tintColor.w * params.tintOpacity * 0.9f)
params.tintColor.w * params.tintOpacity * 0.9f * settings_.uiOpacity)
);
drawList->AddRectFilled(pMin, pMax, tintCol, rounding);
@@ -1528,11 +1528,11 @@ void AcrylicMaterial::drawRect(ImDrawList* drawList, const ImVec2& pMin, const I
(void*)blurTex, u0, v0, u1, v1);
}
// Draw the blurred background. Glass opacity from fallbackColor
// alpha. Blur always renders at full strength; UI opacity is
// handled separately by card surface alpha.
// Draw the blurred background. Scale by both the glass preset
// opacity (fallbackColor.w) AND the user's UI opacity slider so
// that lowering card opacity lets the sharp background through.
uint8_t glassAlpha = (uint8_t)std::min(255.f,
std::max(0.f, params.fallbackColor.w * 255.f));
std::max(0.f, params.fallbackColor.w * settings_.uiOpacity * 255.f));
if (blurTex) {
drawList->AddImageRounded(
@@ -1559,7 +1559,7 @@ void AcrylicMaterial::drawTintedRect(ImDrawList* drawList, const ImVec2& pMin, c
{
ImU32 tintCol = ImGui::ColorConvertFloat4ToU32(
ImVec4(params.tintColor.x, params.tintColor.y, params.tintColor.z,
params.tintColor.w * params.tintOpacity * 0.9f));
params.tintColor.w * params.tintOpacity * 0.9f * settings_.uiOpacity));
drawList->AddRectFilled(pMin, pMax, tintCol, rounding);
// Noise grain overlay — single draw call via pre-tiled texture
+6
View File
@@ -105,6 +105,12 @@ public:
bool hasSandstorm() const { return enabled_ && sandstorm_.enabled; }
bool hasViewportOverlay() const { return enabled_ && (viewport_overlay_.colorWashEnabled || viewport_overlay_.vignetteEnabled); }
/// True when any per-panel visual effect is active (rainbow, shimmer, specular, edge, ember, gradient)
bool hasAnyPanelEffect() const {
return hasRainbowBorder() || hasShimmer() || hasSpecularGlare()
|| hasEdgeTrace() || hasEmberRise() || hasGradientBorder();
}
/// True when any time-dependent effect is active and needs continuous redraws
bool hasActiveAnimation() const {
if (!enabled_) return false;
+135 -52
View File
@@ -185,6 +185,102 @@ inline float kItemSpacing() { return schema::UI().drawElement("spacing", "it
inline float kLabelValueGap() { return schema::UI().drawElement("spacing", "label-value").sizeOr(4.0f) * dpiScale(); }
inline float kSeparatorGap() { return schema::UI().drawElement("spacing", "separator").sizeOr(20.0f) * dpiScale(); }
// ============================================================================
// Per-frame cache — populated once via beginFrame(), avoids repeated
// schema hash-map lookups for the hottest accessors.
// ============================================================================
namespace detail {
struct FrameCache {
uint32_t gen = 0; // schema generation when last populated
float rawDp = 1.0f; // rawDpiScale() snapshot
float dp = 1.0f; // dpiScale() snapshot
// Spacing tokens (raw, unscaled)
float spXs = 2.0f;
float spSm = 4.0f;
float spMd = 8.0f;
float spLg = 12.0f;
float spXl = 16.0f;
float spXxl = 24.0f;
// Responsive scale config
float refW = 1200.0f;
float refH = 700.0f;
float minHS = 0.5f;
float maxHS = 1.5f;
float minVS = 0.5f;
float maxVS = 1.4f;
float minDen = 0.6f;
float maxDen = 1.2f;
// Breakpoint thresholds (raw, unscaled)
float compactW = 500.0f;
float compactH = 450.0f;
float expandedW = 900.0f;
float expandedH = 750.0f;
// Glass / card helpers (raw, unscaled)
float glassRnd = 8.0f;
float cardPad = 12.0f;
float cardGap = 8.0f;
};
inline FrameCache& frameCache() { static FrameCache c; return c; }
} // namespace detail
/**
* @brief Refresh the per-frame layout cache.
*
* Call once per frame (e.g., from App::preFrame) BEFORE any rendering.
* Reads all high-frequency TOML values into fast statics. Invalidated
* automatically when the schema generation changes (hot-reload).
*/
inline void beginFrame() {
auto& c = detail::frameCache();
uint32_t g = schema::UI().generation();
// Also capture DPI each frame (can change on display-scale events)
float curRawDp = rawDpiScale();
float curDp = dpiScale();
if (g == c.gen && curRawDp == c.rawDp && curDp == c.dp) return;
c.gen = g;
c.rawDp = curRawDp;
c.dp = curDp;
const auto& S = schema::UI();
// Spacing tokens
c.spXs = S.drawElement("spacing-tokens", "xs").sizeOr(2.0f);
c.spSm = S.drawElement("spacing-tokens", "sm").sizeOr(4.0f);
c.spMd = S.drawElement("spacing-tokens", "md").sizeOr(8.0f);
c.spLg = S.drawElement("spacing-tokens", "lg").sizeOr(12.0f);
c.spXl = S.drawElement("spacing-tokens", "xl").sizeOr(16.0f);
c.spXxl = S.drawElement("spacing-tokens", "xxl").sizeOr(24.0f);
// Responsive config
c.refW = S.drawElement("responsive", "ref-width").sizeOr(1200.0f);
c.refH = S.drawElement("responsive", "ref-height").sizeOr(700.0f);
c.minHS = S.drawElement("responsive", "min-h-scale").sizeOr(0.5f);
c.maxHS = S.drawElement("responsive", "max-h-scale").sizeOr(1.5f);
c.minVS = S.drawElement("responsive", "min-v-scale").sizeOr(0.5f);
c.maxVS = S.drawElement("responsive", "max-v-scale").sizeOr(1.4f);
c.minDen = S.drawElement("responsive", "min-density").sizeOr(0.6f);
c.maxDen = S.drawElement("responsive", "max-density").sizeOr(1.2f);
// Breakpoints
c.compactW = S.drawElement("responsive", "compact-width").sizeOr(500.0f);
c.compactH = S.drawElement("responsive", "compact-height").sizeOr(450.0f);
c.expandedW = S.drawElement("responsive", "expanded-width").sizeOr(900.0f);
c.expandedH = S.drawElement("responsive", "expanded-height").sizeOr(750.0f);
// Glass / card
c.glassRnd = S.drawElement("responsive", "glass-rounding").sizeOr(8.0f);
c.cardPad = S.drawElement("responsive", "card-inner-padding").sizeOr(12.0f);
c.cardGap = S.drawElement("responsive", "card-gap").sizeOr(8.0f);
}
// ============================================================================
// Layout Tier (responsive breakpoints)
// ============================================================================
@@ -203,12 +299,12 @@ enum class LayoutTier { Compact, Normal, Expanded };
* Call after ImGui::BeginChild for the content area, or pass explicit avail.
*/
inline LayoutTier currentTier() {
const auto& S = schema::UI();
float dp = dpiScale();
float cw = S.drawElement("responsive", "compact-width").sizeOr(500.0f) * dp;
float ch = S.drawElement("responsive", "compact-height").sizeOr(450.0f) * dp;
float ew = S.drawElement("responsive", "expanded-width").sizeOr(900.0f) * dp;
float eh = S.drawElement("responsive", "expanded-height").sizeOr(750.0f) * dp;
const auto& c = detail::frameCache();
float dp = c.dp;
float cw = c.compactW * dp;
float ch = c.compactH * dp;
float ew = c.expandedW * dp;
float eh = c.expandedH * dp;
ImVec2 avail = ImGui::GetContentRegionAvail();
if (avail.x < cw || avail.y < ch) return LayoutTier::Compact;
if (avail.x > ew && avail.y > eh) return LayoutTier::Expanded;
@@ -216,12 +312,12 @@ inline LayoutTier currentTier() {
}
inline LayoutTier currentTier(float availW, float availH) {
const auto& S = schema::UI();
float dp = dpiScale();
float cw = S.drawElement("responsive", "compact-width").sizeOr(500.0f) * dp;
float ch = S.drawElement("responsive", "compact-height").sizeOr(450.0f) * dp;
float ew = S.drawElement("responsive", "expanded-width").sizeOr(900.0f) * dp;
float eh = S.drawElement("responsive", "expanded-height").sizeOr(750.0f) * dp;
const auto& c = detail::frameCache();
float dp = c.dp;
float cw = c.compactW * dp;
float ch = c.compactH * dp;
float ew = c.expandedW * dp;
float eh = c.expandedH * dp;
if (availW < cw || availH < ch) return LayoutTier::Compact;
if (availW > ew && availH > eh) return LayoutTier::Expanded;
return LayoutTier::Normal;
@@ -240,15 +336,10 @@ inline LayoutTier currentTier(float availW, float availH) {
* while emitting physical-pixel results.
*/
inline float hScale(float availWidth) {
const auto& S = schema::UI();
float rawDp = rawDpiScale(); // reference uses hardware DPI only
float dp = dpiScale(); // output includes user font scale
float rw = S.drawElement("responsive", "ref-width").sizeOr(1200.0f) * rawDp;
float minH = S.drawElement("responsive", "min-h-scale").sizeOr(0.5f);
float maxH = S.drawElement("responsive", "max-h-scale").sizeOr(1.5f);
// Clamp the logical (DPI-neutral) portion, then apply effective DPI.
float logical = std::clamp(availWidth / rw, minH, maxH);
return logical * dp;
const auto& c = detail::frameCache();
float rw = c.refW * c.rawDp;
float logical = std::clamp(availWidth / rw, c.minHS, c.maxHS);
return logical * c.dp;
}
inline float hScale() {
@@ -261,14 +352,10 @@ inline float hScale() {
* Same decomposition as hScale — logical clamp × DPI.
*/
inline float vScale(float availHeight) {
const auto& S = schema::UI();
float rawDp = rawDpiScale(); // reference uses hardware DPI only
float dp = dpiScale(); // output includes user font scale
float rh = S.drawElement("responsive", "ref-height").sizeOr(700.0f) * rawDp;
float minV = S.drawElement("responsive", "min-v-scale").sizeOr(0.5f);
float maxV = S.drawElement("responsive", "max-v-scale").sizeOr(1.4f);
float logical = std::clamp(availHeight / rh, minV, maxV);
return logical * dp;
const auto& c = detail::frameCache();
float rh = c.refH * c.rawDp;
float logical = std::clamp(availHeight / rh, c.minVS, c.maxVS);
return logical * c.dp;
}
inline float vScale() {
@@ -282,14 +369,10 @@ inline float vScale() {
* values scale proportionally with fonts and style.
*/
inline float densityScale(float availHeight) {
const auto& S = schema::UI();
float rawDp = rawDpiScale(); // reference uses hardware DPI only
float dp = dpiScale(); // output includes user font scale
float rh = S.drawElement("responsive", "ref-height").sizeOr(700.0f) * rawDp;
float minDen = S.drawElement("responsive", "min-density").sizeOr(0.6f);
float maxDen = S.drawElement("responsive", "max-density").sizeOr(1.2f);
float logical = std::clamp(availHeight / rh, minDen, maxDen);
return logical * dp;
const auto& c = detail::frameCache();
float rh = c.refH * c.rawDp;
float logical = std::clamp(availHeight / rh, c.minDen, c.maxDen);
return logical * c.dp;
}
inline float densityScale() {
@@ -301,33 +384,33 @@ inline float densityScale() {
// ============================================================================
/** @brief Get spacing token scaled by current density. */
inline float spacingXs() { return schema::UI().drawElement("spacing-tokens", "xs").sizeOr(2.0f) * densityScale(); }
inline float spacingSm() { return schema::UI().drawElement("spacing-tokens", "sm").sizeOr(4.0f) * densityScale(); }
inline float spacingMd() { return schema::UI().drawElement("spacing-tokens", "md").sizeOr(8.0f) * densityScale(); }
inline float spacingLg() { return schema::UI().drawElement("spacing-tokens", "lg").sizeOr(12.0f) * densityScale(); }
inline float spacingXl() { return schema::UI().drawElement("spacing-tokens", "xl").sizeOr(16.0f) * densityScale(); }
inline float spacingXxl() { return schema::UI().drawElement("spacing-tokens", "xxl").sizeOr(24.0f) * densityScale(); }
inline float spacingXs() { return detail::frameCache().spXs * densityScale(); }
inline float spacingSm() { return detail::frameCache().spSm * densityScale(); }
inline float spacingMd() { return detail::frameCache().spMd * densityScale(); }
inline float spacingLg() { return detail::frameCache().spLg * densityScale(); }
inline float spacingXl() { return detail::frameCache().spXl * densityScale(); }
inline float spacingXxl() { return detail::frameCache().spXxl * densityScale(); }
/** @brief Get raw (unscaled) spacing token. */
inline float spacingXsRaw() { return schema::UI().drawElement("spacing-tokens", "xs").sizeOr(2.0f); }
inline float spacingSmRaw() { return schema::UI().drawElement("spacing-tokens", "sm").sizeOr(4.0f); }
inline float spacingMdRaw() { return schema::UI().drawElement("spacing-tokens", "md").sizeOr(8.0f); }
inline float spacingLgRaw() { return schema::UI().drawElement("spacing-tokens", "lg").sizeOr(12.0f); }
inline float spacingXlRaw() { return schema::UI().drawElement("spacing-tokens", "xl").sizeOr(16.0f); }
inline float spacingXxlRaw() { return schema::UI().drawElement("spacing-tokens", "xxl").sizeOr(24.0f); }
inline float spacingXsRaw() { return detail::frameCache().spXs; }
inline float spacingSmRaw() { return detail::frameCache().spSm; }
inline float spacingMdRaw() { return detail::frameCache().spMd; }
inline float spacingLgRaw() { return detail::frameCache().spLg; }
inline float spacingXlRaw() { return detail::frameCache().spXl; }
inline float spacingXxlRaw() { return detail::frameCache().spXxl; }
// ============================================================================
// Responsive Globals Helpers
// ============================================================================
/** @brief Default glass panel rounding (8.0 default). */
inline float glassRounding() { return schema::UI().drawElement("responsive", "glass-rounding").sizeOr(8.0f) * dpiScale(); }
inline float glassRounding() { return detail::frameCache().glassRnd * dpiScale(); }
/** @brief Default card inner padding (12.0 default). */
inline float cardInnerPadding() { return schema::UI().drawElement("responsive", "card-inner-padding").sizeOr(12.0f) * dpiScale(); }
inline float cardInnerPadding() { return detail::frameCache().cardPad * dpiScale(); }
/** @brief Default card gap (8.0 default). */
inline float cardGap() { return schema::UI().drawElement("responsive", "card-gap").sizeOr(8.0f) * dpiScale(); }
inline float cardGap() { return detail::frameCache().cardGap * dpiScale(); }
/**
* @brief Compute a responsive card height from a base value.
+19 -9
View File
@@ -351,18 +351,24 @@ inline void DrawGlassPanel(ImDrawList* dl, const ImVec2& pMin,
// Noise grain overlay — drawn OVER the surface overlay so card
// opacity doesn't hide it. Gives cards a tactile paper feel.
// Noise tint is cached per-generation, opacity checked each panel.
{
float noiseMul = dragonx::ui::effects::ImGuiAcrylic::GetNoiseOpacity();
if (noiseMul > 0.0f) {
uint8_t origAlpha = (s_glassNoiseTint >> IM_COL32_A_SHIFT) & 0xFF;
uint8_t scaledAlpha = static_cast<uint8_t>(std::min(255.0f, origAlpha * noiseMul));
// Tint base color changes only on theme reload; opacity slider may change per-frame
static uint32_t s_noiseGen = 0;
static uint8_t s_baseAlpha = 0;
if (curGen != s_noiseGen) {
s_noiseGen = curGen;
s_baseAlpha = (s_glassNoiseTint >> IM_COL32_A_SHIFT) & 0xFF;
}
uint8_t scaledAlpha = static_cast<uint8_t>(std::min(255.0f, s_baseAlpha * noiseMul));
ImU32 noiseTint = (s_glassNoiseTint & ~(0xFFu << IM_COL32_A_SHIFT)) | (scaledAlpha << IM_COL32_A_SHIFT);
float inset = spec.rounding * 0.3f;
ImVec2 clipMin(pMin.x + inset, pMin.y + inset);
ImVec2 clipMax(pMax.x - inset, pMax.y - inset);
dl->PushClipRect(clipMin, clipMax, true);
dragonx::util::DrawTiledNoiseRect(dl, clipMin, clipMax, noiseTint);
dl->PopClipRect();
ImVec2 noiseMin(pMin.x + inset, pMin.y + inset);
ImVec2 noiseMax(pMax.x - inset, pMax.y - inset);
// Image rect matches clip bounds exactly — no PushClipRect needed
dragonx::util::DrawTiledNoiseRect(dl, noiseMin, noiseMax, noiseTint);
}
}
@@ -375,6 +381,7 @@ inline void DrawGlassPanel(ImDrawList* dl, const ImVec2& pMin,
// Theme visual effects drawn on ForegroundDrawList so they
// render above card content (text, values, etc.), not below.
auto& fx = effects::ThemeEffects::instance();
if (fx.hasAnyPanelEffect()) {
ImDrawList* fxDl = ImGui::GetForegroundDrawList();
if (fx.hasRainbowBorder()) {
fx.drawRainbowBorder(fxDl, pMin, pMax, spec.rounding, spec.borderWidth);
@@ -387,6 +394,7 @@ inline void DrawGlassPanel(ImDrawList* dl, const ImVec2& pMin,
}
// Per-panel theme effects: edge trace + ember rise
fx.drawPanelEffects(fxDl, pMin, pMax, spec.rounding);
}
} else {
// Low-spec opaque fallback
dl->AddRectFilled(pMin, pMax,
@@ -749,8 +757,10 @@ inline void ApplySmoothScroll(float speed = 12.0f)
s.current = actualY;
}
// Capture mouse wheel when hovered
if (ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows)) {
// Capture mouse wheel when hovered, but not when a popup (combo dropdown
// etc.) is open — let the popup handle its own scrolling exclusively.
bool popupOpen = ImGui::IsPopupOpen("", ImGuiPopupFlags_AnyPopupId | ImGuiPopupFlags_AnyPopupLevel);
if (!popupOpen && ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows)) {
float wheel = ImGui::GetIO().MouseWheel;
if (wheel != 0.0f) {
float step = ImGui::GetTextLineHeightWithSpacing() * 3.0f;
+35 -2
View File
@@ -246,11 +246,14 @@ ImFont* Typography::loadFont(ImGuiIO& io, int weight, float size, const char* na
cfg.PixelSnapH = true;
// Include default ASCII + Latin, Latin Extended (for Spanish/multilingual),
// plus arrows (⇄ U+21C4), math (≈ U+2248),
// general punctuation (— U+2014, … U+2026, etc.)
// Cyrillic (for Russian), Greek, plus arrows (⇄ U+21C4),
// math (≈ U+2248), general punctuation (— U+2014, … U+2026, etc.)
static const ImWchar glyphRanges[] = {
0x0020, 0x00FF, // Basic Latin + Latin-1 Supplement
0x0100, 0x024F, // Latin Extended-A + Latin Extended-B (Spanish, etc.)
0x0370, 0x03FF, // Greek and Coptic
0x0400, 0x04FF, // Cyrillic (Russian, Ukrainian, etc.)
0x0500, 0x052F, // Cyrillic Supplement
0x2000, 0x206F, // General Punctuation (em dash, ellipsis, etc.)
0x2190, 0x21FF, // Arrows (includes ⇄ U+21C4, ↻ U+21BB)
0x2200, 0x22FF, // Mathematical Operators (includes ≈ U+2248)
@@ -269,6 +272,36 @@ ImFont* Typography::loadFont(ImGuiIO& io, int weight, float size, const char* na
if (font) {
DEBUG_LOGF("Typography: Loaded %s (%.0fpx) as '%s'\n", name, size, cfg.Name);
// Merge CJK fallback glyphs (Chinese/Japanese/Korean) from subset font
if (g_noto_cjk_subset_size > 0) {
void* cjkCopy = IM_ALLOC(g_noto_cjk_subset_size);
memcpy(cjkCopy, g_noto_cjk_subset_data, g_noto_cjk_subset_size);
ImFontConfig cjkCfg;
cjkCfg.FontDataOwnedByAtlas = true;
cjkCfg.MergeMode = true; // merge into the font we just loaded
cjkCfg.OversampleH = 1;
cjkCfg.OversampleV = 1;
cjkCfg.PixelSnapH = true;
cjkCfg.GlyphMinAdvanceX = 0;
// CJK Unified Ideographs + Hiragana + Katakana + Hangul + fullwidth punctuation
static const ImWchar cjkRanges[] = {
0x2E80, 0x2FDF, // CJK Radicals
0x3000, 0x30FF, // CJK Symbols, Hiragana, Katakana
0x3100, 0x312F, // Bopomofo
0x31F0, 0x31FF, // Katakana Extensions
0x3400, 0x4DBF, // CJK Extension A
0x4E00, 0x9FFF, // CJK Unified Ideographs
0xAC00, 0xD7AF, // Hangul Syllables
0xFF00, 0xFFEF, // Fullwidth Forms
0,
};
cjkCfg.GlyphRanges = cjkRanges;
snprintf(cjkCfg.Name, sizeof(cjkCfg.Name), "NotoSansCJK %.0fpx (merge)", size);
io.Fonts->AddFontFromMemoryTTF(cjkCopy, g_noto_cjk_subset_size, size, &cjkCfg);
}
} else {
DEBUG_LOGF("Typography: Failed to load %s\n", name);
IM_FREE(fontDataCopy);
File diff suppressed because it is too large Load Diff
+33 -8
View File
@@ -45,6 +45,7 @@ bool UISchema::loadFromFile(const std::string& path) {
// Clear previous data
elements_.clear();
styleCache_.clear();
backgroundImagePath_.clear();
logoImagePath_.clear();
@@ -92,6 +93,7 @@ bool UISchema::loadFromFile(const std::string& path) {
overlayPath_.clear(); // No overlay yet
loaded_ = true;
dirty_ = false;
++generation_;
// Record initial modification time
try {
@@ -126,6 +128,7 @@ bool UISchema::loadFromString(const std::string& tomlStr, const std::string& lab
// Clear previous data
elements_.clear();
styleCache_.clear();
backgroundImagePath_.clear();
logoImagePath_.clear();
@@ -222,6 +225,7 @@ bool UISchema::mergeOverlayFromFile(const std::string& path) {
// Track overlay file for hot-reload
currentPath_ = path;
++generation_;
styleCache_.clear(); // Invalidate after overlay merges new elements
try {
lastModTime_ = std::filesystem::last_write_time(path);
} catch (const std::filesystem::filesystem_error&) {}
@@ -495,6 +499,9 @@ void UISchema::applyIfDirty() {
if (!dirty_) return;
dirty_ = false;
// Clear style cache before snapshot so we re-read from TOML
styleCache_.clear();
// Snapshot font sizes before reload for change detection
static const char* fontKeys[] = {
"h1", "h2", "h3", "h4", "h5", "h6",
@@ -513,10 +520,17 @@ void UISchema::applyIfDirty() {
DEBUG_LOGF("[UISchema] Hot-reload: re-parsing %s\n", currentPath_.c_str());
// Save overlay path before reloading — loadFromFile/loadFromString clear it
std::string savedOverlay = overlayPath_;
// If an overlay is active, reload base first then re-merge overlay
if (!overlayPath_.empty() && !basePath_.empty()) {
if (!savedOverlay.empty() && !basePath_.empty()) {
loadFromFile(basePath_);
mergeOverlayFromFile(overlayPath_);
mergeOverlayFromFile(savedOverlay);
} else if (!savedOverlay.empty() && !embeddedTomlStr_.empty()) {
// Embedded base (e.g. Windows single-file): reload from stored string
loadFromString(embeddedTomlStr_, "embedded-reload");
mergeOverlayFromFile(savedOverlay);
} else {
loadFromFile(currentPath_);
}
@@ -836,15 +850,26 @@ SeparatorStyle UISchema::separator(const std::string& section, const std::string
return result;
}
DrawElementStyle UISchema::drawElement(const std::string& section, const std::string& name) const {
DrawElementStyle result;
const DrawElementStyle& UISchema::drawElement(const std::string& section, const std::string& name) const {
static const DrawElementStyle s_empty{};
const void* elem = findElement(section, name);
if (elem) {
detail::parseDrawElementStyle(elem, result);
std::string key = section + "." + name;
// Return from cache if already parsed
auto cit = styleCache_.find(key);
if (cit != styleCache_.end()) {
return cit->second;
}
return result;
// Parse from TOML and cache
const void* elem = findElement(section, name);
if (!elem) {
return s_empty;
}
auto [it, _] = styleCache_.emplace(std::move(key), DrawElementStyle{});
detail::parseDrawElementStyle(elem, it->second);
return it->second;
}
} // namespace schema
+9 -1
View File
@@ -255,8 +255,12 @@ public:
/**
* @brief Look up a DrawList custom element style
*
* Returns a cached const reference. The cache is invalidated on
* hot-reload (applyIfDirty) and full loads. For missing elements
* a static empty sentinel is returned.
*/
DrawElementStyle drawElement(const std::string& section, const std::string& name) const;
const DrawElementStyle& drawElement(const std::string& section, const std::string& name) const;
/**
* @brief Find a raw stored element by section and name.
@@ -365,6 +369,10 @@ private:
std::any data; // holds toml::table at runtime
};
std::unordered_map<std::string, StoredElement> elements_;
// Parsed DrawElementStyle cache — avoids repeated TOML table iteration.
// Populated lazily on first drawElement() lookup, cleared on reload.
mutable std::unordered_map<std::string, DrawElementStyle> styleCache_;
};
// Convenience alias
+34 -15
View File
@@ -11,6 +11,7 @@
#include "layout.h"
#include "schema/ui_schema.h"
#include "../embedded/IconsMaterialDesign.h"
#include "../util/i18n.h"
#include <cstdio>
#include <cmath>
@@ -34,25 +35,35 @@ enum class NavPage {
};
struct NavItem {
const char* label;
const char* label; // fallback label (English)
NavPage page;
const char* section_label; // if non-null, render section label above this item
const char* tr_key; // i18n key for label
const char* section_tr_key; // i18n key for section_label
};
inline const NavItem kNavItems[] = {
{ "Overview", NavPage::Overview, nullptr },
{ "Send", NavPage::Send, nullptr },
{ "Receive", NavPage::Receive, nullptr },
{ "History", NavPage::History, nullptr },
{ "Mining", NavPage::Mining, "TOOLS" },
{ "Market", NavPage::Market, nullptr },
{ "Console", NavPage::Console, "ADVANCED" },
{ "Network", NavPage::Peers, nullptr },
{ "Settings", NavPage::Settings, nullptr },
{ "Overview", NavPage::Overview, nullptr, "overview", nullptr },
{ "Send", NavPage::Send, nullptr, "send", nullptr },
{ "Receive", NavPage::Receive, nullptr, "receive", nullptr },
{ "History", NavPage::History, nullptr, "history", nullptr },
{ "Mining", NavPage::Mining, "TOOLS", "mining", "tools" },
{ "Market", NavPage::Market, nullptr, "market", nullptr },
{ "Console", NavPage::Console, "ADVANCED","console", "advanced" },
{ "Network", NavPage::Peers, nullptr, "network", nullptr },
{ "Settings", NavPage::Settings, nullptr, "settings", nullptr },
};
static_assert(sizeof(kNavItems) / sizeof(kNavItems[0]) == (int)NavPage::Count_,
"kNavItems must match NavPage::Count_");
// Get translated nav label at runtime
inline const char* NavLabel(const NavItem& item) {
return item.tr_key ? TR(item.tr_key) : item.label;
}
inline const char* NavSectionLabel(const NavItem& item) {
return item.section_tr_key ? TR(item.section_tr_key) : item.section_label;
}
// Get the Material Design icon string for a navigation page.
inline const char* GetNavIconMD(NavPage page)
{
@@ -541,7 +552,7 @@ inline bool RenderSidebar(NavPage& current, float sidebarWidth, float contentHei
float olFsz = ScaledFontSize(olFont);
dl->AddText(olFont, olFsz,
ImVec2(wp.x + sbSectionLabelPadLeft, labelY),
ImGui::ColorConvertFloat4ToU32(olCol), item.section_label);
ImGui::ColorConvertFloat4ToU32(olCol), NavSectionLabel(item));
ImGui::Dummy(ImVec2(0, olFsz + 2.0f));
} else if (item.section_label && !showLabels) {
// Collapsed: thin separator instead of label
@@ -609,11 +620,19 @@ inline bool RenderSidebar(NavPage& current, float sidebarWidth, float contentHei
ImU32 textCol = selected ? Primary() : OnSurfaceMedium();
if (showLabels) {
// Measure total width of icon + gap + label, then center
// Measure total width of icon + gap + label, then center.
// If the translated label is too wide, shrink the font to fit.
ImFont* font = selected ? Type().subtitle2() : Type().body2();
float gap = iconLabelGap;
float lblFsz = ScaledFontSize(font);
ImVec2 labelSz = font->CalcTextSizeA(lblFsz, 1000.0f, 0.0f, item.label);
float btnW = indMax.x - indMin.x;
float maxLabelW = btnW - iconS * 2.0f - gap - Layout::spacingXs() * 2;
ImVec2 labelSz = font->CalcTextSizeA(lblFsz, 1000.0f, 0.0f, NavLabel(item));
if (labelSz.x > maxLabelW && maxLabelW > 0) {
float shrink = maxLabelW / labelSz.x;
lblFsz *= shrink;
labelSz = font->CalcTextSizeA(lblFsz, 1000.0f, 0.0f, NavLabel(item));
}
float totalW = iconS * 2.0f + gap + labelSz.x;
float btnCX = (indMin.x + indMax.x) * 0.5f;
float startX = btnCX - totalW * 0.5f;
@@ -625,7 +644,7 @@ inline bool RenderSidebar(NavPage& current, float sidebarWidth, float contentHei
ImVec4 lc = ImGui::ColorConvertU32ToFloat4(textCol);
lc.w *= expandFrac;
dl->AddText(font, lblFsz, ImVec2(labelX, textY),
ImGui::ColorConvertFloat4ToU32(lc), item.label);
ImGui::ColorConvertFloat4ToU32(lc), NavLabel(item));
} else {
float iconCX = (indMin.x + indMax.x) * 0.5f;
DrawNavIcon(dl, item.page, iconCX, iconCY, iconS, textCol);
@@ -633,7 +652,7 @@ inline bool RenderSidebar(NavPage& current, float sidebarWidth, float contentHei
// Tooltip when collapsed + hovered
if (!showLabels && hovered) {
ImGui::SetTooltip("%s", item.label);
ImGui::SetTooltip("%s", NavLabel(item));
}
// ---- Badge indicator ----
+23 -25
View File
@@ -5,6 +5,7 @@
#include "about_dialog.h"
#include "../../app.h"
#include "../../config/version.h"
#include "../../util/i18n.h"
#include "../schema/ui_schema.h"
#include "../material/type.h"
#include "../material/draw_helpers.h"
@@ -23,7 +24,7 @@ void RenderAboutDialog(App* app, bool* p_open)
auto versionLbl = S.label("dialogs.about", "version-label");
auto editionLbl = S.label("dialogs.about", "edition-label");
if (!material::BeginOverlayDialog("About ObsidianDragon", p_open, win.width, 0.94f)) {
if (!material::BeginOverlayDialog(TR("about_title"), p_open, win.width, 0.94f)) {
return;
}
@@ -38,33 +39,33 @@ void RenderAboutDialog(App* app, bool* p_open)
ImGui::PopStyleColor();
ImGui::SameLine(ImGui::GetWindowWidth() - editionLbl.position);
ImGui::TextDisabled("ImGui Edition");
ImGui::TextDisabled("%s", TR("about_edition"));
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
// Version info
ImGui::Text("Version:");
ImGui::Text("%s", TR("about_version"));
ImGui::SameLine(versionLbl.position);
ImGui::Text("%s", DRAGONX_VERSION);
ImGui::Text("ImGui:");
ImGui::Text("%s", TR("about_imgui"));
ImGui::SameLine(versionLbl.position);
ImGui::Text("%s", IMGUI_VERSION);
ImGui::Text("Build Date:");
ImGui::Text("%s", TR("about_build_date"));
ImGui::SameLine(versionLbl.position);
ImGui::Text("%s %s", __DATE__, __TIME__);
#ifdef DRAGONX_DEBUG
ImGui::Text("Build Type:");
ImGui::Text("%s", TR("about_build_type"));
ImGui::SameLine(versionLbl.position);
ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.0f, 1.0f), "Debug");
ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.0f, 1.0f), "%s", TR("about_debug"));
#else
ImGui::Text("Build Type:");
ImGui::Text("%s", TR("about_build_type"));
ImGui::SameLine(versionLbl.position);
ImGui::Text("Release");
ImGui::Text("%s", TR("about_release"));
#endif
// Daemon info
@@ -73,22 +74,22 @@ void RenderAboutDialog(App* app, bool* p_open)
ImGui::Separator();
ImGui::Spacing();
ImGui::Text("Daemon:");
ImGui::Text("%s", TR("about_daemon"));
ImGui::SameLine(versionLbl.position);
ImGui::TextColored(ImVec4(0.3f, 0.8f, 0.3f, 1.0f), "Connected");
ImGui::TextColored(ImVec4(0.3f, 0.8f, 0.3f, 1.0f), "%s", TR("connected"));
const auto& state = app->getWalletState();
ImGui::Text("Chain:");
ImGui::Text("%s", TR("about_chain"));
ImGui::SameLine(versionLbl.position);
ImGui::Text("ObsidianDragon");
ImGui::Text("Block Height:");
ImGui::Text("%s", TR("about_block_height"));
ImGui::SameLine(versionLbl.position);
ImGui::Text("%d", state.sync.blocks);
ImGui::Text("Connections:");
ImGui::Text("%s", TR("about_connections"));
ImGui::SameLine(versionLbl.position);
ImGui::Text("%zu peers", state.peers.size());
ImGui::Text(TR("about_peers_count"), state.peers.size());
}
ImGui::Spacing();
@@ -96,7 +97,7 @@ void RenderAboutDialog(App* app, bool* p_open)
ImGui::Spacing();
// Credits
ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "Credits");
ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "%s", TR("about_credits"));
ImGui::Spacing();
ImGui::BulletText("The Hush Developers");
@@ -110,19 +111,16 @@ void RenderAboutDialog(App* app, bool* p_open)
ImGui::Spacing();
// License
ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "License");
ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "%s", TR("about_license"));
ImGui::Spacing();
ImGui::TextWrapped(
"This software is released under the GNU General Public License v3 (GPLv3). "
"You are free to use, modify, and distribute this software under the terms of the license."
);
ImGui::TextWrapped("%s", TR("about_license_text"));
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
// Links
if (material::StyledButton("Website", ImVec2(linkBtn.width, 0), S.resolveFont(linkBtn.font))) {
if (material::StyledButton(TR("about_website"), ImVec2(linkBtn.width, 0), S.resolveFont(linkBtn.font))) {
#ifdef _WIN32
system("start https://dragonx.is");
#elif __APPLE__
@@ -132,7 +130,7 @@ void RenderAboutDialog(App* app, bool* p_open)
#endif
}
ImGui::SameLine();
if (material::StyledButton("GitHub", ImVec2(linkBtn.width, 0), S.resolveFont(linkBtn.font))) {
if (material::StyledButton(TR("about_github"), ImVec2(linkBtn.width, 0), S.resolveFont(linkBtn.font))) {
#ifdef _WIN32
system("start https://git.dragonx.is/dragonx/ObsidianDragon");
#elif __APPLE__
@@ -142,7 +140,7 @@ void RenderAboutDialog(App* app, bool* p_open)
#endif
}
ImGui::SameLine();
if (material::StyledButton("Block Explorer", ImVec2(linkBtn.width, 0), S.resolveFont(linkBtn.font))) {
if (material::StyledButton(TR("about_block_explorer"), ImVec2(linkBtn.width, 0), S.resolveFont(linkBtn.font))) {
#ifdef _WIN32
system("start https://explorer.dragonx.is");
#elif __APPLE__
@@ -157,7 +155,7 @@ void RenderAboutDialog(App* app, bool* p_open)
// Close button
float button_width = closeBtn.width;
ImGui::SetCursorPosX((ImGui::GetWindowWidth() - button_width) * 0.5f);
if (material::StyledButton("Close", ImVec2(button_width, 0), S.resolveFont(closeBtn.font))) {
if (material::StyledButton(TR("close"), ImVec2(button_width, 0), S.resolveFont(closeBtn.font))) {
*p_open = false;
}
+30 -29
View File
@@ -5,6 +5,7 @@
#include "address_book_dialog.h"
#include "../../app.h"
#include "../../data/address_book.h"
#include "../../util/i18n.h"
#include "../notifications.h"
#include "../schema/ui_schema.h"
#include "../material/draw_helpers.h"
@@ -65,11 +66,11 @@ void AddressBookDialog::render(App* app)
auto notesInput = S.input("dialogs.address-book", "notes-input");
auto actionBtn = S.button("dialogs.address-book", "action-button");
if (material::BeginOverlayDialog("Address Book", &s_open, win.width, 0.94f)) {
if (material::BeginOverlayDialog(TR("address_book_title"), &s_open, win.width, 0.94f)) {
auto& book = getAddressBook();
// Toolbar
if (material::StyledButton("Add New", ImVec2(0,0), S.resolveFont(actionBtn.font))) {
if (material::StyledButton(TR("address_book_add_new"), ImVec2(0,0), S.resolveFont(actionBtn.font))) {
s_show_add_dialog = true;
s_edit_label[0] = '\0';
s_edit_address[0] = '\0';
@@ -82,7 +83,7 @@ void AddressBookDialog::render(App* app)
if (!has_selection) ImGui::BeginDisabled();
if (material::StyledButton("Edit", ImVec2(0,0), S.resolveFont(actionBtn.font))) {
if (material::StyledButton(TR("edit"), ImVec2(0,0), S.resolveFont(actionBtn.font))) {
if (has_selection) {
const auto& entry = book.entries()[s_selected_index];
strncpy(s_edit_label, entry.label.c_str(), sizeof(s_edit_label) - 1);
@@ -94,20 +95,20 @@ void AddressBookDialog::render(App* app)
ImGui::SameLine();
if (material::StyledButton("Delete", ImVec2(0,0), S.resolveFont(actionBtn.font))) {
if (material::StyledButton(TR("delete"), ImVec2(0,0), S.resolveFont(actionBtn.font))) {
if (has_selection) {
book.removeEntry(s_selected_index);
s_selected_index = -1;
Notifications::instance().success("Entry deleted");
Notifications::instance().success(TR("address_book_deleted"));
}
}
ImGui::SameLine();
if (material::StyledButton("Copy Address", ImVec2(0,0), S.resolveFont(actionBtn.font))) {
if (material::StyledButton(TR("copy_address"), ImVec2(0,0), S.resolveFont(actionBtn.font))) {
if (has_selection) {
ImGui::SetClipboardText(book.entries()[s_selected_index].address.c_str());
Notifications::instance().info("Address copied to clipboard");
Notifications::instance().info(TR("address_copied"));
}
}
@@ -125,16 +126,16 @@ void AddressBookDialog::render(App* app)
{
float labelColW = (addrTable.columns.count("label") && addrTable.columns.at("label").width > 0) ? addrTable.columns.at("label").width : 150;
float notesColW = (addrTable.columns.count("notes") && addrTable.columns.at("notes").width > 0) ? addrTable.columns.at("notes").width : 150;
ImGui::TableSetupColumn("Label", ImGuiTableColumnFlags_WidthFixed, labelColW);
ImGui::TableSetupColumn("Address", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("Notes", ImGuiTableColumnFlags_WidthFixed, notesColW);
ImGui::TableSetupColumn(TR("label"), ImGuiTableColumnFlags_WidthFixed, labelColW);
ImGui::TableSetupColumn(TR("address_label"), ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn(TR("notes"), ImGuiTableColumnFlags_WidthFixed, notesColW);
ImGui::TableSetupScrollFreeze(0, 1);
ImGui::TableHeadersRow();
if (book.empty()) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextDisabled("No saved addresses. Click 'Add New' to add one.");
ImGui::TextDisabled("%s", TR("address_book_empty"));
} else {
for (size_t i = 0; i < book.size(); i++) {
const auto& entry = book.entries()[i];
@@ -182,7 +183,7 @@ void AddressBookDialog::render(App* app)
}
// Status line
ImGui::TextDisabled("%zu addresses saved", book.size());
ImGui::TextDisabled(TR("address_book_count"), book.size());
material::EndOverlayDialog();
}
@@ -196,20 +197,20 @@ void AddressBookDialog::render(App* app)
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
if (ImGui::BeginPopupModal("Add Address", &s_show_add_dialog, ImGuiWindowFlags_AlwaysAutoResize)) {
material::Type().text(material::TypeStyle::H6, "Add Address");
material::Type().text(material::TypeStyle::H6, TR("address_book_add"));
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
ImGui::Text("Label:");
ImGui::Text("%s", TR("label"));
ImGui::SetNextItemWidth(addrInput.width);
ImGui::InputText("##AddLabel", s_edit_label, sizeof(s_edit_label));
ImGui::Spacing();
ImGui::Text("Address:");
ImGui::Text("%s", TR("address_label"));
ImGui::SetNextItemWidth(addrInput.width);
ImGui::InputText("##AddAddress", s_edit_address, sizeof(s_edit_address));
ImGui::SameLine();
if (material::StyledButton("Paste##Add", ImVec2(0,0), S.resolveFont(actionBtn.font))) {
if (material::StyledButton(TR("paste"), ImVec2(0,0), S.resolveFont(actionBtn.font))) {
const char* clipboard = ImGui::GetClipboardText();
if (clipboard) {
strncpy(s_edit_address, clipboard, sizeof(s_edit_address) - 1);
@@ -218,7 +219,7 @@ void AddressBookDialog::render(App* app)
ImGui::Spacing();
ImGui::Text("Notes (optional):");
ImGui::Text("%s", TR("notes_optional"));
ImGui::SetNextItemWidth(addrInput.width);
ImGui::InputTextMultiline("##AddNotes", s_edit_notes, sizeof(s_edit_notes), ImVec2(addrInput.width, notesInput.height > 0 ? notesInput.height : 60));
@@ -229,20 +230,20 @@ void AddressBookDialog::render(App* app)
bool can_add = strlen(s_edit_label) > 0 && strlen(s_edit_address) > 0;
if (!can_add) ImGui::BeginDisabled();
if (material::StyledButton("Add", ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
if (material::StyledButton(TR("add"), ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
data::AddressBookEntry entry(s_edit_label, s_edit_address, s_edit_notes);
if (getAddressBook().addEntry(entry)) {
Notifications::instance().success("Address added to book");
Notifications::instance().success(TR("address_book_added"));
s_show_add_dialog = false;
} else {
Notifications::instance().error("Address already exists in book");
Notifications::instance().error(TR("address_book_exists"));
}
}
if (!can_add) ImGui::EndDisabled();
ImGui::SameLine();
if (material::StyledButton("Cancel", ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
if (material::StyledButton(TR("cancel"), ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
s_show_add_dialog = false;
}
@@ -257,22 +258,22 @@ void AddressBookDialog::render(App* app)
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
if (ImGui::BeginPopupModal("Edit Address", &s_show_edit_dialog, ImGuiWindowFlags_AlwaysAutoResize)) {
material::Type().text(material::TypeStyle::H6, "Edit Address");
material::Type().text(material::TypeStyle::H6, TR("address_book_edit"));
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
ImGui::Text("Label:");
ImGui::Text("%s", TR("label"));
ImGui::SetNextItemWidth(addrInput.width);
ImGui::InputText("##EditLabel", s_edit_label, sizeof(s_edit_label));
ImGui::Spacing();
ImGui::Text("Address:");
ImGui::Text("%s", TR("address_label"));
ImGui::SetNextItemWidth(addrInput.width);
ImGui::InputText("##EditAddress", s_edit_address, sizeof(s_edit_address));
ImGui::Spacing();
ImGui::Text("Notes (optional):");
ImGui::Text("%s", TR("notes_optional"));
ImGui::SetNextItemWidth(addrInput.width);
ImGui::InputTextMultiline("##EditNotes", s_edit_notes, sizeof(s_edit_notes), ImVec2(addrInput.width, notesInput.height > 0 ? notesInput.height : 60));
@@ -283,20 +284,20 @@ void AddressBookDialog::render(App* app)
bool can_save = strlen(s_edit_label) > 0 && strlen(s_edit_address) > 0;
if (!can_save) ImGui::BeginDisabled();
if (material::StyledButton("Save", ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
if (material::StyledButton(TR("save"), ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
data::AddressBookEntry entry(s_edit_label, s_edit_address, s_edit_notes);
if (getAddressBook().updateEntry(s_selected_index, entry)) {
Notifications::instance().success("Address updated");
Notifications::instance().success(TR("address_book_updated"));
s_show_edit_dialog = false;
} else {
Notifications::instance().error("Failed to update - address may be duplicate");
Notifications::instance().error(TR("address_book_update_failed"));
}
}
if (!can_save) ImGui::EndDisabled();
ImGui::SameLine();
if (material::StyledButton("Cancel", ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
if (material::StyledButton(TR("cancel"), ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
s_show_edit_dialog = false;
}
+13 -16
View File
@@ -61,11 +61,8 @@ void BackupWalletDialog::render(App* app)
auto backupBtn = S.button("dialogs.backup-wallet", "backup-button");
auto closeBtn = S.button("dialogs.backup-wallet", "close-button");
if (material::BeginOverlayDialog("Backup Wallet", &s_open, win.width, 0.94f)) {
ImGui::TextWrapped(
"Create a backup of your wallet.dat file. This file contains all your "
"private keys and transaction history. Store the backup in a secure location."
);
if (material::BeginOverlayDialog(TR("backup_title"), &s_open, win.width, 0.94f)) {
ImGui::TextWrapped("%s", TR("backup_description"));
ImGui::Spacing();
ImGui::Separator();
@@ -76,7 +73,7 @@ void BackupWalletDialog::render(App* app)
}
// Destination path
ImGui::Text("Backup destination:");
ImGui::Text("%s", TR("backup_destination"));
ImGui::SetNextItemWidth(-1);
ImGui::InputText("##Destination", s_destination, sizeof(s_destination));
@@ -84,13 +81,13 @@ void BackupWalletDialog::render(App* app)
// Show wallet.dat location
std::string walletPath = util::Platform::getDataDir() + "/wallet.dat";
ImGui::TextDisabled("Source: %s", walletPath.c_str());
ImGui::TextDisabled(TR("backup_source"), walletPath.c_str());
// Check if source exists
bool sourceExists = fs::exists(walletPath);
if (!sourceExists) {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.4f, 0.4f, 1.0f));
ImGui::Text("Warning: wallet.dat not found at expected location");
ImGui::Text("%s", TR("backup_wallet_not_found"));
ImGui::PopStyleColor();
}
@@ -107,7 +104,7 @@ void BackupWalletDialog::render(App* app)
ImGui::BeginDisabled();
}
if (material::StyledButton("Create Backup", ImVec2(backupBtn.width, 0), S.resolveFont(backupBtn.font))) {
if (material::StyledButton(TR("backup_create"), ImVec2(backupBtn.width, 0), S.resolveFont(backupBtn.font))) {
if (strlen(s_destination) == 0) {
Notifications::instance().warning("Please enter a destination path");
} else if (!app->rpc() || !app->rpc()->isConnected()) {
@@ -147,7 +144,7 @@ void BackupWalletDialog::render(App* app)
s_status = statusMsg;
s_backing_up = false;
if (success) {
Notifications::instance().success("Wallet backup created");
Notifications::instance().success(TR("backup_created"));
} else {
Notifications::instance().warning(statusMsg);
}
@@ -160,11 +157,11 @@ void BackupWalletDialog::render(App* app)
if (s_backing_up) {
ImGui::EndDisabled();
ImGui::SameLine();
ImGui::TextDisabled("Backing up...");
ImGui::TextDisabled("%s", TR("backup_backing_up"));
}
ImGui::SameLine();
if (material::StyledButton("Close", ImVec2(closeBtn.width, 0), S.resolveFont(closeBtn.font))) {
if (material::StyledButton(TR("close"), ImVec2(closeBtn.width, 0), S.resolveFont(closeBtn.font))) {
s_open = false;
}
@@ -179,10 +176,10 @@ void BackupWalletDialog::render(App* app)
ImGui::Spacing();
// Tips
ImGui::TextDisabled("Tips:");
ImGui::BulletText("Store backups on external drives or cloud storage");
ImGui::BulletText("Create multiple backups in different locations");
ImGui::BulletText("Test restoring from backup periodically");
ImGui::TextDisabled("%s", TR("backup_tips"));
ImGui::BulletText("%s", TR("backup_tip_external"));
ImGui::BulletText("%s", TR("backup_tip_multiple"));
ImGui::BulletText("%s", TR("backup_tip_test"));
material::EndOverlayDialog();
}
}
+34 -24
View File
@@ -30,6 +30,14 @@
namespace dragonx {
namespace ui {
// Helper: build "TranslatedLabel##id" for ImGui widgets that use label as ID
static std::string TrId(const char* tr_key, const char* id) {
std::string s = TR(tr_key);
s += "##";
s += id;
return s;
}
// Case-insensitive substring search
static bool containsIgnoreCase(const std::string& str, const std::string& search) {
if (search.empty()) return true;
@@ -774,13 +782,13 @@ static void RenderBalanceClassic(App* app)
ImGui::InputTextWithHint("##AddrSearch", "Filter...", addr_search, sizeof(addr_search));
ImGui::SameLine(0, Layout::spacingLg());
ImGui::Checkbox("Hide 0 Balances", &s_hideZeroBalances);
ImGui::Checkbox(TrId("hide_zero_balances", "hide0").c_str(), &s_hideZeroBalances);
{
int hc = app->getHiddenAddressCount();
if (hc > 0) {
ImGui::SameLine(0, Layout::spacingLg());
char hlbl[64];
snprintf(hlbl, sizeof(hlbl), "Show Hidden (%d)", hc);
snprintf(hlbl, sizeof(hlbl), TR("show_hidden"), hc);
ImGui::Checkbox(hlbl, &s_showHidden);
} else {
s_showHidden = false;
@@ -883,7 +891,8 @@ static void RenderBalanceClassic(App* app)
ImU32 greenCol = S.resolveColor("var(--accent-shielded)", Success());
ImU32 goldCol = S.resolveColor("var(--accent-transparent)", Warning());
float rowPadLeft = Layout::spacingLg();
float rowPadLeft = Layout::cardInnerPadding();
float rowPadRight = Layout::cardInnerPadding();
float rowIconSz = std::max(S.drawElement("tabs.balance", "address-icon-min-size").size, S.drawElement("tabs.balance", "address-icon-size").size * hs);
float innerW = ImGui::GetContentRegionAvail().x;
@@ -931,10 +940,10 @@ static void RenderBalanceClassic(App* app)
// --- Button zone (right edge): [eye] [star] ---
float btnH = rowH - Layout::spacingSm() * 2.0f;
float btnW = btnH;
float btnGap = Layout::spacingXs();
float btnGap = Layout::spacingSm();
float btnY = rowPos.y + (rowH - btnH) * 0.5f;
float rightEdge = rowPos.x + innerW;
float starX = rightEdge - btnW - Layout::spacingSm();
float starX = rightEdge - btnW - rowPadRight;
float eyeX = starX - btnGap - btnW;
float btnRound = 6.0f * dp;
bool btnClicked = false;
@@ -958,7 +967,7 @@ static void RenderBalanceClassic(App* app)
else app->favoriteAddress(addr.address);
btnClicked = true;
}
if (bHov) ImGui::SetTooltip("%s", row.favorite ? "Remove favorite" : "Favorite address");
if (bHov) ImGui::SetTooltip("%s", row.favorite ? TR("remove_favorite") : TR("favorite_address"));
}
// Eye button (zero balance or hidden)
@@ -980,7 +989,7 @@ static void RenderBalanceClassic(App* app)
else app->hideAddress(addr.address);
btnClicked = true;
}
if (bHov) ImGui::SetTooltip("%s", row.hidden ? "Restore address" : "Hide address");
if (bHov) ImGui::SetTooltip("%s", row.hidden ? TR("restore_address") : TR("hide_address"));
}
// Content zone ends before buttons
@@ -1103,17 +1112,17 @@ static void RenderBalanceClassic(App* app)
}
ImGui::Separator();
if (row.hidden) {
if (ImGui::MenuItem("Restore Address"))
if (ImGui::MenuItem(TR("restore_address")))
app->unhideAddress(addr.address);
} else if (addr.balance < 1e-9) {
if (ImGui::MenuItem("Hide Address"))
if (ImGui::MenuItem(TR("hide_address")))
app->hideAddress(addr.address);
}
if (row.favorite) {
if (ImGui::MenuItem("Remove Favorite"))
if (ImGui::MenuItem(TR("remove_favorite")))
app->unfavoriteAddress(addr.address);
} else {
if (ImGui::MenuItem("Favorite Address"))
if (ImGui::MenuItem(TR("favorite_address")))
app->favoriteAddress(addr.address);
}
effects::ImGuiAcrylic::EndAcrylicPopup();
@@ -1387,13 +1396,13 @@ static void RenderSharedAddressList(App* app, float listH, float availW,
ImGui::SetNextItemWidth(searchW);
ImGui::InputTextWithHint("##AddrSearch", "Filter...", addr_search, sizeof(addr_search));
ImGui::SameLine(0, Layout::spacingLg());
ImGui::Checkbox("Hide 0 Balances", &s_hideZeroBalances);
ImGui::Checkbox(TrId("hide_zero_balances", "hide0_v2").c_str(), &s_hideZeroBalances);
{
int hc = app->getHiddenAddressCount();
if (hc > 0) {
ImGui::SameLine(0, Layout::spacingLg());
char hlbl[64];
snprintf(hlbl, sizeof(hlbl), "Show Hidden (%d)", hc);
snprintf(hlbl, sizeof(hlbl), TR("show_hidden"), hc);
ImGui::Checkbox(hlbl, &s_showHidden);
} else {
s_showHidden = false;
@@ -1461,10 +1470,10 @@ static void RenderSharedAddressList(App* app, float listH, float availW,
float ch = ImGui::GetContentRegionAvail().y;
if (ch < 60) ch = 60;
if (addr_search[0]) {
ImVec2 textSz = ImGui::CalcTextSize("No matching addresses");
ImVec2 textSz = ImGui::CalcTextSize(TR("no_addresses_match"));
ImGui::SetCursorPosX((cw - textSz.x) * 0.5f);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ch * 0.25f);
ImGui::TextDisabled("No matching addresses");
ImGui::TextDisabled("%s", TR("no_addresses_match"));
} else {
const char* msg = "No addresses yet";
ImVec2 msgSz = ImGui::CalcTextSize(msg);
@@ -1482,7 +1491,8 @@ static void RenderSharedAddressList(App* app, float listH, float availW,
addrScrollMaxY = ImGui::GetScrollMaxY();
ImU32 greenCol = S.resolveColor("var(--accent-shielded)", Success());
ImU32 goldCol = S.resolveColor("var(--accent-transparent)", Warning());
float rowPadLeft = Layout::spacingLg();
float rowPadLeft = Layout::cardInnerPadding();
float rowPadRight = Layout::cardInnerPadding();
float rowIconSz = std::max(S.drawElement("tabs.balance", "address-icon-min-size").size,
S.drawElement("tabs.balance", "address-icon-size").size * hs);
float innerW = ImGui::GetContentRegionAvail().x;
@@ -1522,10 +1532,10 @@ static void RenderSharedAddressList(App* app, float listH, float availW,
// --- Button zone (right edge): [eye] [star] ---
float btnH = rowH - Layout::spacingSm() * 2.0f;
float btnW = btnH;
float btnGap = Layout::spacingXs();
float btnGap = Layout::spacingSm();
float btnY = rowPos.y + (rowH - btnH) * 0.5f;
float rightEdge = rowPos.x + innerW;
float starX = rightEdge - btnW - Layout::spacingSm();
float starX = rightEdge - btnW - rowPadRight;
float eyeX = starX - btnGap - btnW;
float btnRound = 6.0f * dp;
bool btnClicked = false;
@@ -1549,7 +1559,7 @@ static void RenderSharedAddressList(App* app, float listH, float availW,
else app->favoriteAddress(addr.address);
btnClicked = true;
}
if (bHov) ImGui::SetTooltip("%s", row.favorite ? "Remove favorite" : "Favorite address");
if (bHov) ImGui::SetTooltip("%s", row.favorite ? TR("remove_favorite") : TR("favorite_address"));
}
// Eye button (zero balance or hidden)
@@ -1571,7 +1581,7 @@ static void RenderSharedAddressList(App* app, float listH, float availW,
else app->hideAddress(addr.address);
btnClicked = true;
}
if (bHov) ImGui::SetTooltip("%s", row.hidden ? "Restore address" : "Hide address");
if (bHov) ImGui::SetTooltip("%s", row.hidden ? TR("restore_address") : TR("hide_address"));
}
// Content zone ends before buttons
@@ -1672,17 +1682,17 @@ static void RenderSharedAddressList(App* app, float listH, float availW,
QRPopupDialog::show(addr.address, row.isZ ? "Z-Address" : "T-Address");
ImGui::Separator();
if (row.hidden) {
if (ImGui::MenuItem("Restore Address"))
if (ImGui::MenuItem(TR("restore_address")))
app->unhideAddress(addr.address);
} else if (addr.balance < 1e-9) {
if (ImGui::MenuItem("Hide Address"))
if (ImGui::MenuItem(TR("hide_address")))
app->hideAddress(addr.address);
}
if (row.favorite) {
if (ImGui::MenuItem("Remove Favorite"))
if (ImGui::MenuItem(TR("remove_favorite")))
app->unfavoriteAddress(addr.address);
} else {
if (ImGui::MenuItem("Favorite Address"))
if (ImGui::MenuItem(TR("favorite_address")))
app->favoriteAddress(addr.address);
}
effects::ImGuiAcrylic::EndAcrylicPopup();
+22 -22
View File
@@ -99,12 +99,12 @@ void BlockInfoDialog::render(App* app)
auto hashBackLbl = S.label("dialogs.block-info", "hash-back-label");
auto closeBtn = S.button("dialogs.block-info", "close-button");
if (material::BeginOverlayDialog("Block Information", &s_open, win.width, 0.94f)) {
if (material::BeginOverlayDialog(TR("block_info_title"), &s_open, win.width, 0.94f)) {
auto* rpc = app->rpc();
const auto& state = app->getWalletState();
// Height input
ImGui::Text("Block Height:");
ImGui::Text("%s", TR("block_height"));
ImGui::SetNextItemWidth(heightInput.width);
ImGui::InputInt("##Height", &s_height);
if (s_height < 1) s_height = 1;
@@ -123,7 +123,7 @@ void BlockInfoDialog::render(App* app)
ImGui::BeginDisabled();
}
if (material::StyledButton("Get Block Info", ImVec2(0,0), S.resolveFont(closeBtn.font))) {
if (material::StyledButton(TR("block_get_info"), ImVec2(0,0), S.resolveFont(closeBtn.font))) {
if (rpc && rpc->isConnected()) {
s_loading = true;
s_error.clear();
@@ -138,7 +138,7 @@ void BlockInfoDialog::render(App* app)
if (s_loading) {
ImGui::EndDisabled();
ImGui::SameLine();
ImGui::TextDisabled("Loading...");
ImGui::TextDisabled("%s", TR("loading"));
}
ImGui::Spacing();
@@ -155,23 +155,23 @@ void BlockInfoDialog::render(App* app)
// Block info display
if (s_has_data) {
// Block hash
ImGui::Text("Block Hash:");
ImGui::Text("%s", TR("block_hash"));
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.6f, 0.8f, 1.0f, 1.0f));
ImGui::TextWrapped("%s", s_block_hash.c_str());
ImGui::PopStyleColor();
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Click to copy");
ImGui::SetTooltip("%s", TR("click_to_copy"));
}
if (ImGui::IsItemClicked()) {
ImGui::SetClipboardText(s_block_hash.c_str());
Notifications::instance().success("Block hash copied");
Notifications::instance().success(TR("block_hash_copied"));
}
ImGui::Spacing();
// Timestamp
ImGui::Text("Timestamp:");
ImGui::Text("%s", TR("block_timestamp"));
ImGui::SameLine(lbl.position);
if (s_block_time > 0) {
std::time_t t = static_cast<std::time_t>(s_block_time);
@@ -179,21 +179,21 @@ void BlockInfoDialog::render(App* app)
std::strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", std::localtime(&t));
ImGui::Text("%s", time_buf);
} else {
ImGui::TextDisabled("Unknown");
ImGui::TextDisabled("%s", TR("unknown"));
}
// Confirmations
ImGui::Text("Confirmations:");
ImGui::Text("%s", TR("confirmations"));
ImGui::SameLine(lbl.position);
ImGui::Text("%d", s_confirmations);
// Transaction count
ImGui::Text("Transactions:");
ImGui::Text("%s", TR("block_transactions"));
ImGui::SameLine(lbl.position);
ImGui::Text("%d", s_tx_count);
// Size
ImGui::Text("Size:");
ImGui::Text("%s", TR("block_size"));
ImGui::SameLine(lbl.position);
if (s_block_size > 1024 * 1024) {
ImGui::Text("%.2f MB", s_block_size / (1024.0 * 1024.0));
@@ -204,12 +204,12 @@ void BlockInfoDialog::render(App* app)
}
// Difficulty
ImGui::Text("Difficulty:");
ImGui::Text("%s", TR("difficulty"));
ImGui::SameLine(lbl.position);
ImGui::Text("%.4f", s_difficulty);
// Bits
ImGui::Text("Bits:");
ImGui::Text("%s", TR("block_bits"));
ImGui::SameLine(lbl.position);
ImGui::Text("%s", s_bits.c_str());
@@ -218,7 +218,7 @@ void BlockInfoDialog::render(App* app)
ImGui::Spacing();
// Merkle root
ImGui::Text("Merkle Root:");
ImGui::Text("%s", TR("block_merkle_root"));
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.7f, 0.7f, 0.7f, 1.0f));
ImGui::TextWrapped("%s", s_merkle_root.c_str());
ImGui::PopStyleColor();
@@ -227,7 +227,7 @@ void BlockInfoDialog::render(App* app)
// Previous block
if (!s_prev_hash.empty()) {
ImGui::Text("Previous Block:");
ImGui::Text("%s", TR("block_previous"));
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.6f, 0.8f, 1.0f, 1.0f));
// Truncate for display
@@ -239,7 +239,7 @@ void BlockInfoDialog::render(App* app)
ImGui::PopStyleColor();
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Click to view previous block");
ImGui::SetTooltip("%s", TR("block_click_prev"));
}
if (ImGui::IsItemClicked() && s_height > 1) {
s_height--;
@@ -249,7 +249,7 @@ void BlockInfoDialog::render(App* app)
// Next block
if (!s_next_hash.empty()) {
ImGui::Text("Next Block:");
ImGui::Text("%s", TR("block_next"));
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.6f, 0.8f, 1.0f, 1.0f));
// Truncate for display
@@ -261,7 +261,7 @@ void BlockInfoDialog::render(App* app)
ImGui::PopStyleColor();
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Click to view next block");
ImGui::SetTooltip("%s", TR("block_click_next"));
}
if (ImGui::IsItemClicked()) {
s_height++;
@@ -276,7 +276,7 @@ void BlockInfoDialog::render(App* app)
// Navigation buttons
if (s_has_data) {
if (s_height > 1) {
if (material::StyledButton("<< Previous", ImVec2(0,0), S.resolveFont(closeBtn.font))) {
if (material::StyledButton(TR("block_nav_prev"), ImVec2(0,0), S.resolveFont(closeBtn.font))) {
s_height--;
s_has_data = false;
s_error.clear();
@@ -285,7 +285,7 @@ void BlockInfoDialog::render(App* app)
}
if (!s_next_hash.empty()) {
if (material::StyledButton("Next >>", ImVec2(0,0), S.resolveFont(closeBtn.font))) {
if (material::StyledButton(TR("block_nav_next"), ImVec2(0,0), S.resolveFont(closeBtn.font))) {
s_height++;
s_has_data = false;
s_error.clear();
@@ -295,7 +295,7 @@ void BlockInfoDialog::render(App* app)
// Close button at bottom
ImGui::SetCursorPosY(ImGui::GetWindowHeight() - 40);
if (material::StyledButton("Close", ImVec2(closeBtn.width, 0), S.resolveFont(closeBtn.font))) {
if (material::StyledButton(TR("close"), ImVec2(closeBtn.width, 0), S.resolveFont(closeBtn.font))) {
s_open = false;
}
material::EndOverlayDialog();
+68 -56
View File
@@ -13,6 +13,7 @@
#include "../material/color_theme.h"
#include "../theme.h"
#include "../../embedded/IconsMaterialDesign.h"
#include "../../util/i18n.h"
#include <imgui.h>
#include <cstring>
@@ -75,8 +76,8 @@ ConsoleTab::ConsoleTab()
refreshColors();
// Add welcome message
addLine("DragonX Wallet Console", COLOR_INFO);
addLine("Type 'help' for available commands", COLOR_INFO);
addLine(TR("console_welcome"), COLOR_INFO);
addLine(TR("console_type_help"), COLOR_INFO);
addLine("", COLOR_RESULT);
}
@@ -117,27 +118,38 @@ void ConsoleTab::render(daemon::EmbeddedDaemon* daemon, rpc::RPCClient* rpc, rpc
if (current_state == daemon::EmbeddedDaemon::State::Starting &&
last_daemon_state_ == daemon::EmbeddedDaemon::State::Stopped) {
addLine("", COLOR_RESULT);
addLine("=== Starting DragonX Full Node ===", COLOR_INFO);
addLine("Capturing daemon output...", COLOR_INFO);
addLine(TR("console_starting_node"), COLOR_INFO);
addLine(TR("console_capturing_output"), COLOR_INFO);
addLine("", COLOR_RESULT);
shown_startup_message_ = true;
}
else if (current_state == daemon::EmbeddedDaemon::State::Running &&
last_daemon_state_ != daemon::EmbeddedDaemon::State::Running) {
addLine("=== Daemon is running ===", COLOR_INFO);
addLine(TR("console_daemon_started"), COLOR_INFO);
}
else if (current_state == daemon::EmbeddedDaemon::State::Stopped &&
last_daemon_state_ == daemon::EmbeddedDaemon::State::Running) {
addLine("", COLOR_RESULT);
addLine("=== Daemon stopped ===", COLOR_INFO);
addLine(TR("console_daemon_stopped"), COLOR_INFO);
}
else if (current_state == daemon::EmbeddedDaemon::State::Error) {
addLine("=== Daemon error: " + daemon->getLastError() + " ===", COLOR_ERROR);
addLine(std::string(TR("console_daemon_error")) + daemon->getLastError() + " ===", COLOR_ERROR);
}
last_daemon_state_ = current_state;
}
// Track RPC connection state and show a message when connected
if (rpc) {
bool connected_now = rpc->isConnected();
if (connected_now && !last_rpc_connected_) {
addLine(TR("console_connected"), COLOR_INFO);
} else if (!connected_now && last_rpc_connected_) {
addLine(TR("console_disconnected"), COLOR_ERROR);
}
last_rpc_connected_ = connected_now;
}
// Check for new daemon output — always capture so toggle works as a live filter
if (daemon) {
std::string new_output = daemon->getOutputSince(last_daemon_output_size_);
@@ -372,31 +384,31 @@ void ConsoleTab::renderToolbar(daemon::EmbeddedDaemon* daemon)
// Daemon status with colored dot
if (daemon) {
auto state = daemon->getState();
const char* status_text = "Unknown";
const char* status_text = TR("console_status_unknown");
ImU32 dotCol = IM_COL32(150, 150, 150, 255);
bool pulse = false;
switch (state) {
case daemon::EmbeddedDaemon::State::Stopped:
status_text = "Stopped";
status_text = TR("console_status_stopped");
dotCol = IM_COL32(150, 150, 150, 255);
break;
case daemon::EmbeddedDaemon::State::Starting:
status_text = "Starting";
status_text = TR("console_status_starting");
dotCol = Warning();
pulse = true;
break;
case daemon::EmbeddedDaemon::State::Running:
status_text = "Running";
status_text = TR("console_status_running");
dotCol = Success();
break;
case daemon::EmbeddedDaemon::State::Stopping:
status_text = "Stopping";
status_text = TR("console_status_stopping");
dotCol = Warning();
pulse = true;
break;
case daemon::EmbeddedDaemon::State::Error:
status_text = "Error";
status_text = TR("console_status_error");
dotCol = Error();
break;
}
@@ -418,7 +430,7 @@ void ConsoleTab::renderToolbar(daemon::EmbeddedDaemon* daemon)
ImGui::SameLine();
Type().textColored(TypeStyle::Caption, dotCol, status_text);
} else {
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), "No daemon");
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), TR("console_no_daemon"));
}
ImGui::SameLine();
@@ -426,7 +438,7 @@ void ConsoleTab::renderToolbar(daemon::EmbeddedDaemon* daemon)
ImGui::SameLine();
// Auto-scroll toggle
if (ImGui::Checkbox("Auto-scroll", &auto_scroll_)) {
if (ImGui::Checkbox(TR("console_auto_scroll"), &auto_scroll_)) {
if (auto_scroll_) {
scroll_to_bottom_ = true;
new_lines_since_scroll_ = 0;
@@ -440,7 +452,7 @@ void ConsoleTab::renderToolbar(daemon::EmbeddedDaemon* daemon)
// Daemon messages toggle
{
static bool s_prev_daemon_enabled = true;
ImGui::Checkbox("Daemon", &s_daemon_messages_enabled);
ImGui::Checkbox(TR("console_daemon"), &s_daemon_messages_enabled);
// When toggling daemon filter while auto-scroll is active, scroll to bottom
if (s_prev_daemon_enabled != s_daemon_messages_enabled && auto_scroll_) {
scroll_to_bottom_ = true;
@@ -448,7 +460,7 @@ void ConsoleTab::renderToolbar(daemon::EmbeddedDaemon* daemon)
s_prev_daemon_enabled = s_daemon_messages_enabled;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Show daemon output messages");
ImGui::SetTooltip("%s", TR("console_show_daemon_output"));
}
ImGui::SameLine();
@@ -458,7 +470,7 @@ void ConsoleTab::renderToolbar(daemon::EmbeddedDaemon* daemon)
// Errors-only toggle
{
static bool s_prev_errors_only = false;
ImGui::Checkbox("Errors", &s_errors_only_enabled);
ImGui::Checkbox(TR("console_errors"), &s_errors_only_enabled);
// When toggling errors filter while auto-scroll is active, scroll to bottom
if (s_prev_errors_only != s_errors_only_enabled && auto_scroll_) {
scroll_to_bottom_ = true;
@@ -466,7 +478,7 @@ void ConsoleTab::renderToolbar(daemon::EmbeddedDaemon* daemon)
s_prev_errors_only = s_errors_only_enabled;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Show only error messages");
ImGui::SetTooltip("%s", TR("console_show_errors_only"));
}
ImGui::SameLine();
@@ -474,7 +486,7 @@ void ConsoleTab::renderToolbar(daemon::EmbeddedDaemon* daemon)
ImGui::SameLine();
// Clear button
if (TactileButton("Clear", ImVec2(0, 0), schema::UI().resolveFont("button"))) {
if (TactileButton(TR("console_clear"), ImVec2(0, 0), schema::UI().resolveFont("button"))) {
clear();
clearSelection();
}
@@ -482,7 +494,7 @@ void ConsoleTab::renderToolbar(daemon::EmbeddedDaemon* daemon)
ImGui::SameLine();
// Copy button — material styled
if (TactileButton("Copy", ImVec2(0, 0), schema::UI().resolveFont("button"))) {
if (TactileButton(TR("copy"), ImVec2(0, 0), schema::UI().resolveFont("button"))) {
std::lock_guard<std::mutex> lock(lines_mutex_);
if (has_selection_) {
std::string selected = getSelectedText();
@@ -501,17 +513,17 @@ void ConsoleTab::renderToolbar(daemon::EmbeddedDaemon* daemon)
}
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(has_selection_ ? "Copy selected text" : "Copy all output");
ImGui::SetTooltip("%s", has_selection_ ? TR("console_copy_selected") : TR("console_copy_all"));
}
ImGui::SameLine();
// Commands reference button
if (TactileButton("Commands", ImVec2(0, 0), schema::UI().resolveFont("button"))) {
if (TactileButton(TR("console_commands"), ImVec2(0, 0), schema::UI().resolveFont("button"))) {
show_commands_popup_ = true;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Show RPC command reference");
ImGui::SetTooltip("%s", TR("console_show_rpc_ref"));
}
ImGui::SameLine();
@@ -519,7 +531,7 @@ void ConsoleTab::renderToolbar(daemon::EmbeddedDaemon* daemon)
// Line count
{
std::lock_guard<std::mutex> lock(lines_mutex_);
ImGui::TextDisabled("(%zu lines)", lines_.size());
ImGui::TextDisabled(TR("console_line_count"), lines_.size());
}
ImGui::SameLine();
@@ -531,7 +543,7 @@ void ConsoleTab::renderToolbar(daemon::EmbeddedDaemon* daemon)
float filterAvail = ImGui::GetContentRegionAvail().x - zoomBtnSpace;
float filterW = std::min(schema::UI().drawElement("tabs.console", "filter-max-width").size, filterAvail * schema::UI().drawElement("tabs.console", "filter-width-ratio").size);
ImGui::SetNextItemWidth(filterW);
ImGui::InputTextWithHint("##ConsoleFilter", "Filter output...", filter_text_, sizeof(filter_text_));
ImGui::InputTextWithHint("##ConsoleFilter", TR("console_filter_hint"), filter_text_, sizeof(filter_text_));
// Zoom +/- buttons (right side of toolbar)
ImGui::SameLine();
@@ -548,14 +560,14 @@ void ConsoleTab::renderToolbar(daemon::EmbeddedDaemon* daemon)
s_console_zoom = std::max(zoomMin, s_console_zoom - zoomStep);
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Zoom out (%.0f%%)", s_console_zoom * 100.0f);
ImGui::SetTooltip(TR("console_zoom_out"), s_console_zoom * 100.0f);
}
ImGui::SameLine();
if (TactileButton(ICON_MD_ADD, ImVec2(btnSz, btnSz), Type().iconMed())) {
s_console_zoom = std::min(zoomMax, s_console_zoom + zoomStep);
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Zoom in (%.0f%%)", s_console_zoom * 100.0f);
ImGui::SetTooltip(TR("console_zoom_in"), s_console_zoom * 100.0f);
}
}
}
@@ -889,7 +901,7 @@ void ConsoleTab::renderOutput()
// Filter indicator (text filter only — daemon toggle is already visible in toolbar)
if (has_text_filter) {
char filterBuf[128];
snprintf(filterBuf, sizeof(filterBuf), "Showing %d of %zu lines",
snprintf(filterBuf, sizeof(filterBuf), TR("console_showing_lines"),
visible_count, lines_.size());
ImVec2 indicatorPos = ImGui::GetCursorScreenPos();
ImGui::GetWindowDrawList()->AddText(indicatorPos,
@@ -899,13 +911,13 @@ void ConsoleTab::renderOutput()
// Right-click context menu
if (ImGui::BeginPopupContextWindow("ConsoleContextMenu")) {
if (ImGui::MenuItem("Copy", "Ctrl+C", false, has_selection_)) {
if (ImGui::MenuItem(TR("copy"), "Ctrl+C", false, has_selection_)) {
std::string selected = getSelectedText();
if (!selected.empty()) {
ImGui::SetClipboardText(selected.c_str());
}
}
if (ImGui::MenuItem("Select All", "Ctrl+A")) {
if (ImGui::MenuItem(TR("console_select_all"), "Ctrl+A")) {
if (!lines_.empty()) {
sel_anchor_ = {0, 0};
sel_end_ = {static_cast<int>(lines_.size()) - 1,
@@ -914,7 +926,7 @@ void ConsoleTab::renderOutput()
}
}
ImGui::Separator();
if (ImGui::MenuItem("Clear Console")) {
if (ImGui::MenuItem(TR("console_clear_console"))) {
// Can't call clear() here (already holding lock), just mark for clearing
lines_.clear();
has_selection_ = false;
@@ -938,7 +950,7 @@ void ConsoleTab::renderOutput()
dlInd->AddRect(iMin, iMax, IM_COL32(255, 218, 0, 120), 12.0f);
char buf[48];
snprintf(buf, sizeof(buf), " %d new line%s",
snprintf(buf, sizeof(buf), TR("console_new_lines"),
new_lines_since_scroll_, new_lines_since_scroll_ != 1 ? "s" : "");
ImFont* capFont = Type().caption();
if (!capFont) capFont = ImGui::GetFont();
@@ -1229,7 +1241,7 @@ void ConsoleTab::renderInput(rpc::RPCClient* rpc, rpc::RPCWorker* worker)
data->InsertChars(0, matches[0]);
} else if (matches.size() > 1) {
// Multiple matches — show list in console and complete common prefix
console->addLine("Completions:", ConsoleTab::COLOR_INFO);
console->addLine(TR("console_completions"), ConsoleTab::COLOR_INFO);
std::string line = " ";
for (size_t m = 0; m < matches.size(); m++) {
if (m > 0) line += " ";
@@ -1284,17 +1296,17 @@ void ConsoleTab::renderCommandsPopup()
using namespace material;
float popW = std::min(schema::UI().drawElement("tabs.console", "popup-max-width").size, ImGui::GetMainViewport()->Size.x * schema::UI().drawElement("tabs.console", "popup-width-ratio").size);
if (!material::BeginOverlayDialog("RPC Command Reference", &show_commands_popup_, popW, 0.94f)) {
if (!material::BeginOverlayDialog(TR("console_rpc_reference"), &show_commands_popup_, popW, 0.94f)) {
return;
}
Type().text(TypeStyle::H6, "RPC Command Reference");
Type().text(TypeStyle::H6, TR("console_rpc_reference"));
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
// Search filter
static char cmdFilter[128] = {0};
ImGui::SetNextItemWidth(-1);
ImGui::InputTextWithHint("##CmdSearch", "Search commands...", cmdFilter, sizeof(cmdFilter));
ImGui::InputTextWithHint("##CmdSearch", TR("console_search_commands"), cmdFilter, sizeof(cmdFilter));
ImGui::Dummy(ImVec2(0, Layout::spacingXs()));
// Command entries
@@ -1507,9 +1519,9 @@ void ConsoleTab::renderCommandsPopup()
if (ImGui::IsItemHovered()) {
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
if (cmd.params[0] != '\0')
ImGui::SetTooltip("Click to insert '%s %s' into input", cmd.name, cmd.params);
ImGui::SetTooltip(TR("console_click_insert_params"), cmd.name, cmd.params);
else
ImGui::SetTooltip("Click to insert '%s' into input", cmd.name);
ImGui::SetTooltip(TR("console_click_insert"), cmd.name);
}
ImGui::PopStyleColor(3);
if (showParams) {
@@ -1575,7 +1587,7 @@ void ConsoleTab::renderCommandsPopup()
ImGui::Dummy(ImVec2(0, Layout::spacingXs()));
// Close button
if (ImGui::Button("Close", ImVec2(-1, 0))) {
if (ImGui::Button(TR("console_close"), ImVec2(-1, 0))) {
cmdFilter[0] = '\0';
show_commands_popup_ = false;
}
@@ -1605,28 +1617,28 @@ void ConsoleTab::executeCommand(const std::string& cmd, rpc::RPCClient* rpc, rpc
}
if (cmd == "help") {
addLine("Available commands:", COLOR_INFO);
addLine(" clear - Clear console output", COLOR_RESULT);
addLine(" help - Show this help", COLOR_RESULT);
addLine(TR("console_available_commands"), COLOR_INFO);
addLine(TR("console_help_clear"), COLOR_RESULT);
addLine(TR("console_help_help"), COLOR_RESULT);
addLine("", COLOR_RESULT);
addLine("Common RPC commands (when connected):", COLOR_INFO);
addLine(" getinfo - Get daemon info", COLOR_RESULT);
addLine(" getbalance - Get transparent balance", COLOR_RESULT);
addLine(" z_gettotalbalance - Get total balance", COLOR_RESULT);
addLine(" getblockcount - Get current block height", COLOR_RESULT);
addLine(" getpeerinfo - Get connected peers", COLOR_RESULT);
addLine(" setgenerate true/false [threads] - Mining on/off", COLOR_RESULT);
addLine(" getmininginfo - Get mining status", COLOR_RESULT);
addLine(" stop - Stop the daemon", COLOR_RESULT);
addLine(TR("console_common_rpc"), COLOR_INFO);
addLine(TR("console_help_getinfo"), COLOR_RESULT);
addLine(TR("console_help_getbalance"), COLOR_RESULT);
addLine(TR("console_help_gettotalbalance"), COLOR_RESULT);
addLine(TR("console_help_getblockcount"), COLOR_RESULT);
addLine(TR("console_help_getpeerinfo"), COLOR_RESULT);
addLine(TR("console_help_setgenerate"), COLOR_RESULT);
addLine(TR("console_help_getmininginfo"), COLOR_RESULT);
addLine(TR("console_help_stop"), COLOR_RESULT);
addLine("", COLOR_RESULT);
addLine("Click 'Commands' in the toolbar for full RPC reference", COLOR_INFO);
addLine("Use Tab for command completion, Up/Down for history", COLOR_INFO);
addLine(TR("console_click_commands"), COLOR_INFO);
addLine(TR("console_tab_completion"), COLOR_INFO);
return;
}
// Execute RPC command
if (!rpc || !rpc->isConnected()) {
addLine("Error: Not connected to daemon", COLOR_ERROR);
addLine(TR("console_not_connected"), COLOR_ERROR);
return;
}
@@ -1839,7 +1851,7 @@ void ConsoleTab::clear()
last_xmrig_output_size_ = 0;
}
// addLine() takes the lock itself, so call it outside the locked scope
addLine("Console cleared", COLOR_INFO);
addLine(TR("console_cleared"), COLOR_INFO);
}
} // namespace ui
+1
View File
@@ -119,6 +119,7 @@ private:
size_t last_xmrig_output_size_ = 0;
bool shown_startup_message_ = false;
daemon::EmbeddedDaemon::State last_daemon_state_ = daemon::EmbeddedDaemon::State::Stopped;
bool last_rpc_connected_ = false;
// Text selection state
bool is_selecting_ = false;
+11 -13
View File
@@ -69,16 +69,14 @@ void ExportAllKeysDialog::render(App* app)
auto exportBtn = S.button("dialogs.export-all-keys", "export-button");
auto closeBtn = S.button("dialogs.export-all-keys", "close-button");
if (material::BeginOverlayDialog("Export All Private Keys", &s_open, win.width, 0.94f)) {
if (material::BeginOverlayDialog(TR("export_keys_title"), &s_open, win.width, 0.94f)) {
// Warning
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.4f, 0.4f, 1.0f));
ImGui::PushFont(material::Type().iconSmall());
ImGui::Text(ICON_MD_WARNING);
ImGui::PopFont();
ImGui::SameLine(0, 4.0f);
ImGui::TextWrapped("DANGER: This will export ALL private keys from your wallet! "
"Anyone with access to this file can steal your funds. "
"Store it securely and delete after use.");
ImGui::TextWrapped("%s", TR("export_keys_danger"));
ImGui::PopStyleColor();
ImGui::Spacing();
@@ -90,19 +88,19 @@ void ExportAllKeysDialog::render(App* app)
}
// Options
ImGui::Text("Export options:");
ImGui::Checkbox("Include Z-addresses (shielded)", &s_include_z);
ImGui::Checkbox("Include T-addresses (transparent)", &s_include_t);
ImGui::Text("%s", TR("export_keys_options"));
ImGui::Checkbox(TR("export_keys_include_z"), &s_include_z);
ImGui::Checkbox(TR("export_keys_include_t"), &s_include_t);
ImGui::Spacing();
// Filename
ImGui::Text("Output filename:");
ImGui::Text("%s", TR("output_filename"));
ImGui::SetNextItemWidth(-1);
ImGui::InputText("##Filename", s_filename, sizeof(s_filename));
ImGui::Spacing();
ImGui::TextDisabled("File will be saved in: ~/.config/ObsidianDragon/");
ImGui::TextDisabled("%s", TR("file_save_location"));
if (s_exporting) {
ImGui::EndDisabled();
@@ -117,7 +115,7 @@ void ExportAllKeysDialog::render(App* app)
ImGui::BeginDisabled();
}
if (material::StyledButton("Export Keys", ImVec2(exportBtn.width, 0), S.resolveFont(exportBtn.font))) {
if (material::StyledButton(TR("export_keys_btn"), ImVec2(exportBtn.width, 0), S.resolveFont(exportBtn.font))) {
if (!s_include_z && !s_include_t) {
Notifications::instance().warning("Select at least one address type");
} else if (!app->rpc() || !app->rpc()->isConnected()) {
@@ -215,7 +213,7 @@ void ExportAllKeysDialog::render(App* app)
s_exporting = false;
if (writeOk) {
s_status = "Exported to: " + filepath;
Notifications::instance().success("Keys exported successfully");
Notifications::instance().success(TR("export_keys_success"));
} else {
s_status = "Failed to write file";
Notifications::instance().error("Failed to save key file");
@@ -229,11 +227,11 @@ void ExportAllKeysDialog::render(App* app)
if (s_exporting) {
ImGui::EndDisabled();
ImGui::SameLine();
ImGui::TextDisabled("Exporting %d/%d...", s_exported_count, s_total_addresses);
ImGui::TextDisabled(TR("export_keys_progress"), s_exported_count, s_total_addresses);
}
ImGui::SameLine();
if (material::StyledButton("Close", ImVec2(closeBtn.width, 0), S.resolveFont(closeBtn.font))) {
if (material::StyledButton(TR("close"), ImVec2(closeBtn.width, 0), S.resolveFont(closeBtn.font))) {
s_open = false;
}
@@ -72,31 +72,31 @@ void ExportTransactionsDialog::render(App* app)
auto exportBtn = S.button("dialogs.export-transactions", "export-button");
auto closeBtn = S.button("dialogs.export-transactions", "close-button");
if (material::BeginOverlayDialog("Export Transactions to CSV", &s_open, win.width, 0.94f)) {
if (material::BeginOverlayDialog(TR("export_tx_title"), &s_open, win.width, 0.94f)) {
const auto& state = app->getWalletState();
ImGui::Text("Export %zu transactions to CSV file.", state.transactions.size());
ImGui::Text(TR("export_tx_count"), state.transactions.size());
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
// Filename
ImGui::Text("Output filename:");
ImGui::Text("%s", TR("output_filename"));
ImGui::SetNextItemWidth(-1);
ImGui::InputText("##Filename", s_filename, sizeof(s_filename));
ImGui::Spacing();
ImGui::TextDisabled("File will be saved in: ~/.config/ObsidianDragon/");
ImGui::TextDisabled("%s", TR("file_save_location"));
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
// Export button
if (material::StyledButton("Export", ImVec2(exportBtn.width, 0), S.resolveFont(exportBtn.font))) {
if (material::StyledButton(TR("export"), ImVec2(exportBtn.width, 0), S.resolveFont(exportBtn.font))) {
if (state.transactions.empty()) {
Notifications::instance().warning("No transactions to export");
Notifications::instance().warning(TR("export_tx_none"));
} else {
std::string configDir = util::Platform::getConfigDir();
std::string filepath = configDir + "/" + s_filename;
@@ -104,7 +104,7 @@ void ExportTransactionsDialog::render(App* app)
std::ofstream file(filepath);
if (!file.is_open()) {
s_status = "Failed to create file";
Notifications::instance().error("Failed to create CSV file");
Notifications::instance().error(TR("export_tx_file_fail"));
} else {
// Write CSV header
file << "Date,Type,Amount,Address,TXID,Confirmations,Memo\n";
@@ -142,7 +142,7 @@ void ExportTransactionsDialog::render(App* app)
s_status = "Exported " + std::to_string(state.transactions.size()) +
" transactions to: " + filepath;
Notifications::instance().success("Transactions exported successfully");
Notifications::instance().success(TR("export_tx_success"));
}
}
}
+18 -21
View File
@@ -113,15 +113,14 @@ void ImportKeyDialog::render(App* app)
auto importBtn = S.button("dialogs.import-key", "import-button");
auto closeBtn = S.button("dialogs.import-key", "close-button");
if (material::BeginOverlayDialog("Import Private Key", &s_open, win.width, 0.94f)) {
if (material::BeginOverlayDialog(TR("import_key_title"), &s_open, win.width, 0.94f)) {
// Warning
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.8f, 0.0f, 1.0f));
ImGui::PushFont(material::Type().iconSmall());
ImGui::Text(ICON_MD_WARNING);
ImGui::PopFont();
ImGui::SameLine(0, 4.0f);
ImGui::TextWrapped("Warning: Never share your private keys! "
"Importing keys from untrusted sources can compromise your wallet.");
ImGui::TextWrapped("%s", TR("import_key_warning"));
ImGui::PopStyleColor();
ImGui::Spacing();
@@ -129,13 +128,11 @@ void ImportKeyDialog::render(App* app)
ImGui::Spacing();
// Key input
ImGui::Text("Private Key(s):");
ImGui::Text("%s", TR("import_key_label"));
ImGui::SameLine();
ImGui::TextDisabled("(?)");
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Enter one or more private keys, one per line.\n"
"Supports both z-address and t-address keys.\n"
"Lines starting with # are treated as comments.");
ImGui::SetTooltip("%s", TR("import_key_tooltip"));
}
if (s_importing) {
@@ -147,7 +144,7 @@ void ImportKeyDialog::render(App* app)
ImVec2(-1, keyInput.height > 0 ? keyInput.height : 150), ImGuiInputTextFlags_AllowTabInput);
// Paste button
if (material::StyledButton("Paste from Clipboard", ImVec2(0,0), S.resolveFont(importBtn.font))) {
if (material::StyledButton(TR("paste_from_clipboard"), ImVec2(0,0), S.resolveFont(importBtn.font))) {
const char* clipboard = ImGui::GetClipboardText();
if (clipboard) {
strncpy(s_key_input, clipboard, sizeof(s_key_input) - 1);
@@ -155,24 +152,24 @@ void ImportKeyDialog::render(App* app)
}
ImGui::SameLine();
if (material::StyledButton("Clear", ImVec2(0,0), S.resolveFont(importBtn.font))) {
if (material::StyledButton(TR("clear"), ImVec2(0,0), S.resolveFont(importBtn.font))) {
s_key_input[0] = '\0';
}
ImGui::Spacing();
// Rescan options
ImGui::Checkbox("Rescan blockchain after import", &s_rescan);
ImGui::Checkbox(TR("import_key_rescan"), &s_rescan);
if (s_rescan) {
ImGui::Indent();
ImGui::Text("Start height:");
ImGui::Text("%s", TR("import_key_start_height"));
ImGui::SameLine();
ImGui::SetNextItemWidth(rescanInput.width);
ImGui::InputInt("##RescanHeight", &s_rescan_height);
if (s_rescan_height < 0) s_rescan_height = 0;
ImGui::SameLine();
ImGui::TextDisabled("(0 = full rescan)");
ImGui::TextDisabled("%s", TR("import_key_full_rescan"));
ImGui::Unindent();
}
@@ -189,13 +186,13 @@ void ImportKeyDialog::render(App* app)
ImGui::BeginDisabled();
}
if (material::StyledButton("Import Key(s)", ImVec2(importBtn.width, 0), S.resolveFont(importBtn.font))) {
if (material::StyledButton(TR("import_key_btn"), ImVec2(importBtn.width, 0), S.resolveFont(importBtn.font))) {
auto keys = splitKeys(s_key_input);
if (keys.empty()) {
Notifications::instance().warning("No valid keys found in input");
Notifications::instance().warning(TR("import_key_no_valid"));
} else if (!app->rpc() || !app->rpc()->isConnected()) {
Notifications::instance().error("Not connected to daemon");
Notifications::instance().error(TR("not_connected"));
} else {
s_importing = true;
s_total_keys = static_cast<int>(keys.size());
@@ -237,7 +234,7 @@ void ImportKeyDialog::render(App* app)
imported, failed);
s_status = buf;
if (imported > 0) {
Notifications::instance().success("Keys imported successfully");
Notifications::instance().success(TR("import_key_success"));
}
};
});
@@ -248,11 +245,11 @@ void ImportKeyDialog::render(App* app)
if (s_importing) {
ImGui::EndDisabled();
ImGui::SameLine();
ImGui::TextDisabled("Importing %d/%d...", s_imported_keys + s_failed_keys, s_total_keys);
ImGui::TextDisabled(TR("import_key_progress"), s_imported_keys + s_failed_keys, s_total_keys);
}
ImGui::SameLine();
if (material::StyledButton("Close", ImVec2(closeBtn.width, 0), S.resolveFont(closeBtn.font))) {
if (material::StyledButton(TR("close"), ImVec2(closeBtn.width, 0), S.resolveFont(closeBtn.font))) {
s_open = false;
}
@@ -271,9 +268,9 @@ void ImportKeyDialog::render(App* app)
ImGui::Spacing();
// Help text
ImGui::TextDisabled("Supported key formats:");
ImGui::BulletText("Z-address spending keys (secret-extended-key-...)");
ImGui::BulletText("T-address WIF private keys");
ImGui::TextDisabled("%s", TR("import_key_formats"));
ImGui::BulletText("%s", TR("import_key_z_format"));
ImGui::BulletText("%s", TR("import_key_t_format"));
material::EndOverlayDialog();
}
}
+12 -14
View File
@@ -63,15 +63,13 @@ void KeyExportDialog::render(App* app)
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.6f, 0.2f, 0.2f, 0.3f));
ImGui::BeginChild("WarningBox", ImVec2(-1, warningBox.height > 0 ? warningBox.height : 80), true);
ImGui::TextColored(ImVec4(1.0f, 0.4f, 0.4f, 1.0f), " WARNING!");
ImGui::TextColored(ImVec4(1.0f, 0.4f, 0.4f, 1.0f), " %s", TR("warning_upper"));
ImGui::Spacing();
if (s_key_type == KeyType::Private) {
ImGui::TextWrapped(" Keep this key SECRET! Anyone with this key can spend your "
"funds. Never share it online or with untrusted parties.");
ImGui::TextWrapped(" %s", TR("key_export_private_warning"));
} else {
ImGui::TextWrapped(" This viewing key allows others to see your incoming transactions "
"and balance, but NOT spend your funds. Share only with trusted parties.");
ImGui::TextWrapped(" %s", TR("key_export_viewing_warning"));
}
ImGui::EndChild();
@@ -82,7 +80,7 @@ void KeyExportDialog::render(App* app)
ImGui::Spacing();
// Address display
ImGui::Text("Address:");
ImGui::Text("%s", TR("address_label"));
// Determine if it's a z-address (longer) or t-address
bool is_zaddr = s_address.length() > 50;
@@ -105,16 +103,16 @@ void KeyExportDialog::render(App* app)
ImGui::Spacing();
// Key display section
const char* key_label = (s_key_type == KeyType::Private) ? "Private Key:" : "Viewing Key:";
const char* key_label = (s_key_type == KeyType::Private) ? TR("key_export_private_key") : TR("key_export_viewing_key");
ImGui::Text("%s", key_label);
if (s_fetching) {
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "Fetching key from wallet...");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "%s", TR("key_export_fetching"));
} else if (!s_error.empty()) {
ImGui::TextColored(ImVec4(1.0f, 0.3f, 0.3f, 1.0f), "Error: %s", s_error.c_str());
ImGui::TextColored(ImVec4(1.0f, 0.3f, 0.3f, 1.0f), TR("error_format"), s_error.c_str());
} else if (s_key.empty()) {
// Show button to fetch key
if (material::StyledButton("Reveal Key", ImVec2(revealBtn.width, 0), S.resolveFont(revealBtn.font))) {
if (material::StyledButton(TR("key_export_reveal"), ImVec2(revealBtn.width, 0), S.resolveFont(revealBtn.font))) {
s_fetching = true;
// Check if z-address or t-address
@@ -171,13 +169,13 @@ void KeyExportDialog::render(App* app)
});
}
} else {
s_error = "Viewing keys are only available for shielded (z) addresses";
s_error = TR("key_export_viewing_keys_zonly");
s_fetching = false;
}
}
}
ImGui::SameLine();
ImGui::TextDisabled("Click to retrieve the key from your wallet");
ImGui::TextDisabled("%s", TR("key_export_click_retrieve"));
} else {
// Key has been fetched - display it
@@ -201,7 +199,7 @@ void KeyExportDialog::render(App* app)
// Show/Hide and Copy buttons
ImGui::Spacing();
if (material::StyledButton(s_show_key ? "Hide" : "Show", ImVec2(toggleBtn.width, 0), S.resolveFont(toggleBtn.font))) {
if (material::StyledButton(s_show_key ? TR("hide") : TR("show"), ImVec2(toggleBtn.width, 0), S.resolveFont(toggleBtn.font))) {
s_show_key = !s_show_key;
}
@@ -222,7 +220,7 @@ void KeyExportDialog::render(App* app)
float avail_width = ImGui::GetContentRegionAvail().x;
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + (avail_width - button_width) / 2.0f);
if (material::StyledButton("Close", ImVec2(button_width, 0), S.resolveFont(closeBtn.font))) {
if (material::StyledButton(TR("close"), ImVec2(button_width, 0), S.resolveFont(closeBtn.font))) {
s_open = false;
// Clear sensitive data
s_key.clear();
+118 -88
View File
@@ -8,6 +8,7 @@
#include "../../data/wallet_state.h"
#include "../../config/settings.h"
#include "../../data/exchange_info.h"
#include "../../util/i18n.h"
#include "../schema/ui_schema.h"
#include "../material/type.h"
#include "../material/draw_helpers.h"
@@ -147,15 +148,17 @@ void RenderMarketTab(App* app)
float mkCardBudget = std::max(200.0f, marketAvail.y - mkOverhead);
Layout::SectionBudget mb(mkCardBudget);
float statsMarketBudH = mb.allocate(0.14f, S.drawElement("tabs.market", "stats-card-min-height").size);
float portfolioBudgetH = mb.allocate(0.18f, 50.0f);
// ================================================================
// PRICE HERO — Large glass card with price + change badge
// PRICE SUMMARY — Combined hero card with price, stats, and exchange
// ================================================================
{
float dp = Layout::dpiScale();
ImVec2 cardMin = ImGui::GetCursorScreenPos();
float cardH = std::max(S.drawElement("tabs.market", "hero-card-min-height").size, S.drawElement("tabs.market", "hero-card-height").size * vs);
float heroMinH = S.drawElement("tabs.market", "hero-card-min-height").size;
float statsRowH = ovFont->LegacySize + Layout::spacingXs() + sub1->LegacySize + pad;
float cardH = std::max(heroMinH + statsRowH + pad, (S.drawElement("tabs.market", "hero-card-height").size + statsRowH + pad) * vs);
ImVec2 cardMax(cardMin.x + availWidth, cardMin.y + cardH);
DrawGlassPanel(dl, cardMin, cardMax, glassSpec);
@@ -172,36 +175,118 @@ void RenderMarketTab(App* app)
float cy = cardMin.y + Layout::spacingLg();
if (market.price_usd > 0) {
// Large price with text shadow
// ---- HERO PRICE (large, prominent) ----
ImFont* h3 = Type().h3();
std::string priceStr = FormatPrice(market.price_usd);
ImU32 priceCol = Success();
DrawTextShadow(dl, h4, h4->LegacySize, ImVec2(cx, cy), priceCol, priceStr.c_str());
DrawTextShadow(dl, h3, h3->LegacySize, ImVec2(cx, cy), priceCol, priceStr.c_str());
// BTC price beside it
float priceW = h4->CalcTextSizeA(h4->LegacySize, FLT_MAX, 0, priceStr.c_str()).x;
snprintf(buf, sizeof(buf), "%.10f BTC", market.price_btc);
dl->AddText(capFont, capFont->LegacySize,
ImVec2(cx + priceW + Layout::spacingXl(), cy + (h4->LegacySize - capFont->LegacySize)),
OnSurfaceMedium(), buf);
// Ticker label after price
float priceW = h3->CalcTextSizeA(h3->LegacySize, FLT_MAX, 0, priceStr.c_str()).x;
dl->AddText(body2, body2->LegacySize,
ImVec2(cx + priceW + Layout::spacingSm(), cy + (h3->LegacySize - body2->LegacySize)),
OnSurfaceMedium(), DRAGONX_TICKER);
// 24h change badge
float badgeY = cy + h4->LegacySize + 8;
// 24h change badge — to the right of ticker
float tickerW = body2->CalcTextSizeA(body2->LegacySize, FLT_MAX, 0, DRAGONX_TICKER).x;
float badgeX = cx + priceW + Layout::spacingSm() + tickerW + Layout::spacingMd();
ImU32 chgCol = market.change_24h >= 0 ? Success() : Error();
snprintf(buf, sizeof(buf), "%s%.2f%%", market.change_24h >= 0 ? "+" : "", market.change_24h);
ImVec2 txtSz = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0, buf);
float badgePad = Layout::spacingSm() + Layout::spacingXs();
ImVec2 bMin(cx, badgeY);
ImVec2 bMax(cx + txtSz.x + badgePad * 2, badgeY + txtSz.y + badgePad);
snprintf(buf, sizeof(buf), "%s%.2f%% 24h", market.change_24h >= 0 ? "+" : "", market.change_24h);
ImVec2 chgSz = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0, buf);
float badgePadH = Layout::spacingSm();
float badgePadV = Layout::spacingXs();
ImVec2 bMin(badgeX, cy + (h3->LegacySize - chgSz.y - badgePadV * 2) * 0.5f);
ImVec2 bMax(badgeX + chgSz.x + badgePadH * 2, bMin.y + chgSz.y + badgePadV * 2);
ImU32 badgeBg = market.change_24h >= 0 ? WithAlpha(Success(), 30) : WithAlpha(Error(), 30);
dl->AddRectFilled(bMin, bMax, badgeBg, 4.0f);
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx + badgePad, badgeY + badgePad * 0.5f), chgCol, buf);
dl->AddRectFilled(bMin, bMax, badgeBg, 4.0f * dp);
dl->AddText(capFont, capFont->LegacySize, ImVec2(bMin.x + badgePadH, bMin.y + badgePadV), chgCol, buf);
// "24h" label after badge
dl->AddText(capFont, capFont->LegacySize,
ImVec2(bMax.x + 6, badgeY + badgePad * 0.5f), OnSurfaceDisabled(), "24h");
// ---- SEPARATOR ----
float sepY = cy + h3->LegacySize + Layout::spacingMd();
float rnd = glassSpec.rounding;
dl->AddLine(ImVec2(cardMin.x + rnd * 0.5f, sepY),
ImVec2(cardMax.x - rnd * 0.5f, sepY),
WithAlpha(OnSurface(), 15), 1.0f * dp);
// ---- STATS ROW (BTC Price | Volume | Market Cap) ----
float statsY = sepY + Layout::spacingSm();
float colW = (availWidth - Layout::spacingLg() * 2) / 3.0f;
struct StatItem { const char* label; std::string value; ImU32 valueCol; };
StatItem stats[3] = {
{TR("market_btc_price"), "", OnSurface()},
{TR("market_24h_volume"), FormatCompactUSD(market.volume_24h), OnSurface()},
{TR("market_cap"), FormatCompactUSD(market.market_cap), OnSurface()},
};
snprintf(buf, sizeof(buf), "%.10f", market.price_btc);
stats[0].value = buf;
for (int i = 0; i < 3; i++) {
float sx = cardMin.x + Layout::spacingLg() + i * colW;
float centerX = sx + colW * 0.5f;
// Label (overline, centered)
ImVec2 lblSz = ovFont->CalcTextSizeA(ovFont->LegacySize, 10000, 0, stats[i].label);
dl->AddText(ovFont, ovFont->LegacySize,
ImVec2(centerX - lblSz.x * 0.5f, statsY), OnSurfaceMedium(), stats[i].label);
// Value (subtitle1, centered)
float valY = statsY + ovFont->LegacySize + Layout::spacingXs();
ImVec2 valSz = sub1->CalcTextSizeA(sub1->LegacySize, 10000, 0, stats[i].value.c_str());
dl->AddText(sub1, sub1->LegacySize,
ImVec2(centerX - valSz.x * 0.5f, valY), stats[i].valueCol, stats[i].value.c_str());
}
// ---- TRADE BUTTON (top-right of card) ----
if (!currentExchange.pairs.empty()) {
const char* pairName = currentExchange.pairs[s_pair_idx].displayName.c_str();
ImFont* iconFont = Type().iconSmall();
ImVec2 textSz = body2->CalcTextSizeA(body2->LegacySize, FLT_MAX, 0, pairName);
ImVec2 iconSz = iconFont->CalcTextSizeA(iconFont->LegacySize, FLT_MAX, 0, ICON_MD_OPEN_IN_NEW);
float iconGap = Layout::spacingSm();
float tradePadH = Layout::spacingMd();
float tradePadV = Layout::spacingSm();
float tradeBtnW = textSz.x + iconGap + iconSz.x + tradePadH * 2;
float tradeBtnH = std::max(textSz.y, iconSz.y) + tradePadV * 2;
float tradeBtnX = cardMax.x - pad - tradeBtnW;
float tradeBtnY = cardMin.y + Layout::spacingSm();
ImVec2 tMin(tradeBtnX, tradeBtnY), tMax(tradeBtnX + tradeBtnW, tradeBtnY + tradeBtnH);
bool tradeHov = material::IsRectHovered(tMin, tMax);
// Glass pill background
GlassPanelSpec tradeBtnGlass;
tradeBtnGlass.rounding = tradeBtnH * 0.5f;
tradeBtnGlass.fillAlpha = tradeHov ? 35 : 20;
DrawGlassPanel(dl, tMin, tMax, tradeBtnGlass);
if (tradeHov)
dl->AddRectFilled(tMin, tMax, WithAlpha(Primary(), 20), tradeBtnH * 0.5f);
// Text (pair name with body2, icon with icon font)
ImU32 tradeCol = tradeHov ? OnSurface() : OnSurfaceMedium();
float contentY = tradeBtnY + tradePadV;
float curX = tradeBtnX + tradePadH;
dl->AddText(body2, body2->LegacySize,
ImVec2(curX, contentY), tradeCol, pairName);
curX += textSz.x + iconGap;
dl->AddText(iconFont, iconFont->LegacySize,
ImVec2(curX, contentY + (textSz.y - iconSz.y) * 0.5f), tradeCol, ICON_MD_OPEN_IN_NEW);
// Click
ImVec2 savedCur = ImGui::GetCursorScreenPos();
ImGui::SetCursorScreenPos(tMin);
ImGui::InvisibleButton("##TradeOnExchange", ImVec2(tradeBtnW, tradeBtnH));
if (ImGui::IsItemClicked()) {
util::Platform::openUrl(currentExchange.pairs[s_pair_idx].tradeUrl);
}
if (ImGui::IsItemHovered()) {
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
ImGui::SetTooltip(TR("market_trade_on"), currentExchange.name.c_str());
}
ImGui::SetCursorScreenPos(savedCur);
}
} else {
DrawTextShadow(dl, sub1, sub1->LegacySize, ImVec2(cx, cy + 10), OnSurfaceDisabled(), "Price data unavailable");
DrawTextShadow(dl, sub1, sub1->LegacySize, ImVec2(cx, cy + 10), OnSurfaceDisabled(), TR("market_price_unavailable"));
}
ImGui::SetCursorScreenPos(ImVec2(cardMin.x, cardMax.y));
@@ -209,42 +294,6 @@ void RenderMarketTab(App* app)
ImGui::Dummy(ImVec2(0, gap));
}
// ================================================================
// STATS — Three glass cards (Price | Volume | Market Cap)
// ================================================================
{
float cardW = (availWidth - 2 * gap) / 3.0f;
float cardH = std::min(StatCardHeight(vs), statsMarketBudH);
ImVec2 origin = ImGui::GetCursorScreenPos();
struct StatInfo { const char* label; std::string value; ImU32 col; ImU32 accent; };
StatInfo cards[3] = {
{"PRICE", market.price_usd > 0 ? FormatPrice(market.price_usd) : "N/A",
OnSurface(), WithAlpha(Success(), 200)},
{"24H VOLUME", FormatCompactUSD(market.volume_24h),
OnSurface(), WithAlpha(Secondary(), 200)},
{"MARKET CAP", FormatCompactUSD(market.market_cap),
OnSurface(), WithAlpha(Warning(), 200)},
};
for (int i = 0; i < 3; i++) {
float xOff = i * (cardW + gap);
ImVec2 cMin(origin.x + xOff, origin.y);
ImVec2 cMax(cMin.x + cardW, cMin.y + cardH);
StatCardSpec sc;
sc.overline = cards[i].label;
sc.value = cards[i].value.c_str();
sc.valueCol = cards[i].col;
sc.accentCol = cards[i].accent;
sc.centered = true;
DrawStatCard(dl, cMin, cMax, sc, glassSpec);
}
ImGui::Dummy(ImVec2(availWidth, cardH));
ImGui::Dummy(ImVec2(0, gap));
}
// ================================================================
// PRICE CHART — Custom drawn inside glass panel (matches app design)
// ================================================================
@@ -340,7 +389,7 @@ void RenderMarketTab(App* app)
// X-axis labels
const int xlabels[] = {0, 6, 12, 18, 23};
const char* xlabelText[] = {"24h", "18h", "12h", "6h", "Now"};
const char* xlabelText[] = {TR("market_24h"), TR("market_18h"), TR("market_12h"), TR("market_6h"), TR("market_now")};
for (int xi = 0; xi < 5; xi++) {
int idx = xlabels[xi];
float t = (float)idx / (float)(n - 1);
@@ -395,7 +444,7 @@ void RenderMarketTab(App* app)
ImVec2(tipX + tipPad, tipY + tipPad), dotCol, buf);
}
} else {
const char* msg = "No price history available";
const char* msg = TR("market_no_history");
ImVec2 ts = sub1->CalcTextSizeA(sub1->LegacySize, FLT_MAX, 0, msg);
dl->AddText(sub1, sub1->LegacySize,
ImVec2(chartMin.x + (availWidth - ts.x) * 0.5f, chartMin.y + chartH * 0.45f),
@@ -429,7 +478,7 @@ void RenderMarketTab(App* app)
s_history_initialized = false;
s_last_refresh_time = ImGui::GetTime();
}
if (ImGui::IsItemHovered()) ImGui::SetTooltip("Refresh price data");
if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", TR("market_refresh_price"));
// Timestamp text to the left of refresh button
if (s_last_refresh_time > 0.0) {
@@ -452,7 +501,7 @@ void RenderMarketTab(App* app)
}
// ================================================================
// EXCHANGE SELECTOR — Combo dropdown + pair name + trade link
// EXCHANGE SELECTOR — Combo dropdown + attribution
// ================================================================
ImGui::Dummy(ImVec2(0, S.drawElement("tabs.market", "exchange-top-gap").size));
{
@@ -483,28 +532,9 @@ void RenderMarketTab(App* app)
}
ImGui::PopItemWidth();
// Show current pair name beside combo
if (!currentExchange.pairs.empty()) {
ImGui::SameLine(0, Layout::spacingLg());
Type().textColored(TypeStyle::Subtitle1, OnSurface(),
currentExchange.pairs[s_pair_idx].displayName.c_str());
// "Open on exchange" button
ImGui::SameLine(0, Layout::spacingSm());
ImGui::PushFont(material::Typography::instance().iconSmall());
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4, 4));
snprintf(buf, sizeof(buf), ICON_MD_OPEN_IN_NEW "##TradeLink");
if (ImGui::Button(buf)) {
util::Platform::openUrl(currentExchange.pairs[s_pair_idx].tradeUrl);
}
ImGui::PopStyleVar();
ImGui::PopFont();
if (ImGui::IsItemHovered()) ImGui::SetTooltip("Open on %s", currentExchange.name.c_str());
}
// Attribution
ImGui::SameLine(0, Layout::spacingLg());
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), "Price data from CoinGecko API");
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), TR("market_attribution"));
if (!market.last_updated.empty()) {
ImGui::SameLine(0, 12);
@@ -722,7 +752,7 @@ void RenderMarketTab(App* app)
// PORTFOLIO — Glass card with balance breakdown
// ================================================================
{
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "PORTFOLIO");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("market_portfolio"));
ImGui::Dummy(ImVec2(0, Layout::spacingXs()));
double total_balance = state.totalBalance;
@@ -760,7 +790,7 @@ void RenderMarketTab(App* app)
dl->AddText(capFont, capFont->LegacySize,
ImVec2(cardMax.x - valW - pad, cy + 2), OnSurfaceMedium(), buf);
} else {
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, cy), OnSurfaceDisabled(), "No price data");
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, cy), OnSurfaceDisabled(), TR("market_no_price"));
}
cy += sub1->LegacySize + 8;
@@ -799,7 +829,7 @@ void RenderMarketTab(App* app)
shieldedW > 0.5f ? ImDrawFlags_RoundCornersRight : ImDrawFlags_RoundCornersAll, 3.0f);
int pct = (int)(shieldedRatio * 100.0f + 0.5f);
snprintf(buf, sizeof(buf), "%d%% Shielded", pct);
snprintf(buf, sizeof(buf), TR("market_pct_shielded"), pct);
dl->AddText(capFont, capFont->LegacySize,
ImVec2(cx, cy + barH + 2), OnSurfaceDisabled(), buf);
}
+210 -86
View File
@@ -4,6 +4,7 @@
#include "mining_tab.h"
#include "../../app.h"
#include "../../util/i18n.h"
#include "../../config/version.h"
#include "../../data/wallet_state.h"
#include "../../config/settings.h"
@@ -38,6 +39,9 @@ static bool s_threads_initialized = false;
static bool s_drag_active = false;
static int s_drag_anchor_thread = 0; // thread# where drag started
// Earnings filter: 0 = All, 1 = Solo, 2 = Pool
static int s_earnings_filter = 0;
// Pool mode state
static bool s_pool_mode = false;
static char s_pool_url[256] = "pool.dragonx.is:3433";
@@ -126,7 +130,13 @@ void RenderMiningTab(App* app)
int max_threads = GetMaxMiningThreads();
if (!s_threads_initialized) {
s_selected_threads = mining.generate ? std::max(1, mining.genproclimit) : 1;
int saved = app->settings()->getPoolThreads();
if (mining.generate)
s_selected_threads = std::max(1, mining.genproclimit);
else if (saved > 0)
s_selected_threads = std::min(saved, max_threads);
else
s_selected_threads = 1;
s_threads_initialized = true;
}
@@ -234,7 +244,7 @@ void RenderMiningTab(App* app)
dl->AddRectFilled(soloMin, soloMax, WithAlpha(OnSurface(), 20), toggleRnd);
}
{
const char* label = "SOLO";
const char* label = TR("mining_solo");
ImVec2 sz = ovFont->CalcTextSizeA(ovFont->LegacySize, FLT_MAX, 0, label);
float lx = soloMin.x + (toggleW - sz.x) * 0.5f;
float ly = soloMin.y + (toggleH - sz.y) * 0.5f;
@@ -255,7 +265,7 @@ void RenderMiningTab(App* app)
dl->AddRectFilled(poolMin, poolMax, WithAlpha(OnSurface(), 20), toggleRnd);
}
{
const char* label = "POOL";
const char* label = TR("mining_pool");
ImVec2 sz = ovFont->CalcTextSizeA(ovFont->LegacySize, FLT_MAX, 0, label);
float lx = poolMin.x + (toggleW - sz.x) * 0.5f;
float ly = poolMin.y + (toggleH - sz.y) * 0.5f;
@@ -287,7 +297,7 @@ void RenderMiningTab(App* app)
}
if (poolHov && !soloMiningActive) ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
if (poolHov && soloMiningActive && !s_pool_mode) {
ImGui::SetTooltip("Stop solo mining to use pool mining");
ImGui::SetTooltip("%s", TR("mining_stop_solo_for_pool"));
}
ImGui::SetCursorScreenPos(ImVec2(tMin.x, tMax.y));
@@ -307,7 +317,7 @@ void RenderMiningTab(App* app)
ImGui::PopFont();
ImGui::SameLine(0, Layout::spacingSm());
ImGui::PushFont(capFont);
ImGui::TextUnformatted("Stop solo mining to configure pool settings");
ImGui::TextUnformatted(TR("mining_stop_solo_for_pool_settings"));
ImGui::PopFont();
ImGui::PopStyleColor();
} else if (s_pool_mode) {
@@ -339,7 +349,7 @@ void RenderMiningTab(App* app)
// === Pool URL input ===
ImGui::SetNextItemWidth(urlW);
if (ImGui::InputTextWithHint("##PoolURL", "Pool URL", s_pool_url, sizeof(s_pool_url))) {
if (ImGui::InputTextWithHint("##PoolURL", TR("mining_pool_url"), s_pool_url, sizeof(s_pool_url))) {
s_pool_settings_dirty = true;
}
@@ -357,7 +367,7 @@ void RenderMiningTab(App* app)
dl2->AddRectFilled(btnPos, ImVec2(btnPos.x + btnSize.x, btnPos.y + btnSize.y),
StateHover(), 4.0f * dp);
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
ImGui::SetTooltip("Saved pools");
ImGui::SetTooltip("%s", TR("mining_saved_pools"));
}
ImFont* icoFont = Type().iconSmall();
const char* dropIcon = ICON_MD_ARROW_DROP_DOWN;
@@ -389,7 +399,7 @@ void RenderMiningTab(App* app)
dl2->AddRectFilled(btnPos, ImVec2(btnPos.x + btnSize.x, btnPos.y + btnSize.y),
StateHover(), 4.0f * dp);
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
ImGui::SetTooltip(alreadySaved ? "Already saved" : "Save pool URL");
ImGui::SetTooltip("%s", alreadySaved ? TR("mining_already_saved") : TR("mining_save_pool_url"));
}
ImFont* icoFont = Type().iconSmall();
const char* saveIcon = alreadySaved ? ICON_MD_BOOKMARK : ICON_MD_BOOKMARK_BORDER;
@@ -416,11 +426,19 @@ void RenderMiningTab(App* app)
if (savedUrls.empty()) {
ImGui::SetCursorPosX(8 * dp);
ImGui::PushFont(Type().caption());
ImGui::TextDisabled("No saved pools");
ImGui::TextDisabled("%s", TR("mining_no_saved_pools"));
ImGui::PopFont();
ImGui::SetCursorPosX(8 * dp);
ImGui::PushFont(Type().caption());
ImGui::TextDisabled("Click " ICON_MD_BOOKMARK_BORDER " to save");
ImGui::TextDisabled("%s", TR("mining_click"));
ImGui::PopFont();
ImGui::SameLine(0, 2 * dp);
ImGui::PushFont(Type().iconSmall());
ImGui::TextDisabled(ICON_MD_BOOKMARK_BORDER);
ImGui::PopFont();
ImGui::SameLine(0, 2 * dp);
ImGui::PushFont(Type().caption());
ImGui::TextDisabled("%s", TR("mining_to_save"));
ImGui::PopFont();
} else {
std::string urlToRemove;
@@ -457,7 +475,7 @@ void RenderMiningTab(App* app)
if (inXZone) {
pdl->AddRectFilled(xMin, xMax, IM_COL32(255, 80, 80, 30));
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
ImGui::SetTooltip("Remove");
ImGui::SetTooltip("%s", TR("mining_remove"));
} else if (rowHov) {
// Show faint X when row is hovered
ImFont* icoF = Type().iconSmall();
@@ -508,11 +526,11 @@ void RenderMiningTab(App* app)
float wrkGroupW = wrkW + perGroupExtra;
ImGui::SetNextItemWidth(wrkW);
if (ImGui::InputTextWithHint("##PoolWorker", "Payout Address", s_pool_worker, sizeof(s_pool_worker))) {
if (ImGui::InputTextWithHint("##PoolWorker", TR("mining_payout_address"), s_pool_worker, sizeof(s_pool_worker))) {
s_pool_settings_dirty = true;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Your DRAGONX address for receiving pool payouts");
ImGui::SetTooltip("%s", TR("mining_payout_tooltip"));
}
// --- Worker: Dropdown arrow button ---
@@ -529,7 +547,7 @@ void RenderMiningTab(App* app)
dl2->AddRectFilled(btnPos, ImVec2(btnPos.x + btnSize.x, btnPos.y + btnSize.y),
StateHover(), 4.0f * dp);
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
ImGui::SetTooltip("Saved addresses");
ImGui::SetTooltip("%s", TR("mining_saved_addresses"));
}
ImFont* icoFont = Type().iconSmall();
const char* dropIcon = ICON_MD_ARROW_DROP_DOWN;
@@ -561,7 +579,7 @@ void RenderMiningTab(App* app)
dl2->AddRectFilled(btnPos, ImVec2(btnPos.x + btnSize.x, btnPos.y + btnSize.y),
StateHover(), 4.0f * dp);
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
ImGui::SetTooltip(alreadySaved ? "Already saved" : "Save payout address");
ImGui::SetTooltip("%s", alreadySaved ? TR("mining_already_saved") : TR("mining_save_payout_address"));
}
ImFont* icoFont = Type().iconSmall();
const char* saveIcon = alreadySaved ? ICON_MD_BOOKMARK : ICON_MD_BOOKMARK_BORDER;
@@ -589,11 +607,19 @@ void RenderMiningTab(App* app)
if (savedWorkers.empty()) {
ImGui::SetCursorPosX(8 * dp);
ImGui::PushFont(Type().caption());
ImGui::TextDisabled("No saved addresses");
ImGui::TextDisabled("%s", TR("mining_no_saved_addresses"));
ImGui::PopFont();
ImGui::SetCursorPosX(8 * dp);
ImGui::PushFont(Type().caption());
ImGui::TextDisabled("Click " ICON_MD_BOOKMARK_BORDER " to save");
ImGui::TextDisabled("%s", TR("mining_click"));
ImGui::PopFont();
ImGui::SameLine(0, 2 * dp);
ImGui::PushFont(Type().iconSmall());
ImGui::TextDisabled(ICON_MD_BOOKMARK_BORDER);
ImGui::PopFont();
ImGui::SameLine(0, 2 * dp);
ImGui::PushFont(Type().caption());
ImGui::TextDisabled("%s", TR("mining_to_save"));
ImGui::PopFont();
} else {
std::string addrToRemove;
@@ -633,7 +659,7 @@ void RenderMiningTab(App* app)
if (inXZone) {
pdl->AddRectFilled(xMin, xMax, IM_COL32(255, 80, 80, 30));
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
ImGui::SetTooltip("Remove");
ImGui::SetTooltip("%s", TR("mining_remove"));
} else if (rowHov) {
ImFont* icoF = Type().iconSmall();
const char* xIcon = ICON_MD_CLOSE;
@@ -694,7 +720,7 @@ void RenderMiningTab(App* app)
dl2->AddRectFilled(btnPos, ImVec2(btnPos.x + btnSize.x, btnPos.y + btnSize.y),
StateHover(), 4.0f * dp);
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
ImGui::SetTooltip("Reset to defaults");
ImGui::SetTooltip("%s", TR("mining_reset_defaults"));
}
// Icon
@@ -781,9 +807,9 @@ void RenderMiningTab(App* app)
// --- Header row: "THREADS 4 / 16" + RAM est + active indicator ---
{
ImVec2 labelPos(cardMin.x + pad, curY);
dl->AddText(ovFont, ovFont->LegacySize, labelPos, OnSurfaceMedium(), "THREADS");
dl->AddText(ovFont, ovFont->LegacySize, labelPos, OnSurfaceMedium(), TR("mining_threads"));
float labelW = ovFont->CalcTextSizeA(ovFont->LegacySize, FLT_MAX, 0, "THREADS").x;
float labelW = ovFont->CalcTextSizeA(ovFont->LegacySize, FLT_MAX, 0, TR("mining_threads")).x;
snprintf(buf, sizeof(buf), " %d / %d", s_selected_threads, max_threads);
ImVec2 countPos(labelPos.x + labelW, curY);
dl->AddText(sub1, sub1->LegacySize, countPos, OnSurface(), buf);
@@ -804,17 +830,58 @@ void RenderMiningTab(App* app)
OnSurfaceDisabled(), buf);
}
// Active mining indicator (top-right)
// Idle mining toggle (top-right corner of card)
float idleRightEdge = cardMax.x - pad;
{
bool idleOn = app->settings()->getMineWhenIdle();
ImFont* icoFont = Type().iconSmall();
const char* idleIcon = ICON_MD_SCHEDULE;
float icoH = icoFont->LegacySize;
float btnSz = icoH + 8.0f * dp;
float btnX = idleRightEdge - btnSz;
float btnY = curY + (headerH - btnSz) * 0.5f;
// Pill background when active
if (idleOn) {
dl->AddRectFilled(ImVec2(btnX, btnY), ImVec2(btnX + btnSz, btnY + btnSz),
WithAlpha(Primary(), 60), btnSz * 0.5f);
}
// Icon centered in button
ImVec2 icoSz = icoFont->CalcTextSizeA(icoFont->LegacySize, FLT_MAX, 0, idleIcon);
ImU32 icoCol = idleOn ? Primary() : OnSurfaceDisabled();
dl->AddText(icoFont, icoFont->LegacySize,
ImVec2(btnX + (btnSz - icoSz.x) * 0.5f, btnY + (btnSz - icoSz.y) * 0.5f),
icoCol, idleIcon);
// Click target (save/restore cursor so layout is unaffected)
ImVec2 savedCur = ImGui::GetCursorScreenPos();
ImGui::SetCursorScreenPos(ImVec2(btnX, btnY));
ImGui::InvisibleButton("##IdleMining", ImVec2(btnSz, btnSz));
if (ImGui::IsItemClicked()) {
app->settings()->setMineWhenIdle(!idleOn);
app->settings()->save();
}
if (ImGui::IsItemHovered()) {
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
ImGui::SetTooltip("%s", idleOn ? TR("mining_idle_on_tooltip") : TR("mining_idle_off_tooltip"));
}
ImGui::SetCursorScreenPos(savedCur);
idleRightEdge = btnX - 4.0f * dp;
}
// Active mining indicator (left of idle toggle)
if (mining.generate) {
float pulse = effects::isLowSpecMode()
? schema::UI().drawElement("animations", "pulse-base-normal").size
: schema::UI().drawElement("animations", "pulse-base-normal").size + schema::UI().drawElement("animations", "pulse-amp-normal").size * (float)std::sin((double)ImGui::GetTime() * schema::UI().drawElement("animations", "pulse-speed-normal").size);
ImU32 pulseCol = WithAlpha(Success(), (int)(255 * pulse));
float dotR = schema::UI().drawElement("tabs.mining", "active-dot-radius").size + 2.0f * hs;
dl->AddCircleFilled(ImVec2(cardMax.x - pad - dotR * 2, curY + dotR + 1 * dp), dotR, pulseCol);
dl->AddCircleFilled(ImVec2(idleRightEdge - dotR, curY + dotR + 1 * dp), dotR, pulseCol);
dl->AddText(capFont, capFont->LegacySize,
ImVec2(cardMax.x - pad - dotR * 2 - 60 * hs, curY),
WithAlpha(Success(), 200), "Mining");
ImVec2(idleRightEdge - dotR - dotR - 60 * hs, curY),
WithAlpha(Success(), 200), TR("mining_active"));
}
curY += headerH + secGap;
}
@@ -930,13 +997,17 @@ void RenderMiningTab(App* app)
dl->AddText(capFont, capFont->LegacySize, txtPos, txtCol, buf);
}
if (threads_changed && mining.generate) {
if (threads_changed) {
app->settings()->setPoolThreads(s_selected_threads);
app->settings()->save();
if (mining.generate) {
app->startMining(s_selected_threads);
}
if (threads_changed && s_pool_mode && state.pool_mining.xmrig_running) {
if (s_pool_mode && state.pool_mining.xmrig_running) {
app->stopPoolMining();
app->startPoolMining(s_selected_threads);
}
}
curY += gridH + secGap;
}
@@ -1059,20 +1130,20 @@ void RenderMiningTab(App* app)
const char* label;
ImU32 lblCol;
if (isToggling) {
label = isMiningActive ? "STOPPING" : "STARTING";
label = isMiningActive ? TR("mining_stopping") : TR("mining_starting");
// Animated dots effect via alpha pulse
float pulse = effects::isLowSpecMode()
? 0.7f
: 0.5f + 0.5f * (float)std::sin((double)ImGui::GetTime() * 3.0);
lblCol = WithAlpha(Primary(), (int)(120 + 135 * pulse));
} else if (isMiningActive) {
label = "STOP";
label = TR("mining_stop");
lblCol = WithAlpha(Error(), 220);
} else if (disabled) {
label = "MINE";
label = TR("mining_mine");
lblCol = WithAlpha(OnSurface(), 50);
} else {
label = "MINE";
label = TR("mining_mine");
lblCol = WithAlpha(OnSurface(), 160);
}
ImVec2 lblSz = ovFont->CalcTextSizeA(ovFont->LegacySize, FLT_MAX, 0, label);
@@ -1086,13 +1157,13 @@ void RenderMiningTab(App* app)
if (!disabled)
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
if (isToggling)
ImGui::SetTooltip(isMiningActive ? "Stopping miner..." : "Starting miner...");
ImGui::SetTooltip("%s", isMiningActive ? TR("mining_stopping_tooltip") : TR("mining_starting_tooltip"));
else if (isSyncing && !s_pool_mode)
ImGui::SetTooltip("Syncing blockchain... (%.1f%%)", state.sync.verification_progress * 100.0);
ImGui::SetTooltip(TR("mining_syncing_tooltip"), state.sync.verification_progress * 100.0);
else if (poolBlockedBySolo)
ImGui::SetTooltip("Stop solo mining before starting pool mining");
ImGui::SetTooltip("%s", TR("mining_stop_solo_for_pool"));
else
ImGui::SetTooltip(isMiningActive ? "Stop Mining" : "Start Mining");
ImGui::SetTooltip("%s", isMiningActive ? TR("stop_mining") : TR("start_mining"));
}
// Click action — pool or solo
@@ -1201,23 +1272,15 @@ void RenderMiningTab(App* app)
int numStats = 3;
if (s_pool_mode) {
col1Label = "POOL HASHRATE";
col1Label = TR("mining_local_hashrate");
col1Str = FormatHashrate(state.pool_mining.hashrate_10s);
col1Col = state.pool_mining.xmrig_running ? greenCol : OnSurfaceDisabled();
col2Label = "THREADS / MEM";
{
char buf[64];
int64_t memMB = state.pool_mining.memory_used / (1024 * 1024);
if (memMB > 0)
snprintf(buf, sizeof(buf), "%d / %lld MB", state.pool_mining.threads_active, (long long)memMB);
else
snprintf(buf, sizeof(buf), "%d / --", state.pool_mining.threads_active);
col2Str = buf;
}
col2Col = OnSurface();
col2Label = TR("mining_pool_hashrate");
col2Str = FormatHashrate(state.pool_mining.pool_hashrate);
col2Col = state.pool_mining.pool_hashrate > 0 ? OnSurface() : OnSurfaceDisabled();
col3Label = "SHARES";
col3Label = TR("mining_shares");
char sharesBuf[64];
snprintf(sharesBuf, sizeof(sharesBuf), "%lld / %lld",
(long long)state.pool_mining.accepted,
@@ -1225,7 +1288,7 @@ void RenderMiningTab(App* app)
col3Str = sharesBuf;
col3Col = OnSurface();
col4Label = "UPTIME";
col4Label = TR("mining_uptime");
int64_t up = state.pool_mining.uptime_sec;
char uptBuf[64];
if (up <= 0)
@@ -1240,15 +1303,15 @@ void RenderMiningTab(App* app)
} else {
double est_hours = EstimateHoursToBlock(mining.localHashrate, mining.networkHashrate, mining.difficulty);
col1Label = "LOCAL HASHRATE";
col1Label = TR("mining_local_hashrate");
col1Str = FormatHashrate(mining.localHashrate);
col1Col = mining.generate ? greenCol : OnSurfaceDisabled();
col2Label = "NETWORK";
col2Label = TR("mining_network");
col2Str = FormatHashrate(mining.networkHashrate);
col2Col = OnSurface();
col3Label = "EST. BLOCK";
col3Label = TR("mining_est_block");
col3Str = FormatEstTime(est_hours);
col3Col = OnSurface();
}
@@ -1402,9 +1465,9 @@ void RenderMiningTab(App* app)
dl->AddText(capFont, capFont->LegacySize,
ImVec2(plotLeft, chartBot - capFont->LegacySize - 2 * dp),
OnSurfaceDisabled(),
chartHistory.size() >= 300 ? "5m ago" :
chartHistory.size() >= 60 ? "1m ago" : "start");
std::string nowLbl = "now";
chartHistory.size() >= 300 ? TR("mining_chart_5m_ago") :
chartHistory.size() >= 60 ? TR("mining_chart_1m_ago") : TR("mining_chart_start"));
std::string nowLbl = TR("mining_chart_now");
ImVec2 nowSz = capFont->CalcTextSizeA(capFont->LegacySize, 10000, 0, nowLbl.c_str());
dl->AddText(capFont, capFont->LegacySize,
ImVec2(plotRight - nowSz.x, chartBot - capFont->LegacySize - 2 * dp),
@@ -1421,7 +1484,7 @@ void RenderMiningTab(App* app)
if (hasLogContent || hasChartContent) {
ImFont* iconFont = Type().iconSmall();
const char* toggleIcon = showLogFlag ? ICON_MD_SHOW_CHART : ICON_MD_ARTICLE;
const char* toggleTip = showLogFlag ? "Show hashrate chart" : "Show mining log";
const char* toggleTip = showLogFlag ? TR("mining_show_chart") : TR("mining_show_log");
ImVec2 iconSz = iconFont->CalcTextSizeA(iconFont->LegacySize, 1000.0f, 0.0f, toggleIcon);
float btnSize = iconSz.y + 8 * dp;
float btnX = cardMax.x - pad - btnSize;
@@ -1486,6 +1549,10 @@ void RenderMiningTab(App* app)
&& !tx.memo.empty()
&& tx.memo.find("Mining Pool payout") != std::string::npos);
if (isSoloMined || isPoolPayout) {
// Apply earnings filter
if (s_earnings_filter == 1 && !isSoloMined) continue;
if (s_earnings_filter == 2 && !isPoolPayout) continue;
double amt = std::abs(tx.amount);
minedAllTime += amt;
minedAllTimeCount++;
@@ -1526,6 +1593,63 @@ void RenderMiningTab(App* app)
ImVec2 cardMax(cardMin.x + availWidth, cardMin.y + combinedCardH);
DrawGlassPanel(dl, cardMin, cardMax, glassSpec);
// === Earnings filter toggle button (top-right of card) ===
{
const char* filterLabels[] = { TR("mining_filter_all"), TR("mining_solo"), TR("mining_pool") };
const char* filterIcons[] = { ICON_MD_FUNCTIONS, ICON_MD_MEMORY, ICON_MD_CLOUD };
const char* curIcon = filterIcons[s_earnings_filter];
const char* curLabel = filterLabels[s_earnings_filter];
ImFont* icoFont = Type().iconSmall();
float icoH = icoFont->LegacySize;
ImVec2 icoSz = icoFont->CalcTextSizeA(icoFont->LegacySize, FLT_MAX, 0, curIcon);
ImVec2 lblSz = ovFont->CalcTextSizeA(ovFont->LegacySize, FLT_MAX, 0, curLabel);
float padH = Layout::spacingSm();
float btnW = padH + icoSz.x + Layout::spacingXs() + lblSz.x + padH;
float btnH = icoH + 8.0f * dp;
float btnX = cardMax.x - pad - btnW;
float btnY = cardMin.y + (earningsRowH - btnH) * 0.5f;
ImVec2 bMin(btnX, btnY), bMax(btnX + btnW, btnY + btnH);
bool hov = material::IsRectHovered(bMin, bMax);
// Pill background
ImU32 pillBg = s_earnings_filter != 0
? WithAlpha(Primary(), 60)
: WithAlpha(OnSurface(), hov ? 25 : 12);
dl->AddRectFilled(bMin, bMax, pillBg, btnH * 0.5f);
// Icon
ImU32 icoCol = s_earnings_filter != 0 ? Primary() : (hov ? OnSurface() : OnSurfaceDisabled());
float cx = bMin.x + padH;
float cy = bMin.y + (btnH - icoSz.y) * 0.5f;
dl->AddText(icoFont, icoFont->LegacySize, ImVec2(cx, cy), icoCol, curIcon);
// Label
ImU32 lblCol = s_earnings_filter != 0 ? Primary() : (hov ? OnSurface() : OnSurfaceMedium());
float lx = cx + icoSz.x + Layout::spacingXs();
float ly = bMin.y + (btnH - lblSz.y) * 0.5f;
dl->AddText(ovFont, ovFont->LegacySize, ImVec2(lx, ly), lblCol, curLabel);
// Click target
ImVec2 savedCur = ImGui::GetCursorScreenPos();
ImGui::SetCursorScreenPos(bMin);
ImGui::InvisibleButton("##EarningsFilter", ImVec2(btnW, btnH));
if (ImGui::IsItemClicked()) {
s_earnings_filter = (s_earnings_filter + 1) % 3;
}
if (ImGui::IsItemHovered()) {
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
const char* tips[] = {
TR("mining_filter_tip_all"),
TR("mining_filter_tip_solo"),
TR("mining_filter_tip_pool")
};
ImGui::SetTooltip("%s", tips[s_earnings_filter]);
}
ImGui::SetCursorScreenPos(savedCur);
}
// === Earnings section (top of combined card) ===
{
const int numCols = 4;
@@ -1561,10 +1685,10 @@ void RenderMiningTab(App* app)
snprintf(estVal, sizeof(estVal), "N/A");
EarningsEntry entries[] = {
{ "TODAY", todayVal, todaySub, greenCol2 },
{ "YESTERDAY", yesterdayVal, yesterdaySub, OnSurface() },
{ "ALL TIME", allVal, allSub, OnSurface() },
{ "EST. DAILY", estVal, nullptr, estActive ? greenCol2 : OnSurfaceDisabled() },
{ TR("mining_today"), todayVal, todaySub, greenCol2 },
{ TR("mining_yesterday"), yesterdayVal, yesterdaySub, OnSurface() },
{ TR("mining_all_time"), allVal, allSub, OnSurface() },
{ TR("mining_est_daily"), estVal, nullptr, estActive ? greenCol2 : OnSurfaceDisabled() },
};
for (int ei = 0; ei < numCols; ei++) {
@@ -1619,7 +1743,7 @@ void RenderMiningTab(App* app)
float col3X = cx + colW * 2.0f;
// -- Difficulty --
dl->AddText(capFont, capFont->LegacySize, ImVec2(col1X, cy), OnSurfaceMedium(), "Difficulty");
dl->AddText(capFont, capFont->LegacySize, ImVec2(col1X, cy), OnSurfaceMedium(), TR("difficulty"));
if (mining.difficulty > 0) {
snprintf(buf, sizeof(buf), "%.4f", mining.difficulty);
dl->AddText(capFont, capFont->LegacySize, ImVec2(col1X + valOffX, cy), OnSurface(), buf);
@@ -1628,19 +1752,19 @@ void RenderMiningTab(App* app)
ImGui::InvisibleButton("##DiffCopy", ImVec2(diffSz.x + Layout::spacingMd(), capFont->LegacySize + 4 * dp));
if (ImGui::IsItemHovered()) {
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
ImGui::SetTooltip("Click to copy difficulty");
ImGui::SetTooltip("%s", TR("mining_click_copy_difficulty"));
dl->AddLine(ImVec2(col1X + valOffX, cy + capFont->LegacySize + 1 * dp),
ImVec2(col1X + valOffX + diffSz.x, cy + capFont->LegacySize + 1 * dp),
WithAlpha(OnSurface(), 60), 1.0f * dp);
}
if (ImGui::IsItemClicked()) {
ImGui::SetClipboardText(buf);
Notifications::instance().info("Difficulty copied");
Notifications::instance().info(TR("mining_difficulty_copied"));
}
}
// -- Block --
dl->AddText(capFont, capFont->LegacySize, ImVec2(col2X, cy), OnSurfaceMedium(), "Block");
dl->AddText(capFont, capFont->LegacySize, ImVec2(col2X, cy), OnSurfaceMedium(), TR("block"));
if (mining.blocks > 0) {
snprintf(buf, sizeof(buf), "%d", mining.blocks);
dl->AddText(capFont, capFont->LegacySize, ImVec2(col2X + valOffX, cy), OnSurface(), buf);
@@ -1649,19 +1773,19 @@ void RenderMiningTab(App* app)
ImGui::InvisibleButton("##BlockCopy", ImVec2(blkSz.x + Layout::spacingMd(), capFont->LegacySize + 4 * dp));
if (ImGui::IsItemHovered()) {
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
ImGui::SetTooltip("Click to copy block height");
ImGui::SetTooltip("%s", TR("mining_click_copy_block"));
dl->AddLine(ImVec2(col2X + valOffX, cy + capFont->LegacySize + 1 * dp),
ImVec2(col2X + valOffX + blkSz.x, cy + capFont->LegacySize + 1 * dp),
WithAlpha(OnSurface(), 60), 1.0f * dp);
}
if (ImGui::IsItemClicked()) {
ImGui::SetClipboardText(buf);
Notifications::instance().info("Block height copied");
Notifications::instance().info(TR("mining_block_copied"));
}
}
// -- Mining Address --
dl->AddText(capFont, capFont->LegacySize, ImVec2(col3X, cy), OnSurfaceMedium(), "Mining Addr");
dl->AddText(capFont, capFont->LegacySize, ImVec2(col3X, cy), OnSurfaceMedium(), TR("mining_mining_addr"));
std::string mining_address = "";
for (const auto& addr : state.addresses) {
if (addr.type == "transparent" && !addr.address.empty()) {
@@ -1685,14 +1809,14 @@ void RenderMiningTab(App* app)
ImGui::InvisibleButton("##MiningAddrCopy", ImVec2(addrTextSz.x + Layout::spacingMd(), capFont->LegacySize + 4 * dp));
if (ImGui::IsItemHovered()) {
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
ImGui::SetTooltip("Click to copy mining address");
ImGui::SetTooltip("%s", TR("mining_click_copy_address"));
dl->AddLine(ImVec2(col3X + valOffX, cy + capFont->LegacySize + 1 * dp),
ImVec2(col3X + valOffX + addrTextSz.x, cy + capFont->LegacySize + 1 * dp),
WithAlpha(OnSurface(), 60), 1.0f * dp);
}
if (ImGui::IsItemClicked()) {
ImGui::SetClipboardText(mining_address.c_str());
Notifications::instance().info("Mining address copied");
Notifications::instance().info(TR("mining_address_copied"));
}
}
}
@@ -1859,15 +1983,15 @@ void RenderMiningTab(App* app)
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
if (selfRAM >= 1024.0)
ImGui::Text("Wallet: %.1f GB", selfRAM / 1024.0);
ImGui::Text(TR("ram_wallet_gb"), selfRAM / 1024.0);
else
ImGui::Text("Wallet: %.0f MB", selfRAM);
ImGui::Text(TR("ram_wallet_mb"), selfRAM);
if (daemonRAM >= 1024.0)
ImGui::Text("Daemon: %.1f GB (%s)", daemonRAM / 1024.0, app->getDaemonMemDiag().c_str());
ImGui::Text(TR("ram_daemon_gb"), daemonRAM / 1024.0, app->getDaemonMemDiag().c_str());
else
ImGui::Text("Daemon: %.0f MB (%s)", daemonRAM, app->getDaemonMemDiag().c_str());
ImGui::Text(TR("ram_daemon_mb"), daemonRAM, app->getDaemonMemDiag().c_str());
ImGui::Separator();
ImGui::Text("System: %.1f / %.0f GB", usedRAM / 1024.0, totalRAM / 1024.0);
ImGui::Text(TR("ram_system_gb"), usedRAM / 1024.0, totalRAM / 1024.0);
ImGui::EndTooltip();
}
}
@@ -1881,7 +2005,7 @@ void RenderMiningTab(App* app)
// ============================================================
if (!recentMined.empty() || s_pool_mode) {
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(),
s_pool_mode ? "RECENT POOL PAYOUTS" : "RECENT BLOCKS");
s_pool_mode ? TR("mining_recent_payouts") : TR("mining_recent_blocks"));
ImGui::Dummy(ImVec2(0, Layout::spacingXs()));
float rowH_blocks = std::max(schema::UI().drawElement("tabs.mining", "recent-row-min-height").size, schema::UI().drawElement("tabs.mining", "recent-row-height").size * vs);
@@ -1924,8 +2048,8 @@ void RenderMiningTab(App* app)
ImVec2(centerX - iSz.x * 0.5f, emptyY),
OnSurfaceDisabled(), emptyIcon);
const char* emptyMsg = s_pool_mode
? "No pool payouts yet"
: "No blocks found yet";
? TR("mining_no_payouts_yet")
: TR("mining_no_blocks_yet");
ImVec2 msgSz = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0, emptyMsg);
miningChildDL->AddText(capFont, capFont->LegacySize,
ImVec2(centerX - msgSz.x * 0.5f, emptyY + iSz.y + Layout::spacingXs()),
@@ -1966,13 +2090,13 @@ void RenderMiningTab(App* app)
// Time
int64_t diff = now - mtx.timestamp;
if (diff < 60)
snprintf(buf, sizeof(buf), "%llds ago", (long long)diff);
snprintf(buf, sizeof(buf), TR("time_seconds_ago"), (long long)diff);
else if (diff < 3600)
snprintf(buf, sizeof(buf), "%lldm ago", (long long)(diff / 60));
snprintf(buf, sizeof(buf), TR("time_minutes_ago"), (long long)(diff / 60));
else if (diff < 86400)
snprintf(buf, sizeof(buf), "%lldh ago", (long long)(diff / 3600));
snprintf(buf, sizeof(buf), TR("time_hours_ago"), (long long)(diff / 3600));
else
snprintf(buf, sizeof(buf), "%lldd ago", (long long)(diff / 86400));
snprintf(buf, sizeof(buf), TR("time_days_ago"), (long long)(diff / 86400));
dl->AddText(capFont, capFont->LegacySize, ImVec2(rx + iSz.x + 8 * dp, ry), OnSurfaceDisabled(), buf);
// Amount
@@ -1984,9 +2108,9 @@ void RenderMiningTab(App* app)
float badgeX = rMax.x - pad - Layout::spacingXl() * 3.5f;
if (mtx.mature) {
dl->AddText(capFont, capFont->LegacySize, ImVec2(badgeX, ry),
WithAlpha(Success(), 180), "Mature");
WithAlpha(Success(), 180), TR("mature"));
} else {
snprintf(buf, sizeof(buf), "%d conf", mtx.confirmations);
snprintf(buf, sizeof(buf), TR("conf_count"), mtx.confirmations);
dl->AddText(capFont, capFont->LegacySize, ImVec2(badgeX, ry),
WithAlpha(Warning(), 200), buf);
}
@@ -2001,7 +2125,7 @@ void RenderMiningTab(App* app)
dragonx::util::Platform::openUrl(url);
}
if (ImGui::IsItemHovered() && !mtx.txid.empty()) {
ImGui::SetTooltip("Open in explorer");
ImGui::SetTooltip("%s", TR("mining_open_in_explorer"));
}
}
@@ -2026,8 +2150,8 @@ void RenderMiningTab(App* app)
const char* dotIcon = ICON_MD_CIRCLE;
ImU32 dotCol = state.pool_mining.connected ? WithAlpha(Success(), 200) : WithAlpha(Error(), 200);
const char* statusText = state.pool_mining.connected
? (state.pool_mining.pool_url.empty() ? "Connected" : state.pool_mining.pool_url.c_str())
: "Connecting...";
? (state.pool_mining.pool_url.empty() ? TR("mining_connected") : state.pool_mining.pool_url.c_str())
: TR("mining_connecting");
ImVec2 pos = ImGui::GetCursorScreenPos();
ImVec2 dotSz = iconFont->CalcTextSizeA(iconFont->LegacySize, 1000.0f, 0.0f, dotIcon);
+60 -57
View File
@@ -5,6 +5,7 @@
#include "peers_tab.h"
#include "../../app.h"
#include "../../data/wallet_state.h"
#include "../../util/i18n.h"
#include "../theme.h"
#include "../effects/imgui_acrylic.h"
#include "../effects/low_spec.h"
@@ -148,7 +149,7 @@ void RenderPeersTab(App* app)
DrawGlassPanel(dl, cardMin, cardMax, glassSpec);
// Card header
dl->AddText(ovFont, ovFont->LegacySize, ImVec2(cardMin.x + pad, cardMin.y + pad * 0.5f), Primary(), "BLOCKCHAIN");
dl->AddText(ovFont, ovFont->LegacySize, ImVec2(cardMin.x + pad, cardMin.y + pad * 0.5f), Primary(), TR("peers_blockchain"));
float colW = (cardW - pad * 2) / 2.0f;
float ry = cardMin.y + pad * 0.5f + headerH;
@@ -165,10 +166,11 @@ void RenderPeersTab(App* app)
{
// Blocks
float cx = cardMin.x + pad;
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Blocks");
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_blocks"));
int blocks = state.sync.blocks;
if (blocks > 0) {
int blocksLeft = state.sync.headers - blocks;
int chainTip = state.longestchain > 0 ? state.longestchain : state.sync.headers;
int blocksLeft = chainTip - blocks;
if (blocksLeft < 0) blocksLeft = 0;
if (blocksLeft > 0) {
snprintf(buf, sizeof(buf), "%d (%d left)", blocks, blocksLeft);
@@ -180,7 +182,7 @@ void RenderPeersTab(App* app)
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, valY), OnSurface(), blockStr);
// Draw "(X left)" in warning color
char leftStr[32];
snprintf(leftStr, sizeof(leftStr), "(%d left)", blocksLeft);
snprintf(leftStr, sizeof(leftStr), TR("peers_blocks_left"), blocksLeft);
dl->AddText(capFont, capFont->LegacySize,
ImVec2(cx + numSz.x, valY + (sub1->LegacySize - capFont->LegacySize) * 0.5f),
Warning(), leftStr);
@@ -194,7 +196,7 @@ void RenderPeersTab(App* app)
// Longest Chain
cx = cardMin.x + pad + colW;
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Longest Chain");
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_longest_chain"));
if (state.longestchain > 0) {
snprintf(buf, sizeof(buf), "%d", state.longestchain);
int localHeight = mining.blocks > 0 ? mining.blocks : state.sync.blocks;
@@ -213,7 +215,7 @@ void RenderPeersTab(App* app)
{
// Hashrate
float cx = cardMin.x + pad;
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Hashrate");
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_hashrate"));
float valY = ry + capFont->LegacySize + Layout::spacingXs();
if (mining.networkHashrate > 0) {
if (mining.networkHashrate >= 1e12)
@@ -233,7 +235,7 @@ void RenderPeersTab(App* app)
// Difficulty
cx = cardMin.x + pad + colW;
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Difficulty");
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("difficulty"));
valY = ry + capFont->LegacySize + Layout::spacingXs();
if (mining.difficulty > 0) {
snprintf(buf, sizeof(buf), "%.4f", mining.difficulty);
@@ -251,7 +253,7 @@ void RenderPeersTab(App* app)
{
// Notarized
float cx = cardMin.x + pad;
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Notarized");
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_notarized"));
float valY = ry + capFont->LegacySize + Layout::spacingXs();
if (state.notarized > 0) {
snprintf(buf, sizeof(buf), "%d", state.notarized);
@@ -262,7 +264,7 @@ void RenderPeersTab(App* app)
// Protocol
cx = cardMin.x + pad + colW;
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Protocol");
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_protocol"));
valY = ry + capFont->LegacySize + Layout::spacingXs();
if (state.protocol_version > 0) {
snprintf(buf, sizeof(buf), "%d", state.protocol_version);
@@ -280,7 +282,7 @@ void RenderPeersTab(App* app)
{
// Version
float cx = cardMin.x + pad;
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Version");
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_version"));
float valY = ry + capFont->LegacySize + Layout::spacingXs();
if (state.daemon_version > 0) {
int major = state.daemon_version / 1000000;
@@ -294,7 +296,7 @@ void RenderPeersTab(App* app)
// Memory
cx = cardMin.x + pad + colW;
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Memory");
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_memory"));
valY = ry + capFont->LegacySize + Layout::spacingXs();
double memMb = state.mining.daemon_memory_mb;
if (memMb > 0) {
@@ -316,7 +318,7 @@ void RenderPeersTab(App* app)
{
// Longest Chain
float cx = cardMin.x + pad;
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Longest");
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_longest"));
float valY = ry + capFont->LegacySize + Layout::spacingXs();
if (state.longestchain > 0) {
snprintf(buf, sizeof(buf), "%d", state.longestchain);
@@ -330,7 +332,7 @@ void RenderPeersTab(App* app)
// Best Block (truncated hash)
cx = cardMin.x + pad + colW;
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Best Block");
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_best_block"));
valY = ry + capFont->LegacySize + Layout::spacingXs();
if (!state.sync.best_blockhash.empty()) {
// Truncate hash to fit: first 6 + "..." + last 6
@@ -349,14 +351,14 @@ void RenderPeersTab(App* app)
ImGui::InvisibleButton("##BestBlockCopy", ImVec2(hashSz.x + Layout::spacingSm(), sub1->LegacySize + 2 * dp));
if (ImGui::IsItemHovered()) {
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
ImGui::SetTooltip("Click to copy: %s", hash.c_str());
ImGui::SetTooltip("%s %s", TR("peers_click_copy"), hash.c_str());
dl->AddLine(ImVec2(cx, valY + sub1->LegacySize + 1 * dp),
ImVec2(cx + hashSz.x, valY + sub1->LegacySize + 1 * dp),
WithAlpha(OnSurface(), 60), 1.0f * dp);
}
if (ImGui::IsItemClicked()) {
ImGui::SetClipboardText(hash.c_str());
ui::Notifications::instance().info("Block hash copied");
ui::Notifications::instance().info(TR("peers_hash_copied"));
}
} else {
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, valY), OnSurfaceDisabled(), "\xE2\x80\x94");
@@ -373,7 +375,7 @@ void RenderPeersTab(App* app)
DrawGlassPanel(dl, cardMin, cardMax, glassSpec);
// Card header
dl->AddText(ovFont, ovFont->LegacySize, ImVec2(cardMin.x + pad, cardMin.y + pad * 0.5f), Primary(), "PEERS");
dl->AddText(ovFont, ovFont->LegacySize, ImVec2(cardMin.x + pad, cardMin.y + pad * 0.5f), Primary(), TR("peers_upper"));
float colW = (cardW - pad * 2) / 2.0f;
float ry = cardMin.y + pad * 0.5f + headerH;
@@ -390,13 +392,13 @@ void RenderPeersTab(App* app)
{
// Connected
float cx = cardMin.x + pad;
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Connected");
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_connected"));
snprintf(buf, sizeof(buf), "%d", totalPeers);
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, ry + capFont->LegacySize + Layout::spacingXs()), OnSurface(), buf);
// In / Out
cx = cardMin.x + pad + colW;
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "In / Out");
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_in_out"));
snprintf(buf, sizeof(buf), "%d / %d", inboundCount, outboundCount);
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, ry + capFont->LegacySize + Layout::spacingXs()), OnSurface(), buf);
}
@@ -426,7 +428,7 @@ void RenderPeersTab(App* app)
// Avg Ping
cx = cardMin.x + pad + colW;
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Avg Ping");
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_avg_ping"));
ImU32 pingCol;
if (avgPing < 100) pingCol = Success();
else if (avgPing < 500) pingCol = Warning();
@@ -443,13 +445,13 @@ void RenderPeersTab(App* app)
{
// Received
float cx = cardMin.x + pad;
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Received");
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_received"));
std::string recvStr = fmtBytes(totalBytesRecv);
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, ry + capFont->LegacySize + Layout::spacingXs()), OnSurface(), recvStr.c_str());
// Sent
cx = cardMin.x + pad + colW;
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Sent");
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_sent"));
std::string sentStr = fmtBytes(totalBytesSent);
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, ry + capFont->LegacySize + Layout::spacingXs()), OnSurface(), sentStr.c_str());
}
@@ -462,7 +464,7 @@ void RenderPeersTab(App* app)
{
// P2P Port
float cx = cardMin.x + pad;
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "P2P Port");
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_p2p_port"));
float valY = ry + capFont->LegacySize + Layout::spacingXs();
if (state.p2p_port > 0) {
snprintf(buf, sizeof(buf), "%d", state.p2p_port);
@@ -472,7 +474,7 @@ void RenderPeersTab(App* app)
}
// Banned count
cx = cardMin.x + pad + colW;
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Banned");
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_banned"));
valY = ry + capFont->LegacySize + Layout::spacingXs();
size_t bannedCount = state.bannedPeers.size();
snprintf(buf, sizeof(buf), "%zu", bannedCount);
@@ -488,7 +490,7 @@ void RenderPeersTab(App* app)
// Compute remaining space for peer list + footer
// ================================================================
float footerH = ImGui::GetFrameHeight() + Layout::spacingSm();
float toggleH = body2->LegacySize + Layout::spacingMd() * 2;
float toggleH = body2->LegacySize + Layout::spacingMd() * 2 + Layout::spacingSm();
float remainForPeers = std::max(60.0f, peersAvail.y - (ImGui::GetCursorScreenPos().y - ImGui::GetWindowPos().y) - footerH - Layout::spacingSm());
float peerPanelHeight = remainForPeers - toggleH;
peerPanelHeight = std::max(S.drawElement("tabs.peers", "peer-panel-min-height").size, peerPanelHeight);
@@ -502,8 +504,8 @@ void RenderPeersTab(App* app)
float toggleY = ImGui::GetCursorScreenPos().y;
{
char connLabel[64], banLabel[64];
snprintf(connLabel, sizeof(connLabel), "Connected (%zu)", state.peers.size());
snprintf(banLabel, sizeof(banLabel), "Banned (%zu)", state.bannedPeers.size());
snprintf(connLabel, sizeof(connLabel), TR("peers_connected_count"), state.peers.size());
snprintf(banLabel, sizeof(banLabel), TR("peers_banned_count"), state.bannedPeers.size());
ImVec2 connSz = body2->CalcTextSizeA(body2->LegacySize, FLT_MAX, 0, connLabel);
ImVec2 banSz = body2->CalcTextSizeA(body2->LegacySize, FLT_MAX, 0, banLabel);
@@ -544,9 +546,14 @@ void RenderPeersTab(App* app)
// Refresh button — top-right, glass panel style (similar to mining button)
{
bool isRefreshing = app->isPeerRefreshInProgress();
auto refreshBtn = S.drawElement("tabs.peers", "refresh-button");
float btnW = refreshBtn.size;
float btnH = toggleH - 4.0f * Layout::dpiScale();
ImFont* iconFont = Type().iconMed();
float iconSz = iconFont->LegacySize;
const char* label = isRefreshing ? TR("peers_refreshing") : TR("peers_refresh");
ImVec2 lblSz = ovFont->CalcTextSizeA(ovFont->LegacySize, FLT_MAX, 0, label);
float padH = Layout::spacingSm();
float padV = Layout::spacingSm();
float btnW = padH + iconSz + Layout::spacingXs() + lblSz.x + padH;
float btnH = std::max(iconSz, lblSz.y) + padV * 2;
float btnX = ImGui::GetWindowPos().x + availWidth - btnW - Layout::spacingSm();
float btnY = toggleY + (toggleH - btnH) * 0.5f;
ImVec2 bMin(btnX, btnY);
@@ -574,10 +581,8 @@ void RenderPeersTab(App* app)
}
// Icon: spinner while refreshing, refresh icon otherwise
float cx = bMin.x + btnW * 0.35f;
float cx = bMin.x + padH + iconSz * 0.5f;
float cy = bMin.y + btnH * 0.5f;
ImFont* iconFont = Type().iconMed();
float iconSz = iconFont->LegacySize;
if (isRefreshing) {
// Spinning arc spinner (same style as mining toggle)
@@ -617,7 +622,6 @@ void RenderPeersTab(App* app)
// Label to the right of icon
{
const char* label = isRefreshing ? "REFRESHING" : "REFRESH";
ImU32 lblCol;
if (isRefreshing) {
float pulse = effects::isLowSpecMode()
@@ -627,7 +631,6 @@ void RenderPeersTab(App* app)
} else {
lblCol = btnHovered ? OnSurface() : WithAlpha(OnSurface(), 160);
}
ImVec2 lblSz = ovFont->CalcTextSizeA(ovFont->LegacySize, FLT_MAX, 0, label);
float lblX = cx + iconSz * 0.5f + Layout::spacingXs();
float lblY = cy - lblSz.y * 0.5f;
dl->AddText(ovFont, ovFont->LegacySize, ImVec2(lblX, lblY), lblCol, label);
@@ -645,7 +648,7 @@ void RenderPeersTab(App* app)
if (ImGui::IsItemHovered()) {
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
if (!isRefreshing)
ImGui::SetTooltip("Refresh peers & blockchain");
ImGui::SetTooltip("%s", TR("peers_refresh_tooltip"));
}
ImGui::PopID();
}
@@ -673,10 +676,10 @@ void RenderPeersTab(App* app)
// ---- Connected Peers ----
if (!app->isConnected()) {
ImGui::Dummy(ImVec2(0, 20));
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), " Not connected to daemon...");
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), TR("not_connected"));
} else if (state.peers.empty()) {
ImGui::Dummy(ImVec2(0, 20));
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), " No connected peers");
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), TR("peers_no_connected"));
} else {
float rowH = body2->LegacySize + capFont->LegacySize + Layout::spacingLg();
float rowInset = Layout::spacingLg();
@@ -727,7 +730,7 @@ void RenderPeersTab(App* app)
}
{
const char* dirLabel = peer.inbound ? "In" : "Out";
const char* dirLabel = peer.inbound ? TR("peers_dir_in") : TR("peers_dir_out");
ImU32 dirBg = peer.inbound ? WithAlpha(Success(), 30) : WithAlpha(Secondary(), 30);
ImU32 dirFg = peer.inbound ? WithAlpha(Success(), 200) : WithAlpha(Secondary(), 200);
ImVec2 dirSz = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0, dirLabel);
@@ -761,12 +764,12 @@ void RenderPeersTab(App* app)
dl->AddText(capFont, capFont->LegacySize, ImVec2(tlsMin.x + 4, cy2 + 1), tlsFg, "TLS");
} else {
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx + S.drawElement("tabs.peers", "address-x-offset").size + verW + Layout::spacingSm(), cy2),
WithAlpha(Error(), 140), "No TLS");
WithAlpha(Error(), 140), TR("peers_no_tls"));
}
if (peer.banscore > 0) {
char banBuf[16];
snprintf(banBuf, sizeof(banBuf), "Ban: %d", peer.banscore);
snprintf(banBuf, sizeof(banBuf), TR("peers_ban_score"), peer.banscore);
ImU32 banCol = peer.banscore > 50 ? Error() : Warning();
ImVec2 banSz = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0, banBuf);
dl->AddText(capFont, capFont->LegacySize,
@@ -780,16 +783,16 @@ void RenderPeersTab(App* app)
const auto& acrylicTheme = GetCurrentAcrylicTheme();
if (effects::ImGuiAcrylic::BeginAcrylicContextItem(nullptr, 0, acrylicTheme.menu)) {
ImGui::Text("Peer: %s", peer.addr.c_str());
ImGui::Text(TR("peers_peer_label"), peer.addr.c_str());
ImGui::Separator();
if (ImGui::MenuItem("Copy Address")) {
if (ImGui::MenuItem(TR("copy_address"))) {
ImGui::SetClipboardText(peer.addr.c_str());
}
if (ImGui::MenuItem("Copy IP")) {
if (ImGui::MenuItem(TR("peers_copy_ip"))) {
ImGui::SetClipboardText(ExtractIP(peer.addr).c_str());
}
ImGui::Separator();
if (ImGui::MenuItem("Ban Peer (24h)")) {
if (ImGui::MenuItem(TR("peers_ban_24h"))) {
app->banPeer(ExtractIP(peer.addr), 86400);
}
effects::ImGuiAcrylic::EndAcrylicPopup();
@@ -808,18 +811,18 @@ void RenderPeersTab(App* app)
};
char ttBuf[128];
snprintf(ttBuf, sizeof(ttBuf), "%d", peer.id);
TTRow("ID", ttBuf);
TTRow("Services", peer.services.c_str());
TTRow(TR("peers_tt_id"), ttBuf);
TTRow(TR("peers_tt_services"), peer.services.c_str());
snprintf(ttBuf, sizeof(ttBuf), "%d", peer.startingheight);
TTRow("Start Height", ttBuf);
TTRow(TR("peers_tt_start_height"), ttBuf);
snprintf(ttBuf, sizeof(ttBuf), "%ld bytes", peer.bytessent);
TTRow("Sent", ttBuf);
TTRow(TR("peers_tt_sent"), ttBuf);
snprintf(ttBuf, sizeof(ttBuf), "%ld bytes", peer.bytesrecv);
TTRow("Received", ttBuf);
TTRow(TR("peers_tt_received"), ttBuf);
snprintf(ttBuf, sizeof(ttBuf), "%d / %d", peer.synced_headers, peer.synced_blocks);
TTRow("Synced H/B", ttBuf);
TTRow(TR("peers_tt_synced"), ttBuf);
if (!peer.tls_cipher.empty())
TTRow("TLS Cipher", peer.tls_cipher.c_str());
TTRow(TR("peers_tt_tls_cipher"), peer.tls_cipher.c_str());
ImGui::EndTable();
}
ImGui::PopStyleVar();
@@ -840,10 +843,10 @@ void RenderPeersTab(App* app)
// ---- Banned Peers ----
if (!app->isConnected()) {
ImGui::Dummy(ImVec2(0, 20));
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), " Not connected to daemon...");
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), TR("not_connected"));
} else if (state.bannedPeers.empty()) {
ImGui::Dummy(ImVec2(0, 20));
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), " No banned peers");
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), TR("peers_no_banned"));
} else {
float rowH = capFont->LegacySize + S.drawElement("tabs.peers", "banned-row-height-padding").size;
float rowInsetB = pad;
@@ -886,7 +889,7 @@ void RenderPeersTab(App* app)
float btnX = rowPos.x + innerW - Layout::spacingXl() * S.drawElement("tabs.peers", "unban-btn-right-offset-multiplier").size;
ImGui::SetCursorScreenPos(ImVec2(btnX, cy - 1));
if (TactileSmallButton("Unban", S.resolveFont("button"))) {
if (TactileSmallButton(TR("peers_unban"), S.resolveFont("button"))) {
app->unbanPeer(banned.address);
}
@@ -898,10 +901,10 @@ void RenderPeersTab(App* app)
const auto& acrylicTheme2 = GetCurrentAcrylicTheme();
if (effects::ImGuiAcrylic::BeginAcrylicContextItem(nullptr, 0, acrylicTheme2.menu)) {
if (ImGui::MenuItem("Copy Address")) {
if (ImGui::MenuItem(TR("copy_address"))) {
ImGui::SetClipboardText(banned.address.c_str());
}
if (ImGui::MenuItem("Unban")) {
if (ImGui::MenuItem(TR("peers_unban"))) {
app->unbanPeer(banned.address);
}
effects::ImGuiAcrylic::EndAcrylicPopup();
@@ -940,7 +943,7 @@ void RenderPeersTab(App* app)
// ================================================================
if (s_show_banned && !state.bannedPeers.empty()) {
ImGui::BeginDisabled(!app->isConnected());
if (TactileSmallButton("Clear All Bans", S.resolveFont("button"))) {
if (TactileSmallButton(TR("peers_clear_all_bans"), S.resolveFont("button"))) {
app->clearBans();
}
ImGui::EndDisabled();
+6 -5
View File
@@ -4,6 +4,7 @@
#include "qr_popup_dialog.h"
#include "../../app.h"
#include "../../util/i18n.h"
#include "../widgets/qr_code.h"
#include "../schema/ui_schema.h"
#include "../material/draw_helpers.h"
@@ -63,7 +64,7 @@ void QRPopupDialog::render(App* app)
auto addrInput = S.input("dialogs.qr-popup", "address-input");
auto actionBtn = S.button("dialogs.qr-popup", "action-button");
if (material::BeginOverlayDialog("QR Code", &s_open, win.width, 0.94f)) {
if (material::BeginOverlayDialog(TR("qr_title"), &s_open, win.width, 0.94f)) {
// Label if present
if (!s_label.empty()) {
@@ -86,7 +87,7 @@ void QRPopupDialog::render(App* app)
} else {
// Fallback: show error
ImGui::BeginChild("QRPlaceholder", ImVec2(qr_size, qr_size), true);
ImGui::TextWrapped("Failed to generate QR code");
ImGui::TextWrapped("%s", TR("qr_failed"));
ImGui::EndChild();
}
@@ -95,7 +96,7 @@ void QRPopupDialog::render(App* app)
ImGui::Spacing();
// Address display
ImGui::Text("Address:");
ImGui::Text("%s", TR("address_label"));
// Use multiline for z-addresses
if (s_address.length() > 50) {
@@ -120,13 +121,13 @@ void QRPopupDialog::render(App* app)
float start_x = (window_width - total_width) / 2.0f;
ImGui::SetCursorPosX(start_x);
if (material::StyledButton("Copy Address", ImVec2(button_width, 0), S.resolveFont(actionBtn.font))) {
if (material::StyledButton(TR("copy_address"), ImVec2(button_width, 0), S.resolveFont(actionBtn.font))) {
ImGui::SetClipboardText(s_address.c_str());
}
ImGui::SameLine();
if (material::StyledButton("Close", ImVec2(button_width, 0), S.resolveFont(actionBtn.font))) {
if (material::StyledButton(TR("close"), ImVec2(button_width, 0), S.resolveFont(actionBtn.font))) {
close();
}
material::EndOverlayDialog();
+52 -44
View File
@@ -11,6 +11,7 @@
#include "receive_tab.h"
#include "send_tab.h"
#include "../../app.h"
#include "../../util/i18n.h"
#include "../../config/version.h"
#include "../../data/wallet_state.h"
#include "../../ui/widgets/qr_code.h"
@@ -35,6 +36,10 @@ namespace ui {
using namespace material;
static std::string TrId(const char* key, const char* id) {
return std::string(TR(key)) + "##" + id;
}
// ============================================================================
// State
// ============================================================================
@@ -110,7 +115,7 @@ static void RenderSyncBanner(const WalletState& state) {
? (float)state.sync.blocks / state.sync.headers * 100.0f : 0.0f;
char syncBuf[128];
snprintf(syncBuf, sizeof(syncBuf),
"Blockchain syncing (%.1f%%)... Balances may be inaccurate.", syncPct);
TR("blockchain_syncing"), syncPct);
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::ColorConvertU32ToFloat4(schema::UI().resolveColor(schema::UI().drawElement("tabs.receive", "sync-banner-bg-color").color)));
float syncH = std::max(schema::UI().drawElement("tabs.receive", "sync-banner-min-height").size, schema::UI().drawElement("tabs.receive", "sync-banner-height").size * Layout::vScale());
ImGui::BeginChild("##SyncBannerRecv", ImVec2(ImGui::GetContentRegionAvail().x, syncH),
@@ -129,13 +134,13 @@ static void RenderAddressDropdown(App* app, float width) {
char buf[256];
// Header row: label + address type toggle buttons
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "ADDRESS");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("address_upper"));
float toggleBtnW = std::max(schema::UI().drawElement("tabs.receive", "toggle-btn-min-width").size, schema::UI().drawElement("tabs.receive", "toggle-btn-width").size * Layout::hScale(width));
float toggleGap = schema::UI().drawElement("tabs.receive", "toggle-gap").size;
float toggleTotalW = toggleBtnW * 3 + toggleGap * 2;
ImGui::SameLine(width - toggleTotalW);
const char* filterLabels[] = { "All", "Z", "T" };
const char* filterLabels[] = { TR("all_filter"), "Z", "T" };
for (int i = 0; i < 3; i++) {
bool isActive = (s_addr_type_filter == i);
if (isActive) {
@@ -190,7 +195,7 @@ static void RenderAddressDropdown(App* app, float width) {
// Build preview string
if (!app->isConnected()) {
s_source_preview = "Not connected to daemon";
s_source_preview = TR("not_connected");
} else if (s_selected_address_idx >= 0 &&
s_selected_address_idx < (int)state.addresses.size()) {
const auto& addr = state.addresses[s_selected_address_idx];
@@ -202,7 +207,7 @@ static void RenderAddressDropdown(App* app, float width) {
tag, trunc.c_str(), addr.balance, DRAGONX_TICKER);
s_source_preview = buf;
} else {
s_source_preview = "Select a receiving address...";
s_source_preview = TR("select_receiving_address");
}
float copyBtnW = std::max(schema::UI().drawElement("tabs.receive", "copy-btn-min-width").size, schema::UI().drawElement("tabs.receive", "copy-btn-width").size * Layout::hScale(width));
@@ -212,7 +217,7 @@ static void RenderAddressDropdown(App* app, float width) {
ImGui::PushFont(Type().getFont(TypeStyle::Body2));
if (ImGui::BeginCombo("##RecvAddr", s_source_preview.c_str())) {
if (!app->isConnected() || state.addresses.empty()) {
ImGui::TextDisabled("No addresses available");
ImGui::TextDisabled("%s", TR("no_addresses_available"));
} else {
// Build filtered and sorted list
std::vector<size_t> sortedIdx;
@@ -229,7 +234,7 @@ static void RenderAddressDropdown(App* app, float width) {
});
if (sortedIdx.empty()) {
ImGui::TextDisabled("No addresses match filter");
ImGui::TextDisabled("%s", TR("no_addresses_match"));
} else {
size_t addrTruncLen = static_cast<size_t>(std::max(schema::UI().drawElement("tabs.receive", "addr-dropdown-trunc-min").size, width / schema::UI().drawElement("tabs.receive", "addr-dropdown-trunc-divisor").size));
double now = ImGui::GetTime();
@@ -287,10 +292,10 @@ static void RenderAddressDropdown(App* app, float width) {
ImGui::SameLine(0, Layout::spacingSm());
ImGui::BeginDisabled(!app->isConnected() || s_selected_address_idx < 0 ||
s_selected_address_idx >= (int)state.addresses.size());
if (TactileButton("Copy##recvAddr", ImVec2(copyBtnW, 0), schema::UI().resolveFont("button"))) {
if (TactileButton(TrId("copy", "recvAddr").c_str(), ImVec2(copyBtnW, 0), schema::UI().resolveFont("button"))) {
if (s_selected_address_idx >= 0 && s_selected_address_idx < (int)state.addresses.size()) {
ImGui::SetClipboardText(state.addresses[s_selected_address_idx].address.c_str());
Notifications::instance().info("Address copied to clipboard");
Notifications::instance().info(TR("address_copied"));
}
}
ImGui::EndDisabled();
@@ -298,23 +303,23 @@ static void RenderAddressDropdown(App* app, float width) {
// New address button on same line
ImGui::SameLine(0, Layout::spacingSm());
ImGui::BeginDisabled(!app->isConnected());
if (TactileButton("+ New##recv", ImVec2(newBtnW, 0), schema::UI().resolveFont("button"))) {
if (TactileButton(TrId("new", "recv").c_str(), ImVec2(newBtnW, 0), schema::UI().resolveFont("button"))) {
if (s_addr_type_filter != 2) {
app->createNewZAddress([](const std::string& addr) {
if (addr.empty())
Notifications::instance().error("Failed to create new shielded address");
Notifications::instance().error(TR("failed_create_shielded"));
else {
s_pending_select_address = addr;
Notifications::instance().success("New shielded address created");
Notifications::instance().success(TR("new_shielded_created"));
}
});
} else {
app->createNewTAddress([](const std::string& addr) {
if (addr.empty())
Notifications::instance().error("Failed to create new transparent address");
Notifications::instance().error(TR("failed_create_transparent"));
else {
s_pending_select_address = addr;
Notifications::instance().success("New transparent address created");
Notifications::instance().success(TR("new_transparent_created"));
}
});
}
@@ -330,10 +335,11 @@ static std::string recvTimeAgo(int64_t timestamp) {
int64_t now = (int64_t)std::time(nullptr);
int64_t diff = now - timestamp;
if (diff < 0) diff = 0;
if (diff < 60) return std::to_string(diff) + "s ago";
if (diff < 3600) return std::to_string(diff / 60) + "m ago";
if (diff < 86400) return std::to_string(diff / 3600) + "h ago";
return std::to_string(diff / 86400) + "d ago";
char buf[32];
if (diff < 60) { snprintf(buf, sizeof(buf), TR("time_seconds_ago"), (long long)diff); return buf; }
if (diff < 3600) { snprintf(buf, sizeof(buf), TR("time_minutes_ago"), (long long)(diff / 60)); return buf; }
if (diff < 86400) { snprintf(buf, sizeof(buf), TR("time_hours_ago"), (long long)(diff / 3600)); return buf; }
snprintf(buf, sizeof(buf), TR("time_days_ago"), (long long)(diff / 86400)); return buf;
}
static void DrawRecvIcon(ImDrawList* dl, float cx, float cy, float s, ImU32 col) {
@@ -353,7 +359,7 @@ static void RenderRecentReceived(ImDrawList* dl, const AddressInfo& /* addr */,
const WalletState& state, float width,
ImFont* capFont, App* app) {
ImGui::Dummy(ImVec2(0, Layout::spacingLg()));
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "RECENT RECEIVED");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("recent_received"));
ImGui::Dummy(ImVec2(0, Layout::spacingXs()));
float hs = Layout::hScale(width);
@@ -375,7 +381,7 @@ static void RenderRecentReceived(ImDrawList* dl, const AddressInfo& /* addr */,
}
if (recvs.empty()) {
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), "No recent receives");
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), TR("no_recent_receives"));
return;
}
@@ -416,11 +422,11 @@ static void RenderRecentReceived(ImDrawList* dl, const AddressInfo& /* addr */,
// Type label (first line)
float labelX = cx + iconSz * 2.0f + Layout::spacingSm();
dl->AddText(capFont, capFont->LegacySize, ImVec2(labelX, cy), recvCol, "Received");
dl->AddText(capFont, capFont->LegacySize, ImVec2(labelX, cy), recvCol, TR("received_label"));
// Time (next to type)
std::string ago = recvTimeAgo(tx.timestamp);
float typeW = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0, "Received").x;
float typeW = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0, TR("received_label")).x;
dl->AddText(capFont, capFont->LegacySize, ImVec2(labelX + typeW + Layout::spacingLg(), cy),
OnSurfaceDisabled(), ago.c_str());
@@ -457,12 +463,12 @@ static void RenderRecentReceived(ImDrawList* dl, const AddressInfo& /* addr */,
const char* statusStr;
ImU32 statusCol;
if (tx.confirmations == 0) {
statusStr = "Pending"; statusCol = Warning();
statusStr = TR("pending"); statusCol = Warning();
} else if (tx.confirmations < (int)schema::UI().drawElement("tabs.receive", "confirmed-threshold").size) {
snprintf(buf, sizeof(buf), "%d conf", tx.confirmations);
snprintf(buf, sizeof(buf), TR("conf_count"), tx.confirmations);
statusStr = buf; statusCol = Warning();
} else {
statusStr = "Confirmed"; statusCol = greenCol;
statusStr = TR("confirmed"); statusCol = greenCol;
}
ImVec2 sSz = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0, statusStr);
float statusX = amtX - sSz.x - Layout::spacingXxl();
@@ -545,10 +551,10 @@ void RenderReceiveTab(App* app)
DrawGlassPanel(dl, emptyMin, emptyMax, glassSpec);
dl->AddText(sub1, sub1->LegacySize,
ImVec2(emptyMin.x + Layout::spacingXl(), emptyMin.y + Layout::spacingXl()),
OnSurfaceDisabled(), "Waiting for daemon connection...");
OnSurfaceDisabled(), TR("waiting_for_daemon"));
dl->AddText(capFont, capFont->LegacySize,
ImVec2(emptyMin.x + Layout::spacingXl(), emptyMin.y + Layout::spacingXl() + sub1->LegacySize + S.drawElement("tabs.receive", "empty-state-subtitle-gap").size),
OnSurfaceDisabled(), "Your receiving addresses will appear here once connected.");
OnSurfaceDisabled(), TR("addresses_appear_here"));
ImGui::Dummy(ImVec2(formW, emptyH));
ImGui::EndGroup();
ImGui::EndChild();
@@ -572,7 +578,7 @@ void RenderReceiveTab(App* app)
skelCol, schema::UI().drawElement("tabs.receive", "skeleton-rounding").size);
dl->AddText(capFont, capFont->LegacySize,
ImVec2(emptyMin.x + Layout::spacingLg(), emptyMin.y + emptyH - S.drawElement("tabs.receive", "skeleton-text-bottom-offset").size),
OnSurfaceDisabled(), "Loading addresses...");
OnSurfaceDisabled(), TR("loading_addresses"));
ImGui::Dummy(ImVec2(formW, emptyH));
ImGui::EndGroup();
ImGui::EndChild();
@@ -639,7 +645,7 @@ void RenderReceiveTab(App* app)
ImGui::Dummy(ImVec2(0, Layout::spacingMd()));
// ---- PAYMENT REQUEST ----
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "PAYMENT REQUEST");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("payment_request"));
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
// Amount input with currency toggle
@@ -805,7 +811,7 @@ void RenderReceiveTab(App* app)
// Memo (z-addresses only)
if (isZ) {
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "MEMO (OPTIONAL)");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("memo_optional"));
ImGui::Dummy(ImVec2(0, S.drawElement("tabs.receive", "memo-label-gap").size));
float memoInputH = std::max(schema::UI().drawElement("tabs.receive", "memo-input-min-height").size, schema::UI().drawElement("tabs.receive", "memo-input-height").size * vScale);
@@ -841,7 +847,7 @@ void RenderReceiveTab(App* app)
ImGui::PushStyleColor(ImGuiCol_Text,
ImGui::ColorConvertU32ToFloat4(hasData ? OnSurfaceMedium() : OnSurfaceDisabled()));
ImGui::BeginDisabled(!hasData);
if (TactileSmallButton("Clear Request##recv", S.resolveFont("button"))) {
if (TactileSmallButton(TrId("clear_request", "recv").c_str(), S.resolveFont("button"))) {
s_request_amount = 0.0;
s_request_usd_amount = 0.0;
s_request_memo[0] = '\0';
@@ -880,20 +886,20 @@ void RenderReceiveTab(App* app)
ImVec2 textPos(qrPanelMin.x + totalQrSize * 0.5f - S.drawElement("tabs.receive", "qr-unavailable-text-offset").size,
qrPanelMin.y + totalQrSize * 0.5f);
dl->AddText(capFont, capFont->LegacySize, textPos,
OnSurfaceDisabled(), "QR unavailable");
OnSurfaceDisabled(), TR("qr_unavailable"));
}
ImGui::SetCursorScreenPos(qrPanelMin);
ImGui::InvisibleButton("##QRClickCopy", ImVec2(totalQrSize, totalQrSize));
if (ImGui::IsItemHovered()) {
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
ImGui::SetTooltip("Click to copy %s",
s_request_amount > 0 ? "payment URI" : "address");
ImGui::SetTooltip("%s",
s_request_amount > 0 ? TR("click_copy_uri") : TR("click_copy_address"));
}
if (ImGui::IsItemClicked()) {
ImGui::SetClipboardText(qr_data.c_str());
Notifications::instance().info(s_request_amount > 0
? "Payment URI copied" : "Address copied");
? TR("payment_uri_copied") : TR("address_copied"));
}
ImGui::SetCursorScreenPos(ImVec2(rx, qrPanelMax.y));
@@ -926,9 +932,9 @@ void RenderReceiveTab(App* app)
if (s_request_amount > 0) {
if (!firstBtn) ImGui::SameLine(0, btnGap);
firstBtn = false;
if (TactileButton("Copy URI##recv", ImVec2(otherBtnW, btnH), S.resolveFont("button"))) {
if (TactileButton(TrId("copy_uri", "recv").c_str(), ImVec2(otherBtnW, btnH), S.resolveFont("button"))) {
ImGui::SetClipboardText(s_cached_qr_data.c_str());
Notifications::instance().info("Payment URI copied");
Notifications::instance().info(TR("payment_uri_copied"));
}
}
@@ -939,14 +945,16 @@ void RenderReceiveTab(App* app)
ImGui::PushStyleColor(ImGuiCol_ButtonHovered,
ImGui::ColorConvertU32ToFloat4(IM_COL32(255, 255, 255, (int)S.drawElement("tabs.receive", "btn-hover-alpha").size)));
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::ColorConvertU32ToFloat4(PrimaryLight()));
if (TactileButton("Share##recv", ImVec2(otherBtnW, btnH), S.resolveFont("button"))) {
if (TactileButton(TrId("share", "recv").c_str(), ImVec2(otherBtnW, btnH), S.resolveFont("button"))) {
char shareBuf[1024];
snprintf(shareBuf, sizeof(shareBuf),
"Payment Request\nAmount: %.8f %s\nAddress: %s\nURI: %s",
"%s\n%s: %.8f %s\n%s: %s\nURI: %s",
TR("payment_request"), TR("amount"),
s_request_amount, DRAGONX_TICKER,
selected.address.c_str(), s_cached_qr_data.c_str());
TR("address"), selected.address.c_str(),
s_cached_qr_data.c_str());
ImGui::SetClipboardText(shareBuf);
Notifications::instance().info("Payment request copied");
Notifications::instance().info(TR("payment_request_copied"));
}
ImGui::PopStyleColor(3);
}
@@ -959,7 +967,7 @@ void RenderReceiveTab(App* app)
ImGui::PushStyleColor(ImGuiCol_Border, ImGui::ColorConvertU32ToFloat4(OnSurfaceDisabled()));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, S.drawElement("tabs.receive", "explorer-btn-border-size").size);
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::ColorConvertU32ToFloat4(PrimaryLight()));
if (TactileButton("Explorer##recv", ImVec2(otherBtnW, btnH), S.resolveFont("button"))) {
if (TactileButton(TrId("explorer", "recv").c_str(), ImVec2(otherBtnW, btnH), S.resolveFont("button"))) {
OpenExplorerURL(selected.address);
}
ImGui::PopStyleVar(); // FrameBorderSize
@@ -972,7 +980,7 @@ void RenderReceiveTab(App* app)
ImGui::PushStyleColor(ImGuiCol_ButtonHovered,
ImGui::ColorConvertU32ToFloat4(IM_COL32(255, 255, 255, (int)S.drawElement("tabs.receive", "btn-hover-alpha").size)));
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::ColorConvertU32ToFloat4(OnSurfaceMedium()));
if (TactileButton("Send \xe2\x86\x97##recv", ImVec2(otherBtnW, btnH), S.resolveFont("button"))) {
if (TactileButton(TrId("send", "recv").c_str(), ImVec2(otherBtnW, btnH), S.resolveFont("button"))) {
SetSendFromAddress(selected.address);
app->setCurrentPage(NavPage::Send);
}
@@ -1001,7 +1009,7 @@ void RenderReceiveTab(App* app)
ImGui::SetCursorScreenPos(ImVec2(containerMin.x, containerMax.y));
ImGui::Dummy(ImVec2(formW, 0));
ImGui::Dummy(ImVec2(0, Layout::spacingMd()));
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
}
// ================================================================
+15 -18
View File
@@ -128,22 +128,19 @@ void RequestPaymentDialog::render(App* app)
auto qr = S.drawElement("dialogs.request-payment", "qr-code");
auto actionBtn = S.button("dialogs.request-payment", "action-button");
if (material::BeginOverlayDialog("Request Payment", &s_open, win.width, 0.94f)) {
if (material::BeginOverlayDialog(TR("request_title"), &s_open, win.width, 0.94f)) {
const auto& state = app->getWalletState();
ImGui::TextWrapped(
"Generate a payment request that others can scan or copy. "
"The QR code contains your address and optional amount/memo."
);
ImGui::TextWrapped("%s", TR("request_description"));
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
// Address selection
ImGui::Text("Receive Address:");
ImGui::Text("%s", TR("request_receive_address"));
std::string addr_display = s_address[0] ? s_address : "Select address...";
std::string addr_display = s_address[0] ? s_address : TR("request_select_address");
if (addr_display.length() > static_cast<size_t>(zAddrLbl.truncate)) {
addr_display = addr_display.substr(0, zAddrFrontLbl.truncate) + "..." + addr_display.substr(addr_display.length() - zAddrBackLbl.truncate);
}
@@ -152,7 +149,7 @@ void RequestPaymentDialog::render(App* app)
if (ImGui::BeginCombo("##Address", addr_display.c_str())) {
// Z-addresses
if (!state.z_addresses.empty()) {
ImGui::TextDisabled("-- Shielded Addresses --");
ImGui::TextDisabled("%s", TR("request_shielded_addrs"));
for (size_t i = 0; i < state.z_addresses.size(); i++) {
const auto& addr = state.z_addresses[i];
std::string label = addr.address;
@@ -169,7 +166,7 @@ void RequestPaymentDialog::render(App* app)
// T-addresses
if (!state.t_addresses.empty()) {
ImGui::TextDisabled("-- Transparent Addresses --");
ImGui::TextDisabled("%s", TR("request_transparent_addrs"));
for (size_t i = 0; i < state.t_addresses.size(); i++) {
const auto& addr = state.t_addresses[i];
std::string label = addr.address;
@@ -189,7 +186,7 @@ void RequestPaymentDialog::render(App* app)
ImGui::Spacing();
// Amount (optional)
ImGui::Text("Amount (optional):");
ImGui::Text("%s", TR("request_amount"));
ImGui::SetNextItemWidth(amountInput.width);
if (ImGui::InputDouble("##Amount", &s_amount, 0.1, 1.0, "%.8f")) {
s_uri_dirty = true;
@@ -200,7 +197,7 @@ void RequestPaymentDialog::render(App* app)
ImGui::Spacing();
// Label (optional)
ImGui::Text("Label (optional):");
ImGui::Text("%s", TR("request_label"));
ImGui::SetNextItemWidth(-1);
if (ImGui::InputText("##Label", s_label, sizeof(s_label))) {
s_uri_dirty = true;
@@ -211,7 +208,7 @@ void RequestPaymentDialog::render(App* app)
// Memo (optional, only for z-addr)
bool is_zaddr = (s_address[0] == 'z');
if (is_zaddr) {
ImGui::Text("Memo (optional):");
ImGui::Text("%s", TR("request_memo"));
ImGui::SetNextItemWidth(-1);
if (ImGui::InputTextMultiline("##Memo", s_memo, sizeof(s_memo), ImVec2(-1, memoInput.height > 0 ? memoInput.height : 60))) {
s_uri_dirty = true;
@@ -245,7 +242,7 @@ void RequestPaymentDialog::render(App* app)
// Payment URI display
if (!s_payment_uri.empty()) {
ImGui::Text("Payment URI:");
ImGui::Text("%s", TR("request_payment_uri"));
ImGui::SetNextItemWidth(-1);
// Use a selectable text area for the URI
@@ -256,23 +253,23 @@ void RequestPaymentDialog::render(App* app)
ImGui::Spacing();
// Copy button
if (material::StyledButton("Copy URI", ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
if (material::StyledButton(TR("request_copy_uri"), ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
ImGui::SetClipboardText(s_payment_uri.c_str());
Notifications::instance().success("Payment URI copied to clipboard");
Notifications::instance().success(TR("request_uri_copied"));
}
ImGui::SameLine();
if (material::StyledButton("Copy Address", ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
if (material::StyledButton(TR("copy_address"), ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
ImGui::SetClipboardText(s_address);
Notifications::instance().success("Address copied to clipboard");
Notifications::instance().success(TR("address_copied"));
}
}
ImGui::Spacing();
// Close button
if (material::StyledButton("Close", ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
if (material::StyledButton(TR("close"), ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
s_open = false;
}
material::EndOverlayDialog();
+56 -56
View File
@@ -214,7 +214,7 @@ static void RenderSourceDropdown(App* app, float width) {
auto& S = schema::UI();
char buf[256];
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "SENDING FROM");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("send_sending_from"));
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
// Auto-select the address with the largest balance on first load
@@ -237,7 +237,7 @@ static void RenderSourceDropdown(App* app, float width) {
// Build preview string for selected address
if (!app->isConnected()) {
s_source_preview = "Not connected to daemon";
s_source_preview = TR("not_connected");
} else if (s_selected_from_idx >= 0 &&
s_selected_from_idx < (int)state.addresses.size()) {
const auto& addr = state.addresses[s_selected_from_idx];
@@ -249,7 +249,7 @@ static void RenderSourceDropdown(App* app, float width) {
tag, trunc.c_str(), addr.balance, DRAGONX_TICKER);
s_source_preview = buf;
} else {
s_source_preview = "Select a source address...";
s_source_preview = TR("send_select_source");
}
ImGui::SetNextItemWidth(width);
@@ -257,7 +257,7 @@ static void RenderSourceDropdown(App* app, float width) {
ImGui::PushFont(Type().getFont(TypeStyle::Body2));
if (ImGui::BeginCombo("##SendFrom", s_source_preview.c_str())) {
if (!app->isConnected() || state.addresses.empty()) {
ImGui::TextDisabled("No addresses available");
ImGui::TextDisabled("%s", TR("no_addresses_available"));
} else {
// Sort by balance descending, only show addresses with balance
std::vector<size_t> sortedIdx;
@@ -272,7 +272,7 @@ static void RenderSourceDropdown(App* app, float width) {
});
if (sortedIdx.empty()) {
ImGui::TextDisabled("No addresses with balance");
ImGui::TextDisabled("%s", TR("send_no_balance"));
} else {
size_t addrTruncLen = static_cast<size_t>(std::max(S.drawElement("tabs.send", "addr-dropdown-trunc-min").size, width / S.drawElement("tabs.send", "addr-dropdown-trunc-divisor").size));
@@ -352,7 +352,7 @@ static void RenderAddressSuggestions(const WalletState& state, float width, cons
// ============================================================================
static void RenderFeeTierSelector(const char* suffix = "") {
auto& S = schema::UI();
const char* feeLabels[] = { "Low", "Normal", "High" };
const char* feeLabels[] = { TR("send_fee_low"), TR("send_fee_normal"), TR("send_fee_high") };
const double feeValues[] = { FEE_LOW, FEE_NORMAL, FEE_HIGH };
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
@@ -569,12 +569,12 @@ static void RenderTxProgress(ImDrawList* dl, float x, float y, float w,
ImGui::PushStyleColor(ImGuiCol_Button, ImGui::ColorConvertU32ToFloat4(IM_COL32(255, 255, 255, (int)schema::UI().drawElement("tabs.send", "error-btn-bg-alpha").size)));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::ColorConvertU32ToFloat4(IM_COL32(255, 255, 255, (int)schema::UI().drawElement("tabs.send", "error-btn-hover-alpha").size)));
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, schema::UI().drawElement("tabs.send", "error-btn-rounding").size);
if (TactileSmallButton("Copy Error##txErr", schema::UI().resolveFont("button"))) {
if (TactileSmallButton(TR("send_copy_error"), schema::UI().resolveFont("button"))) {
ImGui::SetClipboardText(s_tx_status.c_str());
Notifications::instance().info("Error copied to clipboard");
Notifications::instance().info(TR("send_error_copied"));
}
ImGui::SameLine();
if (TactileSmallButton("Dismiss##txErr", schema::UI().resolveFont("button"))) {
if (TactileSmallButton(TR("send_dismiss"), schema::UI().resolveFont("button"))) {
s_tx_status.clear();
s_result_txid.clear();
s_status_success = false;
@@ -615,7 +615,7 @@ static void RenderTxProgress(ImDrawList* dl, float x, float y, float w,
dl->AddText(iconFont, iconFont->LegacySize,
ImVec2(ix, iy), Primary(), spinIcon);
double elapsed = ImGui::GetTime() - s_send_start_time;
snprintf(buf, sizeof(buf), "Submitting transaction... (%.0fs)", elapsed);
snprintf(buf, sizeof(buf), TR("send_submitting"), elapsed);
dl->AddText(body2, body2->LegacySize, ImVec2(ix + iSz.x + schema::UI().drawElement("tabs.send", "progress-icon-text-gap").size, iy), OnSurface(), buf);
} else {
// Success checkmark
@@ -624,7 +624,7 @@ static void RenderTxProgress(ImDrawList* dl, float x, float y, float w,
ImVec2 iSz = iconFont->CalcTextSizeA(iconFont->LegacySize, 1000.0f, 0.0f, checkIcon);
dl->AddText(iconFont, iconFont->LegacySize,
ImVec2(ix, iy), Success(), checkIcon);
dl->AddText(body2, body2->LegacySize, ImVec2(ix + iSz.x + schema::UI().drawElement("tabs.send", "progress-icon-text-gap").size, iy), Success(), "Transaction sent!");
dl->AddText(body2, body2->LegacySize, ImVec2(ix + iSz.x + schema::UI().drawElement("tabs.send", "progress-icon-text-gap").size, iy), Success(), TR("send_tx_sent"));
if (!s_result_txid.empty()) {
float txY = iy + body2->LegacySize + schema::UI().drawElement("tabs.send", "txid-y-offset").size;
@@ -633,13 +633,13 @@ static void RenderTxProgress(ImDrawList* dl, float x, float y, float w,
std::string dispTxid = (int)s_result_txid.length() > txidThreshold
? s_result_txid.substr(0, txidTruncLen) + "..." + s_result_txid.substr(s_result_txid.length() - txidTruncLen)
: s_result_txid;
snprintf(buf, sizeof(buf), "TxID: %s", dispTxid.c_str());
snprintf(buf, sizeof(buf), TR("send_txid_label"), dispTxid.c_str());
dl->AddText(capFont, capFont->LegacySize, ImVec2(ix + schema::UI().drawElement("tabs.send", "txid-label-x-offset").size, txY),
OnSurfaceDisabled(), buf);
ImGui::SetCursorScreenPos(ImVec2(pMax.x - schema::UI().drawElement("tabs.send", "txid-copy-btn-right-offset").size, txY - schema::UI().drawElement("tabs.send", "txid-copy-btn-y-offset").size));
if (TactileSmallButton("Copy##TxID", schema::UI().resolveFont("button"))) {
if (TactileSmallButton(TR("copy"), schema::UI().resolveFont("button"))) {
ImGui::SetClipboardText(s_result_txid.c_str());
Notifications::instance().info("TxID copied to clipboard");
Notifications::instance().info(TR("send_txid_copied"));
}
}
}
@@ -688,7 +688,7 @@ void RenderSendConfirmPopup(App* app) {
// FROM card
{
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "FROM");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("from_upper"));
ImVec2 cMin = ImGui::GetCursorScreenPos();
ImVec2 cMax(cMin.x + popW, cMin.y + addrCardH);
GlassPanelSpec gs; gs.rounding = popGlassRound;
@@ -702,7 +702,7 @@ void RenderSendConfirmPopup(App* app) {
// TO card
{
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "TO");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("to_upper"));
ImVec2 cMin = ImGui::GetCursorScreenPos();
ImVec2 cMax(cMin.x + popW, cMin.y + addrCardH);
GlassPanelSpec gs; gs.rounding = popGlassRound;
@@ -716,7 +716,7 @@ void RenderSendConfirmPopup(App* app) {
// Fee tier selector
{
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "NETWORK FEE");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("send_network_fee"));
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
RenderFeeTierSelector("##confirm");
// Recalculate total after potential fee change
@@ -729,7 +729,7 @@ void RenderSendConfirmPopup(App* app) {
float valX = std::max(schema::UI().drawElement("tabs.send", "confirm-val-col-min-x").size, schema::UI().drawElement("tabs.send", "confirm-val-col-x").size * popVs);
float usdX = popW - std::max(schema::UI().drawElement("tabs.send", "confirm-usd-col-min-x").size, schema::UI().drawElement("tabs.send", "confirm-usd-col-x").size * popVs);
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "AMOUNT DETAILS");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("send_amount_details"));
ImVec2 cMin = ImGui::GetCursorScreenPos();
float cH = std::max(schema::UI().drawElement("tabs.send", "confirm-amount-card-min-height").size, schema::UI().drawElement("tabs.send", "confirm-amount-card-height").size * popVs);
ImVec2 cMax(cMin.x + popW, cMin.y + cH);
@@ -740,7 +740,7 @@ void RenderSendConfirmPopup(App* app) {
float cy = cMin.y + Layout::spacingSm() + Layout::spacingXs();
float rowStep = std::max(schema::UI().drawElement("tabs.send", "confirm-row-step-min").size, schema::UI().drawElement("tabs.send", "confirm-row-step").size * popVs);
popDl->AddText(capFont, capFont->LegacySize, ImVec2(cx, cy), OnSurfaceMedium(), "Amount");
popDl->AddText(capFont, capFont->LegacySize, ImVec2(cx, cy), OnSurfaceMedium(), TR("send_amount"));
snprintf(buf, sizeof(buf), "%.8f %s", s_amount, DRAGONX_TICKER);
popDl->AddText(capFont, capFont->LegacySize, ImVec2(cx + valX, cy), OnSurface(), buf);
if (market.price_usd > 0) {
@@ -749,7 +749,7 @@ void RenderSendConfirmPopup(App* app) {
}
cy += rowStep;
popDl->AddText(capFont, capFont->LegacySize, ImVec2(cx, cy), OnSurfaceMedium(), "Fee");
popDl->AddText(capFont, capFont->LegacySize, ImVec2(cx, cy), OnSurfaceMedium(), TR("send_fee"));
snprintf(buf, sizeof(buf), "%.8f %s", s_fee, DRAGONX_TICKER);
popDl->AddText(capFont, capFont->LegacySize, ImVec2(cx + valX, cy), OnSurface(), buf);
if (market.price_usd > 0) {
@@ -762,7 +762,7 @@ void RenderSendConfirmPopup(App* app) {
ImGui::GetColorU32(Divider()), S.drawElement("tabs.send", "confirm-divider-thickness").size);
cy += rowStep;
popDl->AddText(sub1, sub1->LegacySize, ImVec2(cx, cy), OnSurfaceMedium(), "Total");
popDl->AddText(sub1, sub1->LegacySize, ImVec2(cx, cy), OnSurfaceMedium(), TR("send_total"));
snprintf(buf, sizeof(buf), "%.8f %s", total, DRAGONX_TICKER);
DrawTextShadow(popDl, sub1, sub1->LegacySize, ImVec2(cx + valX, cy), Primary(), buf);
if (market.price_usd > 0) {
@@ -774,7 +774,7 @@ void RenderSendConfirmPopup(App* app) {
}
if (s_memo[0] != '\0' && is_valid_z) {
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "MEMO");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("memo_upper"));
Type().textColored(TypeStyle::Caption, OnSurface(), s_memo);
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
}
@@ -782,7 +782,7 @@ void RenderSendConfirmPopup(App* app) {
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
if (s_sending) {
Type().text(TypeStyle::Body2, "Sending...");
Type().text(TypeStyle::Body2, TR("sending"));
} else {
if (TactileButton(TR("confirm_and_send"), ImVec2(S.button("tabs.send", "confirm-button").width, std::max(schema::UI().drawElement("tabs.send", "confirm-btn-min-height").size, schema::UI().drawElement("tabs.send", "confirm-btn-base-height").size * popVs)), S.resolveFont(S.button("tabs.send", "confirm-button").font))) {
s_sending = true;
@@ -801,26 +801,26 @@ void RenderSendConfirmPopup(App* app) {
s_sending = false;
s_status_timestamp = ImGui::GetTime();
if (success) {
s_tx_status = "Transaction sent!";
s_tx_status = TR("send_tx_sent");
s_result_txid = result;
s_status_success = true;
Notifications::instance().success("Transaction sent successfully!");
Notifications::instance().success(TR("send_tx_success"));
s_to_address[0] = '\0';
s_amount = 0.0;
s_memo[0] = '\0';
s_send_max = false;
} else {
s_tx_status = "Error: " + result;
s_tx_status = std::string(TR("send_error_prefix")) + result;
s_result_txid.clear();
s_status_success = false;
Notifications::instance().error("Transaction failed: " + result);
Notifications::instance().error(std::string(TR("send_tx_failed")) + result);
}
}
);
s_show_confirm = false;
}
ImGui::SameLine();
if (TactileButton("Cancel", ImVec2(S.button("tabs.send", "cancel-button").width, std::max(schema::UI().drawElement("tabs.send", "confirm-btn-min-height").size, schema::UI().drawElement("tabs.send", "confirm-btn-base-height").size * popVs)), S.resolveFont(S.button("tabs.send", "cancel-button").font))) {
if (TactileButton(TR("cancel"), ImVec2(S.button("tabs.send", "cancel-button").width, std::max(schema::UI().drawElement("tabs.send", "confirm-btn-min-height").size, schema::UI().drawElement("tabs.send", "confirm-btn-base-height").size * popVs)), S.resolveFont(S.button("tabs.send", "cancel-button").font))) {
s_show_confirm = false;
}
}
@@ -851,13 +851,13 @@ static bool RenderZeroBalanceCTA(App* app, ImDrawList* dl, float width) {
float cx = ctaMin.x + Layout::spacingXl();
float cy = ctaMin.y + Layout::spacingLg();
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, cy), OnSurface(), "Your wallet is empty");
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, cy), OnSurface(), TR("send_wallet_empty"));
cy += sub1->LegacySize + Layout::spacingSm();
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, cy), OnSurfaceMedium(),
"Switch to Receive to get your address and start receiving funds.");
TR("send_switch_to_receive"));
cy += capFont->LegacySize + Layout::spacingMd();
ImGui::SetCursorScreenPos(ImVec2(cx, cy));
if (TactileButton("Go to Receive", ImVec2(schema::UI().drawElement("tabs.send", "cta-button-width").size, schema::UI().drawElement("tabs.send", "cta-button-height").size), schema::UI().resolveFont("button"))) {
if (TactileButton(TR("send_go_to_receive"), ImVec2(schema::UI().drawElement("tabs.send", "cta-button-width").size, schema::UI().drawElement("tabs.send", "cta-button-height").size), schema::UI().resolveFont("button"))) {
app->setCurrentPage(NavPage::Receive);
}
ImGui::SetCursorScreenPos(ImVec2(ctaMin.x, ctaMax.y + Layout::spacingLg()));
@@ -904,19 +904,19 @@ static void RenderActionButtons(App* app, float width, float vScale,
if (!can_send && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
if (!app->isConnected())
ImGui::SetTooltip("Not connected to daemon");
ImGui::SetTooltip("%s", TR("send_tooltip_not_connected"));
else if (state.sync.syncing)
ImGui::SetTooltip("Blockchain is still syncing");
ImGui::SetTooltip("%s", TR("send_tooltip_syncing"));
else if (s_from_address[0] == '\0')
ImGui::SetTooltip("Select a source address above");
ImGui::SetTooltip("%s", TR("send_tooltip_select_source"));
else if (!is_valid_address)
ImGui::SetTooltip("Enter a valid recipient address");
ImGui::SetTooltip("%s", TR("send_tooltip_invalid_address"));
else if (s_amount <= 0)
ImGui::SetTooltip("Enter an amount to send");
ImGui::SetTooltip("%s", TR("send_tooltip_enter_amount"));
else if (total > available)
ImGui::SetTooltip("Amount exceeds available balance");
ImGui::SetTooltip("%s", TR("send_tooltip_exceeds_balance"));
else if (s_sending)
ImGui::SetTooltip("Transaction in progress...");
ImGui::SetTooltip("%s", TR("send_tooltip_in_progress"));
}
if (!can_send) ImGui::PopStyleColor(3);
@@ -946,14 +946,14 @@ static void RenderActionButtons(App* app, float width, float vScale,
s_clear_confirm_pending = false;
}
if (ImGui::BeginPopup(confirmClearId)) {
ImGui::Text("Clear all form fields?");
ImGui::Text("%s", TR("send_clear_fields"));
ImGui::Spacing();
if (TactileButton("Yes, Clear", ImVec2(schema::UI().drawElement("tabs.send", "clear-confirm-yes-width").size, 0), S.resolveFont("button"))) {
if (TactileButton(TR("send_yes_clear"), ImVec2(schema::UI().drawElement("tabs.send", "clear-confirm-yes-width").size, 0), S.resolveFont("button"))) {
ClearFormWithUndo();
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
if (TactileButton("Keep", ImVec2(schema::UI().drawElement("tabs.send", "clear-confirm-keep-width").size, 0), S.resolveFont("button"))) {
if (TactileButton(TR("send_keep"), ImVec2(schema::UI().drawElement("tabs.send", "clear-confirm-keep-width").size, 0), S.resolveFont("button"))) {
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
@@ -972,7 +972,7 @@ static void RenderActionButtons(App* app, float width, float vScale,
snprintf(undoId, sizeof(undoId), "Undo Clear%s", suffix);
if (TactileButton(undoId, ImVec2(width, btnH), S.resolveFont("button"))) {
RestoreFormSnapshot();
Notifications::instance().info("Form restored");
Notifications::instance().info(TR("send_form_restored"));
}
ImGui::PopStyleColor(2);
ImGui::PopStyleVar();
@@ -989,7 +989,7 @@ static void RenderRecentSends(ImDrawList* dl, const WalletState& state,
float width, ImFont* capFont, App* app) {
auto& S = schema::UI();
ImGui::Dummy(ImVec2(0, Layout::spacingLg()));
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "RECENT SENDS");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("send_recent_sends"));
ImGui::Dummy(ImVec2(0, Layout::spacingXs()));
ImVec2 avail = ImGui::GetContentRegionAvail();
@@ -1012,7 +1012,7 @@ static void RenderRecentSends(ImDrawList* dl, const WalletState& state,
}
if (sends.empty()) {
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), "No recent sends");
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), TR("send_no_recent"));
return;
}
@@ -1055,11 +1055,11 @@ static void RenderRecentSends(ImDrawList* dl, const WalletState& state,
// Type label (first line)
float labelX = cx + iconSz * 2.0f + Layout::spacingSm();
dl->AddText(capFont, capFont->LegacySize, ImVec2(labelX, cy), sendCol, "Sent");
dl->AddText(capFont, capFont->LegacySize, ImVec2(labelX, cy), sendCol, TR("sent_upper"));
// Time (next to type)
std::string ago = timeAgo(tx.timestamp);
float typeW = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0, "Sent").x;
float typeW = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0, TR("sent_upper")).x;
dl->AddText(capFont, capFont->LegacySize, ImVec2(labelX + typeW + Layout::spacingLg(), cy),
OnSurfaceDisabled(), ago.c_str());
@@ -1096,12 +1096,12 @@ static void RenderRecentSends(ImDrawList* dl, const WalletState& state,
const char* statusStr;
ImU32 statusCol;
if (tx.confirmations == 0) {
statusStr = "Pending"; statusCol = Warning();
statusStr = TR("pending"); statusCol = Warning();
} else if (tx.confirmations < (int)S.drawElement("tabs.send", "confirmed-threshold").size) {
snprintf(buf, sizeof(buf), "%d conf", tx.confirmations);
snprintf(buf, sizeof(buf), TR("conf_count"), tx.confirmations);
statusStr = buf; statusCol = Warning();
} else {
statusStr = "Confirmed"; statusCol = greenCol;
statusStr = TR("confirmed"); statusCol = greenCol;
}
ImVec2 sSz = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0, statusStr);
float statusX = amtX - sSz.x - Layout::spacingXxl();
@@ -1238,7 +1238,7 @@ void RenderSendTab(App* app)
static bool s_paste_previewing = false;
static std::string s_preview_text;
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "RECIPIENT");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("send_recipient"));
// Validation indicator — inline next to title (no height change)
// Check the preview text during hover, otherwise check actual address
@@ -1254,9 +1254,9 @@ void RenderSendTab(App* app)
if (vz || vt) {
ImGui::SameLine();
if (vz)
Type().textColored(TypeStyle::Caption, Success(), "Valid shielded address");
Type().textColored(TypeStyle::Caption, Success(), TR("send_valid_shielded"));
else
Type().textColored(TypeStyle::Caption, Warning(), "Valid transparent address");
Type().textColored(TypeStyle::Caption, Warning(), TR("send_valid_transparent"));
} else if (!checkPreview) {
ImGui::SameLine();
Type().textColored(TypeStyle::Caption, Error(), TR("invalid_address"));
@@ -1341,7 +1341,7 @@ void RenderSendTab(App* app)
// ---- AMOUNT ----
{
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "AMOUNT");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("send_amount_upper"));
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
// Toggle between DRGX and USD input
@@ -1439,7 +1439,7 @@ void RenderSendTab(App* app)
// Amount error
if (s_amount > 0 && s_amount + s_fee > available && available > 0) {
snprintf(buf, sizeof(buf), "Exceeds available (%.8f)", available - s_fee);
snprintf(buf, sizeof(buf), TR("send_exceeds_available"), available - s_fee);
Type().textColored(TypeStyle::Caption, Error(), buf);
}
}
@@ -1455,7 +1455,7 @@ void RenderSendTab(App* app)
}
ImGui::Dummy(ImVec2(0, innerGap * 0.5f));
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "MEMO (OPTIONAL)");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("memo_optional"));
ImGui::Dummy(ImVec2(0, S.drawElement("tabs.send", "memo-label-gap").size));
float memoInputH = std::max(S.drawElement("tabs.send", "memo-min-height").size, S.drawElement("tabs.send", "memo-base-height").size * vScale);
@@ -1502,7 +1502,7 @@ void RenderSendTab(App* app)
ImGui::SetCursorScreenPos(ImVec2(containerMin.x, containerMax.y));
ImGui::Dummy(ImVec2(formW, 0));
ImGui::Dummy(ImVec2(0, Layout::spacingMd()));
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
// Pass card bottom Y so error overlay can anchor to it
float cardBottom = containerMax.y;
+70 -66
View File
@@ -27,6 +27,14 @@
namespace dragonx {
namespace ui {
// Helper: build "TranslatedLabel##id" for ImGui widgets that use label as ID
static std::string TrId(const char* tr_key, const char* id) {
std::string s = TR(tr_key);
s += "##";
s += id;
return s;
}
// Settings state - these get loaded from Settings on window open
static bool s_initialized = false;
static int s_language_index = 0;
@@ -141,17 +149,17 @@ void RenderSettingsWindow(App* app, bool* p_open)
auto saveBtn = S.button("dialogs.settings", "save-button");
auto cancelBtn = S.button("dialogs.settings", "cancel-button");
if (!material::BeginOverlayDialog("Settings", p_open, win.width, 0.94f)) {
if (!material::BeginOverlayDialog(TR("settings"), p_open, win.width, 0.94f)) {
return;
}
if (ImGui::BeginTabBar("SettingsTabs")) {
// General settings tab
if (ImGui::BeginTabItem("General")) {
if (ImGui::BeginTabItem(TR("general"))) {
ImGui::Spacing();
// Skin/theme selection
ImGui::Text("Theme:");
ImGui::Text("%s", TR("theme"));
ImGui::SameLine(lbl.position);
// Active skin combo (populated from SkinManager)
@@ -172,7 +180,7 @@ void RenderSettingsWindow(App* app, bool* p_open)
ImGui::SetNextItemWidth(cmb.width);
if (ImGui::BeginCombo("##Theme", active_preview.c_str())) {
// Bundled themes header
ImGui::TextDisabled("Built-in");
ImGui::TextDisabled("%s", TR("settings_builtin"));
ImGui::Separator();
for (size_t i = 0; i < skins.size(); i++) {
const auto& skin = skins[i];
@@ -198,7 +206,7 @@ void RenderSettingsWindow(App* app, bool* p_open)
}
if (has_custom) {
ImGui::Spacing();
ImGui::TextDisabled("Custom");
ImGui::TextDisabled("%s", TR("settings_custom"));
ImGui::Separator();
for (size_t i = 0; i < skins.size(); i++) {
const auto& skin = skins[i];
@@ -236,7 +244,7 @@ void RenderSettingsWindow(App* app, bool* p_open)
ImGui::EndCombo();
}
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Hotkey: Ctrl+Left/Right to cycle themes");
ImGui::SetTooltip("%s", TR("tt_theme_hotkey"));
// Show indicator if custom theme is active
if (active_is_custom) {
@@ -245,7 +253,7 @@ void RenderSettingsWindow(App* app, bool* p_open)
ImGui::TextColored(ImVec4(0.4f, 0.8f, 1.0f, 1.0f), ICON_CUSTOM_THEME);
ImGui::PopFont();
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Custom theme active");
ImGui::SetTooltip("%s", TR("tt_custom_theme"));
}
}
@@ -257,14 +265,14 @@ void RenderSettingsWindow(App* app, bool* p_open)
}
ImGui::PopFont();
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Scan for new themes.\nPlace theme folders in:\n%s",
ImGui::SetTooltip(TR("tt_scan_themes"),
schema::SkinManager::getUserSkinsDirectory().c_str());
}
ImGui::Spacing();
// Language selection
ImGui::Text("Language:");
ImGui::Text("%s", TR("language"));
ImGui::SameLine(lbl.position);
auto& i18n = util::I18n::instance();
const auto& languages = i18n.getAvailableLanguages();
@@ -283,17 +291,17 @@ void RenderSettingsWindow(App* app, bool* p_open)
std::advance(it, s_language_index);
i18n.loadLanguage(it->first);
}
ImGui::TextDisabled(" Note: Some text requires restart to update");
ImGui::TextDisabled(" %s", TR("settings_language_note"));
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
// Acrylic Effects settings
ImGui::Text("Visual Effects");
ImGui::Text("%s", TR("settings_visual_effects"));
ImGui::Spacing();
ImGui::Text("Acrylic Level:");
ImGui::Text("%s", TR("settings_acrylic_level"));
ImGui::SameLine(lbl.position);
ImGui::SetNextItemWidth(cmb.width);
{
@@ -309,10 +317,10 @@ void RenderSettingsWindow(App* app, bool* p_open)
effects::ImGuiAcrylic::ApplyBlurAmount(s_blur_amount);
}
}
ImGui::TextDisabled(" Blur amount (0%% = off, 100%% = maximum)");
ImGui::TextDisabled(" %s", TR("tt_blur"));
ImGui::Spacing();
ImGui::Text("Noise Opacity:");
ImGui::Text("%s", TR("settings_noise_opacity"));
ImGui::SameLine(lbl.position);
ImGui::SetNextItemWidth(cmb.width);
{
@@ -326,86 +334,86 @@ void RenderSettingsWindow(App* app, bool* p_open)
effects::ImGuiAcrylic::SetNoiseOpacity(s_noise_opacity);
}
}
ImGui::TextDisabled(" Grain texture intensity (0%% = off, 100%% = maximum)");
ImGui::TextDisabled(" %s", TR("tt_noise"));
ImGui::Spacing();
// Accessibility: Reduced transparency
if (ImGui::Checkbox("Reduce transparency", &s_reduced_transparency)) {
if (ImGui::Checkbox(TrId("settings_reduce_transparency", "reduce_trans").c_str(), &s_reduced_transparency)) {
effects::ImGuiAcrylic::SetReducedTransparency(s_reduced_transparency);
}
ImGui::TextDisabled(" Use solid colors instead of blur effects (accessibility)");
ImGui::TextDisabled(" %s", TR("settings_solid_colors_desc"));
ImGui::Spacing();
if (ImGui::Checkbox("Simple background", &s_gradient_background)) {
if (ImGui::Checkbox(TrId("simple_background", "simple_bg").c_str(), &s_gradient_background)) {
schema::SkinManager::instance().setGradientMode(s_gradient_background);
}
ImGui::TextDisabled(" Replace textured backgrounds with smooth gradients");
ImGui::TextDisabled(" %s", TR("settings_gradient_desc"));
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
// Privacy settings
ImGui::Text("Privacy");
ImGui::Text("%s", TR("settings_privacy"));
ImGui::Spacing();
ImGui::Checkbox("Save shielded transaction history locally", &s_save_ztxs);
ImGui::TextDisabled(" Stores z-addr transactions in a local file for viewing");
ImGui::Checkbox(TrId("settings_save_shielded_local", "save_ztx_w").c_str(), &s_save_ztxs);
ImGui::TextDisabled(" %s", TR("settings_save_shielded_desc"));
ImGui::Spacing();
ImGui::Checkbox("Auto-shield transparent funds", &s_auto_shield);
ImGui::TextDisabled(" Automatically move transparent funds to shielded addresses");
ImGui::Checkbox(TrId("settings_auto_shield_funds", "auto_shld_w").c_str(), &s_auto_shield);
ImGui::TextDisabled(" %s", TR("settings_auto_shield_desc"));
ImGui::Spacing();
ImGui::Checkbox("Use Tor for network connections", &s_use_tor);
ImGui::TextDisabled(" Route all connections through Tor for enhanced privacy");
ImGui::Checkbox(TrId("settings_use_tor_network", "tor_w").c_str(), &s_use_tor);
ImGui::TextDisabled(" %s", TR("settings_tor_desc"));
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
// Other settings
ImGui::Text("Other");
ImGui::Text("%s", TR("settings_other"));
ImGui::Spacing();
ImGui::Checkbox("Allow custom transaction fees", &s_allow_custom_fees);
ImGui::Checkbox("Fetch price data from CoinGecko", &s_fetch_prices);
ImGui::Checkbox(TrId("custom_fees", "fees_w").c_str(), &s_allow_custom_fees);
ImGui::Checkbox(TrId("fetch_prices", "prices_w").c_str(), &s_fetch_prices);
ImGui::EndTabItem();
}
// Connection settings tab
if (ImGui::BeginTabItem("Connection")) {
if (ImGui::BeginTabItem(TR("settings_connection"))) {
ImGui::Spacing();
ImGui::Text("RPC Connection");
ImGui::TextDisabled("Configure connection to dragonxd daemon");
ImGui::Text("%s", TR("settings_rpc_connection"));
ImGui::TextDisabled("%s", TR("settings_configure_rpc"));
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
ImGui::Text("Host:");
ImGui::Text("%s", TR("rpc_host"));
ImGui::SameLine(connLbl.position);
ImGui::SetNextItemWidth(cmb.width);
ImGui::InputText("##RPCHost", s_rpc_host, sizeof(s_rpc_host));
ImGui::Text("Port:");
ImGui::Text("%s", TR("rpc_port"));
ImGui::SameLine(connLbl.position);
ImGui::SetNextItemWidth(portInput.width);
ImGui::InputText("##RPCPort", s_rpc_port, sizeof(s_rpc_port));
ImGui::Spacing();
ImGui::Text("Username:");
ImGui::Text("%s", TR("rpc_user"));
ImGui::SameLine(connLbl.position);
ImGui::SetNextItemWidth(cmb.width);
ImGui::InputText("##RPCUser", s_rpc_user, sizeof(s_rpc_user));
ImGui::Text("Password:");
ImGui::Text("%s", TR("rpc_pass"));
ImGui::SameLine(connLbl.position);
ImGui::SetNextItemWidth(cmb.width);
ImGui::InputText("##RPCPassword", s_rpc_password, sizeof(s_rpc_password),
@@ -415,11 +423,11 @@ void RenderSettingsWindow(App* app, bool* p_open)
ImGui::Separator();
ImGui::Spacing();
ImGui::TextDisabled("Note: Connection settings are usually auto-detected from DRAGONX.conf");
ImGui::TextDisabled("%s", TR("settings_rpc_note"));
ImGui::Spacing();
if (material::StyledButton("Test Connection", ImVec2(0,0), S.resolveFont("button"))) {
if (material::StyledButton(TR("test_connection"), ImVec2(0,0), S.resolveFont("button"))) {
if (app->rpc()) {
app->rpc()->getInfo([](const nlohmann::json& result, const std::string& error) {
if (error.empty()) {
@@ -439,15 +447,15 @@ void RenderSettingsWindow(App* app, bool* p_open)
}
// Wallet tab
if (ImGui::BeginTabItem("Wallet")) {
if (ImGui::BeginTabItem(TR("wallet"))) {
ImGui::Spacing();
ImGui::Text("Wallet Maintenance");
ImGui::Text("%s", TR("settings_wallet_maintenance"));
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
if (material::StyledButton("Rescan Blockchain", ImVec2(walletBtn.width, 0), S.resolveFont(walletBtn.font))) {
if (material::StyledButton(TR("rescan"), ImVec2(walletBtn.width, 0), S.resolveFont(walletBtn.font))) {
if (app->rpc()) {
// Start rescan from block 0
app->rpc()->rescanBlockchain(0, [](const nlohmann::json& result, const std::string& error) {
@@ -465,45 +473,41 @@ void RenderSettingsWindow(App* app, bool* p_open)
Notifications::instance().error("RPC client not initialized");
}
}
ImGui::TextDisabled(" Rescan blockchain for missing transactions");
ImGui::TextDisabled(" %s", TR("settings_rescan_desc"));
ImGui::Spacing();
static bool s_confirm_clear_ztx = false;
if (material::StyledButton("Clear Saved Z-Transaction History", ImVec2(walletBtn.width, 0), S.resolveFont(walletBtn.font))) {
if (material::StyledButton(TR("settings_clear_ztx_long"), ImVec2(walletBtn.width, 0), S.resolveFont(walletBtn.font))) {
s_confirm_clear_ztx = true;
}
ImGui::TextDisabled(" Delete locally stored shielded transaction data");
ImGui::TextDisabled(" %s", TR("settings_clear_ztx_desc"));
// Confirmation dialog
if (s_confirm_clear_ztx) {
if (material::BeginOverlayDialog("Confirm Clear Z-Tx History", &s_confirm_clear_ztx, 480.0f, 0.94f)) {
if (material::BeginOverlayDialog(TR("confirm_clear_ztx_title"), &s_confirm_clear_ztx, 480.0f, 0.94f)) {
ImGui::PushFont(material::Type().iconLarge());
ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.0f, 1.0f), ICON_MD_WARNING);
ImGui::PopFont();
ImGui::SameLine();
ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.0f, 1.0f), "Warning");
ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.0f, 1.0f), "%s", TR("warning"));
ImGui::Spacing();
ImGui::TextWrapped(
"Clearing z-transaction history may cause your shielded balance to show as 0 "
"until a wallet rescan is performed.");
ImGui::TextWrapped("%s", TR("confirm_clear_ztx_warning1"));
ImGui::Spacing();
ImGui::TextWrapped(
"If this happens, you will need to re-import your z-address private keys with "
"rescan enabled to recover your balance.");
ImGui::TextWrapped("%s", TR("confirm_clear_ztx_warning2"));
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
float btnW = (ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ItemSpacing.x) * 0.5f;
if (ImGui::Button("Cancel", ImVec2(btnW, 40))) {
if (ImGui::Button(TR("cancel"), ImVec2(btnW, 40))) {
s_confirm_clear_ztx = false;
}
ImGui::SameLine();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.8f, 0.2f, 0.2f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.9f, 0.3f, 0.3f, 1.0f));
if (ImGui::Button("Clear Anyway", ImVec2(btnW, 40))) {
if (ImGui::Button(TrId("clear_anyway", "clear_ztx_w").c_str(), ImVec2(btnW, 40))) {
std::string ztx_file = util::Platform::getDragonXDataDir() + "ztx_history.json";
if (util::Platform::deleteFile(ztx_file)) {
Notifications::instance().success("Z-transaction history cleared");
@@ -521,7 +525,7 @@ void RenderSettingsWindow(App* app, bool* p_open)
ImGui::Separator();
ImGui::Spacing();
ImGui::Text("Wallet Info");
ImGui::Text("%s", TR("settings_wallet_info"));
ImGui::Spacing();
// Get actual wallet size
@@ -529,35 +533,35 @@ void RenderSettingsWindow(App* app, bool* p_open)
uint64_t wallet_size = util::Platform::getFileSize(wallet_path);
if (wallet_size > 0) {
std::string size_str = util::Platform::formatFileSize(wallet_size);
ImGui::Text("Wallet file size: %s", size_str.c_str());
ImGui::Text(TR("settings_wallet_file_size"), size_str.c_str());
} else {
ImGui::TextDisabled("Wallet file not found");
ImGui::TextDisabled("%s", TR("settings_wallet_not_found"));
}
ImGui::Text("Wallet location: %s", wallet_path.c_str());
ImGui::Text(TR("settings_wallet_location"), wallet_path.c_str());
ImGui::EndTabItem();
}
// Explorer tab
if (ImGui::BeginTabItem("Explorer")) {
if (ImGui::BeginTabItem(TR("explorer"))) {
ImGui::Spacing();
ImGui::Text("Block Explorer URLs");
ImGui::TextDisabled("Configure external block explorer links");
ImGui::Text("%s", TR("settings_block_explorer_urls"));
ImGui::TextDisabled("%s", TR("settings_configure_explorer"));
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
ImGui::Text("Transaction URL:");
ImGui::Text("%s", TR("transaction_url"));
ImGui::SetNextItemWidth(-1);
ImGui::InputText("##TxExplorer", s_tx_explorer, sizeof(s_tx_explorer));
ImGui::Text("Address URL:");
ImGui::Text("%s", TR("address_url"));
ImGui::SetNextItemWidth(-1);
ImGui::InputText("##AddrExplorer", s_addr_explorer, sizeof(s_addr_explorer));
ImGui::Spacing();
ImGui::TextDisabled("URLs should include a trailing slash. The txid/address will be appended.");
ImGui::TextDisabled("%s", TR("settings_explorer_hint"));
ImGui::EndTabItem();
}
@@ -570,13 +574,13 @@ void RenderSettingsWindow(App* app, bool* p_open)
ImGui::Spacing();
// Save/Cancel buttons
if (material::StyledButton("Save", ImVec2(saveBtn.width, 0), S.resolveFont(saveBtn.font))) {
if (material::StyledButton(TR("save"), ImVec2(saveBtn.width, 0), S.resolveFont(saveBtn.font))) {
saveSettingsFromUI(app->settings());
Notifications::instance().success("Settings saved");
*p_open = false;
}
ImGui::SameLine();
if (material::StyledButton("Cancel", ImVec2(cancelBtn.width, 0), S.resolveFont(cancelBtn.font))) {
if (material::StyledButton(TR("cancel"), ImVec2(cancelBtn.width, 0), S.resolveFont(cancelBtn.font))) {
// Reload settings to revert changes
loadSettingsToUI(app->settings());
// Revert skin to what was active when settings opened
+20 -27
View File
@@ -76,24 +76,17 @@ void ShieldDialog::render(App* app)
auto cancelBtn = S.button("dialogs.shield", "cancel-button");
const char* title = (s_mode == Mode::ShieldCoinbase)
? "Shield Coinbase Rewards"
: "Merge to Address";
? TR("shield_title")
: TR("merge_title");
if (material::BeginOverlayDialog(title, &s_open, win.width, 0.94f)) {
const auto& state = app->getWalletState();
// Description
if (s_mode == Mode::ShieldCoinbase) {
ImGui::TextWrapped(
"Shield your mining rewards by sending coinbase outputs from "
"transparent addresses to a shielded address. This improves "
"privacy by hiding your mining income."
);
ImGui::TextWrapped("%s", TR("shield_description"));
} else {
ImGui::TextWrapped(
"Merge multiple UTXOs into a single shielded address. This can "
"help reduce wallet size and improve privacy."
);
ImGui::TextWrapped("%s", TR("merge_description"));
}
ImGui::Spacing();
@@ -102,18 +95,18 @@ void ShieldDialog::render(App* app)
// From address (for shield coinbase)
if (s_mode == Mode::ShieldCoinbase) {
ImGui::Text("From Address:");
ImGui::Text("%s", TR("shield_from_address"));
ImGui::SetNextItemWidth(-1);
ImGui::InputText("##FromAddr", s_from_address, sizeof(s_from_address));
ImGui::TextDisabled("Use '*' to shield from all transparent addresses");
ImGui::TextDisabled("%s", TR("shield_wildcard_hint"));
ImGui::Spacing();
}
// To address (z-address dropdown)
ImGui::Text("To Address (Shielded):");
ImGui::Text("%s", TR("shield_to_address"));
// Get z-addresses for dropdown
std::string to_display = s_to_address[0] ? s_to_address : "Select z-address...";
std::string to_display = s_to_address[0] ? s_to_address : TR("shield_select_z");
if (to_display.length() > static_cast<size_t>(addrLbl.truncate)) {
to_display = to_display.substr(0, addrFrontLbl.truncate) + "..." + to_display.substr(to_display.length() - addrBackLbl.truncate);
}
@@ -142,7 +135,7 @@ void ShieldDialog::render(App* app)
ImGui::Spacing();
// Fee
ImGui::Text("Fee:");
ImGui::Text("%s", TR("fee_label"));
ImGui::SetNextItemWidth(feeInput.width);
ImGui::InputDouble("##Fee", &s_fee, 0.0001, 0.001, "%.8f");
ImGui::SameLine();
@@ -151,11 +144,11 @@ void ShieldDialog::render(App* app)
ImGui::Spacing();
// UTXO limit
ImGui::Text("UTXO Limit:");
ImGui::Text("%s", TR("shield_utxo_limit"));
ImGui::SetNextItemWidth(utxoInput.width);
ImGui::InputInt("##Limit", &s_utxo_limit);
ImGui::SameLine();
ImGui::TextDisabled("Max UTXOs per operation");
ImGui::TextDisabled("%s", TR("shield_max_utxos"));
if (s_utxo_limit < 1) s_utxo_limit = 1;
if (s_utxo_limit > 100) s_utxo_limit = 100;
@@ -178,7 +171,7 @@ void ShieldDialog::render(App* app)
if (!can_submit) ImGui::BeginDisabled();
const char* btn_label = (s_mode == Mode::ShieldCoinbase) ? "Shield Funds" : "Merge Funds";
const char* btn_label = (s_mode == Mode::ShieldCoinbase) ? TR("shield_funds") : TR("merge_funds");
if (material::StyledButton(btn_label, ImVec2(shieldBtn.width, 0), S.resolveFont(shieldBtn.font))) {
s_operation_pending = true;
s_status_message = "Submitting operation...";
@@ -201,7 +194,7 @@ void ShieldDialog::render(App* app)
if (error.empty()) {
s_operation_id = result.value("opid", "");
s_status_message = "Operation submitted: " + s_operation_id;
Notifications::instance().success("Shield operation started");
Notifications::instance().success(TR("shield_started"));
} else {
s_status_message = "Error: " + error;
Notifications::instance().error("Shield failed: " + error);
@@ -231,7 +224,7 @@ void ShieldDialog::render(App* app)
if (error.empty()) {
s_operation_id = result.value("opid", "");
s_status_message = "Operation submitted: " + s_operation_id;
Notifications::instance().success("Merge operation started");
Notifications::instance().success(TR("merge_started"));
} else {
s_status_message = "Error: " + error;
Notifications::instance().error("Merge failed: " + error);
@@ -246,7 +239,7 @@ void ShieldDialog::render(App* app)
ImGui::SameLine();
if (material::StyledButton("Cancel", ImVec2(cancelBtn.width, 0), S.resolveFont(cancelBtn.font))) {
if (material::StyledButton(TR("cancel"), ImVec2(cancelBtn.width, 0), S.resolveFont(cancelBtn.font))) {
s_open = false;
}
@@ -256,9 +249,9 @@ void ShieldDialog::render(App* app)
ImGui::Separator();
ImGui::Spacing();
ImGui::Text("Operation ID: %s", s_operation_id.c_str());
ImGui::Text(TR("shield_operation_id"), s_operation_id.c_str());
if (material::StyledButton("Check Status", ImVec2(0,0), S.resolveFont(shieldBtn.font))) {
if (material::StyledButton(TR("shield_check_status"), ImVec2(0,0), S.resolveFont(shieldBtn.font))) {
std::string opid = s_operation_id;
if (app->worker()) {
app->worker()->post([rpc = app->rpc(), opid]() -> rpc::RPCWorker::MainCb {
@@ -276,14 +269,14 @@ void ShieldDialog::render(App* app)
auto& op = result[0];
std::string status = op.value("status", "unknown");
if (status == "success") {
s_status_message = "Operation completed successfully!";
Notifications::instance().success("Shield/merge completed!");
s_status_message = TR("shield_completed");
Notifications::instance().success(TR("shield_merge_done"));
} else if (status == "failed") {
std::string errMsg = op.value("error", nlohmann::json{}).value("message", "Unknown error");
s_status_message = "Operation failed: " + errMsg;
Notifications::instance().error("Operation failed: " + errMsg);
} else if (status == "executing") {
s_status_message = "Operation in progress...";
s_status_message = TR("shield_in_progress");
} else {
s_status_message = "Status: " + status;
}
+15 -15
View File
@@ -44,7 +44,7 @@ void TransactionDetailsDialog::render(App* app)
auto memoInput = S.input("dialogs.transaction-details", "memo-input");
auto bottomBtn = S.button("dialogs.transaction-details", "bottom-button");
if (material::BeginOverlayDialog("Transaction Details", &s_open, win.width, 0.94f)) {
if (material::BeginOverlayDialog(TR("tx_details_title"), &s_open, win.width, 0.94f)) {
const auto& tx = s_transaction;
// Type indicator with color
@@ -52,16 +52,16 @@ void TransactionDetailsDialog::render(App* app)
std::string type_display;
if (tx.type == "receive") {
type_color = ImVec4(0.3f, 0.8f, 0.3f, 1.0f);
type_display = "RECEIVED";
type_display = TR("tx_received");
} else if (tx.type == "send") {
type_color = ImVec4(0.8f, 0.3f, 0.3f, 1.0f);
type_display = "SENT";
type_display = TR("tx_sent");
} else if (tx.type == "generate" || tx.type == "mined") {
type_color = ImVec4(0.3f, 0.6f, 0.9f, 1.0f);
type_display = "MINED";
type_display = TR("tx_mined");
} else if (tx.type == "immature") {
type_color = ImVec4(0.8f, 0.8f, 0.3f, 1.0f);
type_display = "IMMATURE";
type_display = TR("tx_immature");
} else {
type_color = ImVec4(0.7f, 0.7f, 0.7f, 1.0f);
type_display = tx.type;
@@ -72,11 +72,11 @@ void TransactionDetailsDialog::render(App* app)
// Confirmations badge
if (tx.confirmations == 0) {
ImGui::TextColored(ImVec4(0.8f, 0.6f, 0.0f, 1.0f), "Pending");
ImGui::TextColored(ImVec4(0.8f, 0.6f, 0.0f, 1.0f), "%s", TR("pending"));
} else if (tx.confirmations < 10) {
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.3f, 1.0f), "%d confirmations", tx.confirmations);
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.3f, 1.0f), TR("tx_confirmations"), tx.confirmations);
} else {
ImGui::TextColored(ImVec4(0.3f, 0.8f, 0.3f, 1.0f), "%d confirmations", tx.confirmations);
ImGui::TextColored(ImVec4(0.3f, 0.8f, 0.3f, 1.0f), TR("tx_confirmations"), tx.confirmations);
}
ImGui::Spacing();
@@ -84,7 +84,7 @@ void TransactionDetailsDialog::render(App* app)
ImGui::Spacing();
// Amount (prominent display)
ImGui::Text("Amount:");
ImGui::Text("%s", TR("amount_label"));
ImGui::SameLine(lbl.position);
if (tx.amount >= 0) {
ImGui::TextColored(ImVec4(0.3f, 0.8f, 0.3f, 1.0f), "+%.8f DRGX", tx.amount);
@@ -102,7 +102,7 @@ void TransactionDetailsDialog::render(App* app)
ImGui::Spacing();
// Date/Time
ImGui::Text("Date:");
ImGui::Text("%s", TR("date_label"));
ImGui::SameLine(lbl.position);
ImGui::Text("%s", tx.getTimeString().c_str());
@@ -111,7 +111,7 @@ void TransactionDetailsDialog::render(App* app)
ImGui::Spacing();
// Transaction ID
ImGui::Text("Transaction ID:");
ImGui::Text("%s", TR("tx_id_label"));
char txid_buf[128];
strncpy(txid_buf, tx.txid.c_str(), sizeof(txid_buf) - 1);
txid_buf[sizeof(txid_buf) - 1] = '\0';
@@ -126,7 +126,7 @@ void TransactionDetailsDialog::render(App* app)
// Address
if (!tx.address.empty()) {
ImGui::Text(tx.type == "send" ? "To Address:" : "From Address:");
ImGui::Text("%s", tx.type == "send" ? TR("tx_to_address") : TR("tx_from_address"));
// Use multiline for z-addresses
if (tx.address.length() > 50) {
@@ -155,7 +155,7 @@ void TransactionDetailsDialog::render(App* app)
ImGui::Separator();
ImGui::Spacing();
ImGui::Text("Memo:");
ImGui::Text("%s", TR("memo_label"));
char memo_buf[512];
strncpy(memo_buf, tx.memo.c_str(), sizeof(memo_buf) - 1);
memo_buf[sizeof(memo_buf) - 1] = '\0';
@@ -173,7 +173,7 @@ void TransactionDetailsDialog::render(App* app)
float start_x = (ImGui::GetWindowWidth() - total_width) / 2.0f;
ImGui::SetCursorPosX(start_x);
if (material::StyledButton("View on Explorer", ImVec2(button_width, 0), S.resolveFont(bottomBtn.font))) {
if (material::StyledButton(TR("tx_view_explorer"), ImVec2(button_width, 0), S.resolveFont(bottomBtn.font))) {
std::string url = app->settings()->getTxExplorerUrl() + tx.txid;
// Platform-specific URL opening
#ifdef _WIN32
@@ -189,7 +189,7 @@ void TransactionDetailsDialog::render(App* app)
ImGui::SameLine();
if (material::StyledButton("Close", ImVec2(button_width, 0), S.resolveFont(bottomBtn.font))) {
if (material::StyledButton(TR("close"), ImVec2(button_width, 0), S.resolveFont(bottomBtn.font))) {
s_open = false;
}
material::EndOverlayDialog();
+48 -42
View File
@@ -6,6 +6,7 @@
#include "transaction_details_dialog.h"
#include "export_transactions_dialog.h"
#include "../../app.h"
#include "../../util/i18n.h"
#include "../../config/settings.h"
#include "../../config/version.h"
#include "../theme.h"
@@ -28,6 +29,10 @@ namespace ui {
using namespace material;
static std::string TrId(const char* key, const char* id) {
return std::string(TR(key)) + "##" + id;
}
// Helper to truncate strings
static std::string truncateString(const std::string& str, int maxLen = 16) {
if (str.length() <= static_cast<size_t>(maxLen)) return str;
@@ -66,7 +71,7 @@ struct DisplayTx {
};
std::string DisplayTx::getTimeString() const {
if (timestamp <= 0) return "Pending";
if (timestamp <= 0) return TR("pending");
std::time_t t = static_cast<std::time_t>(timestamp);
char buf[64];
std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M", std::localtime(&t));
@@ -79,10 +84,11 @@ static std::string timeAgo(int64_t timestamp) {
int64_t now = (int64_t)std::time(nullptr);
int64_t diff = now - timestamp;
if (diff < 0) diff = 0;
if (diff < 60) return std::to_string(diff) + "s ago";
if (diff < 3600) return std::to_string(diff / 60) + "m ago";
if (diff < 86400) return std::to_string(diff / 3600) + "h ago";
return std::to_string(diff / 86400) + "d ago";
char buf[32];
if (diff < 60) { snprintf(buf, sizeof(buf), TR("time_seconds_ago"), (long long)diff); return buf; }
if (diff < 3600) { snprintf(buf, sizeof(buf), TR("time_minutes_ago"), (long long)(diff / 60)); return buf; }
if (diff < 86400) { snprintf(buf, sizeof(buf), TR("time_hours_ago"), (long long)(diff / 3600)); return buf; }
snprintf(buf, sizeof(buf), TR("time_days_ago"), (long long)(diff / 86400)); return buf;
}
// Draw a small transaction-type icon
@@ -191,10 +197,10 @@ void RenderTransactionsTab(App* app)
DrawTxIcon(dl, "receive", cx + iconSz, cy + iconSz * 1.33f, iconSz, greenCol);
float labelX = cx + iconSz * 3.0f;
dl->AddText(ovFont, ovFont->LegacySize, ImVec2(labelX, cy), OnSurfaceMedium(), "RECEIVED");
dl->AddText(ovFont, ovFont->LegacySize, ImVec2(labelX, cy), OnSurfaceMedium(), TR("received_upper"));
cy += ovFont->LegacySize + Layout::spacingSm();
snprintf(buf, sizeof(buf), "%d txs", recvCount);
snprintf(buf, sizeof(buf), TR("txs_count"), recvCount);
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, cy), OnSurfaceDisabled(), buf);
cy += capFont->LegacySize + Layout::spacingXs();
@@ -221,10 +227,10 @@ void RenderTransactionsTab(App* app)
DrawTxIcon(dl, "send", cx + iconSz, cy + iconSz * 1.33f, iconSz, redCol);
float labelX = cx + iconSz * 3.0f;
dl->AddText(ovFont, ovFont->LegacySize, ImVec2(labelX, cy), OnSurfaceMedium(), "SENT");
dl->AddText(ovFont, ovFont->LegacySize, ImVec2(labelX, cy), OnSurfaceMedium(), TR("sent_upper"));
cy += ovFont->LegacySize + Layout::spacingSm();
snprintf(buf, sizeof(buf), "%d txs", sendCount);
snprintf(buf, sizeof(buf), TR("txs_count"), sendCount);
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, cy), OnSurfaceDisabled(), buf);
cy += capFont->LegacySize + Layout::spacingXs();
@@ -251,10 +257,10 @@ void RenderTransactionsTab(App* app)
DrawTxIcon(dl, "mined", cx + iconSz, cy + iconSz * 1.33f, iconSz, goldCol);
float labelX = cx + iconSz * 3.0f;
dl->AddText(ovFont, ovFont->LegacySize, ImVec2(labelX, cy), OnSurfaceMedium(), "MINED");
dl->AddText(ovFont, ovFont->LegacySize, ImVec2(labelX, cy), OnSurfaceMedium(), TR("mined_upper"));
cy += ovFont->LegacySize + Layout::spacingSm();
snprintf(buf, sizeof(buf), "%d txs", minedCount);
snprintf(buf, sizeof(buf), TR("txs_count"), minedCount);
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, cy), OnSurfaceDisabled(), buf);
cy += capFont->LegacySize + Layout::spacingXs();
@@ -292,23 +298,23 @@ void RenderTransactionsTab(App* app)
ImGui::SetNextItemWidth(searchWidth);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, Layout::spacingSm());
ImGui::InputTextWithHint("##TxSearch", "Search...", search_filter, sizeof(search_filter));
ImGui::InputTextWithHint("##TxSearch", TR("search_placeholder"), search_filter, sizeof(search_filter));
ImGui::PopStyleVar();
float filterGap = std::max(8.0f, ((filterGapEl.size > 0) ? filterGapEl.size : 20.0f) * hs);
ImGui::SameLine(0, filterGap);
float comboW = std::max(80.0f, ((filterCombo.width > 0) ? filterCombo.width : 120.0f) * hs);
ImGui::SetNextItemWidth(comboW);
const char* types[] = { "All", "Sent", "Received", "Mined" };
const char* types[] = { TR("all_filter"), TR("sent_filter"), TR("received_filter"), TR("mined_filter") };
ImGui::Combo("##TxType", &type_filter, types, IM_ARRAYSIZE(types));
ImGui::SameLine(0, filterGap);
if (TactileButton("Refresh", ImVec2(0, 0), S.resolveFont("button"))) {
if (TactileButton(TrId("refresh", "tx").c_str(), ImVec2(0, 0), S.resolveFont("button"))) {
app->refreshNow();
}
ImGui::SameLine(0, filterGap);
if (TactileButton("Export CSV", ImVec2(0, 0), S.resolveFont("button"))) {
if (TactileButton(TrId("export_csv", "tx").c_str(), ImVec2(0, 0), S.resolveFont("button"))) {
ExportTransactionsDialog::show();
}
@@ -442,7 +448,7 @@ void RenderTransactionsTab(App* app)
// ---- Heading line: "TRANSACTIONS" left, pagination right ----
{
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "TRANSACTIONS");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("transactions_upper"));
if (totalPages > 1) {
float paginationH = ImGui::GetFrameHeight();
@@ -557,13 +563,13 @@ void RenderTransactionsTab(App* app)
{
if (!app->isConnected()) {
ImGui::Dummy(ImVec2(0, 20));
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), " Not connected to daemon...");
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), TR("not_connected"));
} else if (state.transactions.empty()) {
ImGui::Dummy(ImVec2(0, 20));
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), " No transactions found");
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), TR("no_transactions"));
} else if (filtered_indices.empty()) {
ImGui::Dummy(ImVec2(0, 20));
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), " No matching transactions");
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), TR("no_matching"));
} else {
float rowH = body2->LegacySize + capFont->LegacySize + Layout::spacingLg() + Layout::spacingMd();
float innerW = ImGui::GetContentRegionAvail().x;
@@ -592,15 +598,15 @@ void RenderTransactionsTab(App* app)
ImU32 iconCol;
const char* typeStr;
if (tx.display_type == "shield") {
iconCol = Primary(); typeStr = "Shielded";
iconCol = Primary(); typeStr = TR("shielded_type");
} else if (tx.display_type == "receive") {
iconCol = greenCol; typeStr = "Recv";
iconCol = greenCol; typeStr = TR("recv_type");
} else if (tx.display_type == "send") {
iconCol = redCol; typeStr = "Sent";
iconCol = redCol; typeStr = TR("sent_type");
} else if (tx.display_type == "immature") {
iconCol = Warning(); typeStr = "Immature";
iconCol = Warning(); typeStr = TR("immature_type");
} else {
iconCol = goldCol; typeStr = "Mined";
iconCol = goldCol; typeStr = TR("mined_type");
}
// Expanded selection accent
@@ -669,14 +675,14 @@ void RenderTransactionsTab(App* app)
const char* statusStr;
ImU32 statusCol;
if (tx.confirmations == 0) {
statusStr = "Pending"; statusCol = Warning();
statusStr = TR("pending"); statusCol = Warning();
} else if (tx.confirmations < 10) {
snprintf(buf, sizeof(buf), "%d conf", tx.confirmations);
snprintf(buf, sizeof(buf), TR("conf_count"), tx.confirmations);
statusStr = buf; statusCol = Warning();
} else if (tx.confirmations >= 100 && (tx.display_type == "generate" || tx.display_type == "mined")) {
statusStr = "Mature"; statusCol = greenCol;
statusStr = TR("mature"); statusCol = greenCol;
} else {
statusStr = "Confirmed"; statusCol = WithAlpha(Success(), 140);
statusStr = TR("confirmed"); statusCol = WithAlpha(Success(), 140);
}
// Position status badge in the middle-right area
ImVec2 sSz = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0, statusStr);
@@ -707,14 +713,14 @@ void RenderTransactionsTab(App* app)
// Context menu
const auto& acrylicTheme = GetCurrentAcrylicTheme();
if (effects::ImGuiAcrylic::BeginAcrylicContextItem("TxContext", 0, acrylicTheme.menu)) {
if (ImGui::MenuItem("Copy Address") && !tx.address.empty()) {
if (ImGui::MenuItem(TR("copy_address")) && !tx.address.empty()) {
ImGui::SetClipboardText(tx.address.c_str());
}
if (ImGui::MenuItem("Copy TxID")) {
if (ImGui::MenuItem(TR("copy_txid"))) {
ImGui::SetClipboardText(tx.txid.c_str());
}
ImGui::Separator();
if (ImGui::MenuItem("View on Explorer")) {
if (ImGui::MenuItem(TR("view_on_explorer"))) {
std::string url = app->settings()->getTxExplorerUrl() + tx.txid;
#ifdef _WIN32
ShellExecuteA(nullptr, "open", url.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
@@ -726,7 +732,7 @@ void RenderTransactionsTab(App* app)
system(cmd.c_str());
#endif
}
if (ImGui::MenuItem("View Details")) {
if (ImGui::MenuItem(TR("view_details"))) {
if (tx.orig_idx >= 0 && tx.orig_idx < (int)state.transactions.size())
TransactionDetailsDialog::show(state.transactions[tx.orig_idx]);
}
@@ -747,19 +753,19 @@ void RenderTransactionsTab(App* app)
// From address
if (!tx.from_address.empty()) {
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "FROM");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("from_upper"));
ImGui::TextWrapped("%s", tx.from_address.c_str());
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
}
// To address
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(),
tx.display_type == "send" ? "TO" : (tx.display_type == "shield" ? "SHIELDED TO" : "ADDRESS"));
tx.display_type == "send" ? TR("to_upper") : (tx.display_type == "shield" ? TR("shielded_to") : TR("address_upper")));
ImGui::TextWrapped("%s", tx.address.c_str());
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
// TxID (full, copyable)
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "TRANSACTION ID");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("transaction_id"));
ImGui::TextWrapped("%s", tx.txid.c_str());
if (ImGui::IsItemHovered()) ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
if (ImGui::IsItemClicked()) ImGui::SetClipboardText(tx.txid.c_str());
@@ -767,13 +773,13 @@ void RenderTransactionsTab(App* app)
// Memo
if (!tx.memo.empty()) {
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), "MEMO");
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("memo_upper"));
ImGui::TextWrapped("%s", tx.memo.c_str());
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
}
// Confirmations + time
snprintf(buf, sizeof(buf), "%d confirmations | %s",
snprintf(buf, sizeof(buf), TR("confirmations_display"),
tx.confirmations, tx.getTimeString().c_str());
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), buf);
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
@@ -782,15 +788,15 @@ void RenderTransactionsTab(App* app)
ImGui::PushStyleColor(ImGuiCol_Button, ImGui::ColorConvertU32ToFloat4(IM_COL32(255, 255, 255, 15)));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::ColorConvertU32ToFloat4(IM_COL32(255, 255, 255, 30)));
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, schema::UI().drawElement("tabs.transactions", "detail-btn-rounding").size);
if (TactileSmallButton("Copy TxID##detail", S.resolveFont("button"))) {
if (TactileSmallButton(TrId("copy_txid", "detail").c_str(), S.resolveFont("button"))) {
ImGui::SetClipboardText(tx.txid.c_str());
}
ImGui::SameLine();
if (!tx.address.empty() && TactileSmallButton("Copy Address##detail", S.resolveFont("button"))) {
if (!tx.address.empty() && TactileSmallButton(TrId("copy_address", "detail").c_str(), S.resolveFont("button"))) {
ImGui::SetClipboardText(tx.address.c_str());
}
ImGui::SameLine();
if (TactileSmallButton("Explorer##detail", S.resolveFont("button"))) {
if (TactileSmallButton(TrId("explorer", "detail").c_str(), S.resolveFont("button"))) {
std::string url = app->settings()->getTxExplorerUrl() + tx.txid;
#ifdef _WIN32
ShellExecuteA(nullptr, "open", url.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
@@ -803,7 +809,7 @@ void RenderTransactionsTab(App* app)
#endif
}
ImGui::SameLine();
if (TactileSmallButton("Full Details##detail", S.resolveFont("button"))) {
if (TactileSmallButton(TrId("full_details", "detail").c_str(), S.resolveFont("button"))) {
if (tx.orig_idx >= 0 && tx.orig_idx < (int)state.transactions.size())
TransactionDetailsDialog::show(state.transactions[tx.orig_idx]);
}
@@ -849,7 +855,7 @@ void RenderTransactionsTab(App* app)
}
// Status line with page info
snprintf(buf, sizeof(buf), "Showing %d\xe2\x80\x93%d of %d transactions (total: %zu)",
snprintf(buf, sizeof(buf), TR("showing_transactions"),
filtered_count > 0 ? pageStart + 1 : 0, pageEnd, filtered_count, state.transactions.size());
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), buf);
}
+19 -18
View File
@@ -6,6 +6,7 @@
#include "../../app.h"
#include "../../rpc/rpc_client.h"
#include "../../rpc/rpc_worker.h"
#include "../../util/i18n.h"
#include "../schema/ui_schema.h"
#include "../material/draw_helpers.h"
#include "../theme.h"
@@ -52,15 +53,15 @@ void ValidateAddressDialog::render(App* app)
auto lbl = S.label("dialogs.validate-address", "label");
auto closeBtn = S.button("dialogs.validate-address", "close-button");
if (material::BeginOverlayDialog("Validate Address", &s_open, win.width, 0.94f)) {
ImGui::TextWrapped("Enter a DragonX address to check if it's valid and whether it belongs to this wallet.");
if (material::BeginOverlayDialog(TR("validate_title"), &s_open, win.width, 0.94f)) {
ImGui::TextWrapped("%s", TR("validate_description"));
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
// Address input
ImGui::Text("Address:");
ImGui::Text("%s", TR("address_label"));
ImGui::SetNextItemWidth(-1);
bool enter_pressed = ImGui::InputText("##ValidateAddr", s_address_input, sizeof(s_address_input),
ImGuiInputTextFlags_EnterReturnsTrue);
@@ -74,7 +75,7 @@ void ValidateAddressDialog::render(App* app)
ImGui::BeginDisabled();
}
if (material::StyledButton("Validate", ImVec2(valBtn.width, 0), S.resolveFont(valBtn.font)) || (enter_pressed && can_validate)) {
if (material::StyledButton(TR("validate_btn"), ImVec2(valBtn.width, 0), S.resolveFont(valBtn.font)) || (enter_pressed && can_validate)) {
s_validating = true;
s_validated = false;
s_error_message.clear();
@@ -100,7 +101,7 @@ void ValidateAddressDialog::render(App* app)
if (error.empty()) {
s_is_valid = valid;
s_is_mine = mine;
s_address_type = "Shielded (z-address)";
s_address_type = TR("validate_shielded_type");
} else {
s_error_message = error;
s_is_valid = false;
@@ -126,7 +127,7 @@ void ValidateAddressDialog::render(App* app)
if (error.empty()) {
s_is_valid = valid;
s_is_mine = mine;
s_address_type = "Transparent (t-address)";
s_address_type = TR("validate_transparent_type");
} else {
s_error_message = error;
s_is_valid = false;
@@ -145,7 +146,7 @@ void ValidateAddressDialog::render(App* app)
ImGui::SameLine();
if (material::StyledButton("Paste", ImVec2(pasteBtn.width, 0), S.resolveFont(pasteBtn.font))) {
if (material::StyledButton(TR("paste"), ImVec2(pasteBtn.width, 0), S.resolveFont(pasteBtn.font))) {
const char* clipboard = ImGui::GetClipboardText();
if (clipboard) {
strncpy(s_address_input, clipboard, sizeof(s_address_input) - 1);
@@ -156,7 +157,7 @@ void ValidateAddressDialog::render(App* app)
if (s_validating) {
ImGui::SameLine();
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "Validating...");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "%s", TR("validating"));
}
ImGui::Spacing();
@@ -165,39 +166,39 @@ void ValidateAddressDialog::render(App* app)
// Results
if (s_validated) {
ImGui::Text("Results:");
ImGui::Text("%s", TR("validate_results"));
ImGui::Spacing();
if (!s_error_message.empty()) {
ImGui::TextColored(ImVec4(1.0f, 0.3f, 0.3f, 1.0f), "Error: %s", s_error_message.c_str());
} else {
// Valid/Invalid indicator
ImGui::Text("Status:");
ImGui::Text("%s", TR("validate_status"));
ImGui::SameLine(lbl.position);
if (s_is_valid) {
ImGui::TextColored(ImVec4(0.3f, 0.8f, 0.3f, 1.0f), "VALID");
ImGui::TextColored(ImVec4(0.3f, 0.8f, 0.3f, 1.0f), "%s", TR("validate_valid"));
} else {
ImGui::TextColored(ImVec4(1.0f, 0.3f, 0.3f, 1.0f), "INVALID");
ImGui::TextColored(ImVec4(1.0f, 0.3f, 0.3f, 1.0f), "%s", TR("validate_invalid"));
}
if (s_is_valid) {
// Address type
ImGui::Text("Type:");
ImGui::Text("%s", TR("validate_type"));
ImGui::SameLine(lbl.position);
ImGui::Text("%s", s_address_type.c_str());
// Is mine?
ImGui::Text("Ownership:");
ImGui::Text("%s", TR("validate_ownership"));
ImGui::SameLine(lbl.position);
if (s_is_mine) {
ImGui::TextColored(ImVec4(0.3f, 0.8f, 0.3f, 1.0f), "This wallet owns this address");
ImGui::TextColored(ImVec4(0.3f, 0.8f, 0.3f, 1.0f), "%s", TR("validate_is_mine"));
} else {
ImGui::TextDisabled("Not owned by this wallet");
ImGui::TextDisabled("%s", TR("validate_not_mine"));
}
}
}
} else if (!app->isConnected()) {
ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.0f, 1.0f), "Not connected to daemon");
ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.0f, 1.0f), "%s", TR("not_connected"));
}
ImGui::Spacing();
@@ -205,7 +206,7 @@ void ValidateAddressDialog::render(App* app)
// Close button at bottom
float button_width = closeBtn.width;
ImGui::SetCursorPosX((ImGui::GetWindowWidth() - button_width) / 2.0f);
if (material::StyledButton("Close", ImVec2(button_width, 0), S.resolveFont(closeBtn.font))) {
if (material::StyledButton(TR("close"), ImVec2(button_width, 0), S.resolveFont(closeBtn.font))) {
s_open = false;
}
material::EndOverlayDialog();
+778 -18
View File
@@ -3,6 +3,7 @@
// Released under the GPLv3
#include "i18n.h"
#include "platform.h"
#include <fstream>
#include <cstdio>
@@ -28,15 +29,17 @@ using json = nlohmann::json;
I18n::I18n()
{
// Register built-in languages
// CJK glyphs are provided by the merged NotoSansCJK-Subset fallback font.
// Cyrillic glyphs are included in the Ubuntu font glyph ranges.
registerLanguage("en", "English");
registerLanguage("es", "Español");
registerLanguage("zh", "中文");
registerLanguage("ru", "Русский");
registerLanguage("zh", "Chinese");
registerLanguage("ru", "Russian");
registerLanguage("de", "Deutsch");
registerLanguage("fr", "Français");
registerLanguage("pt", "Português");
registerLanguage("ja", "日本語");
registerLanguage("ko", "한국어");
registerLanguage("ja", "Japanese");
registerLanguage("ko", "Korean");
// Load default English strings (built-in fallback)
loadLanguage("en");
@@ -50,16 +53,25 @@ I18n& I18n::instance()
bool I18n::loadLanguage(const std::string& locale)
{
// First, try to load from file (allows user overrides)
std::string lang_file = "res/lang/" + locale + ".json";
std::ifstream file(lang_file);
// Try to load from file: CWD-relative first, then exe-relative
std::string rel_path = "res/lang/" + locale + ".json";
std::string exe_path = Platform::getExecutableDirectory() + "/" + rel_path;
// Try both paths; prefer whichever opens successfully
for (const auto& lang_file : { rel_path, exe_path }) {
std::ifstream file(lang_file);
if (!file.is_open()) continue;
if (file.is_open()) {
try {
json j;
file >> j;
// Load English built-in as fallback base for non-English
if (locale != "en") {
loadBuiltinEnglish();
} else {
strings_.clear();
}
for (auto& [key, value] : j.items()) {
if (value.is_string()) {
strings_[key] = value.get<std::string>();
@@ -110,7 +122,12 @@ bool I18n::loadLanguage(const std::string& locale)
std::string json_str(reinterpret_cast<const char*>(embedded_data), embedded_size);
json j = json::parse(json_str);
// Load English built-in as fallback base for non-English
if (locale != "en") {
loadBuiltinEnglish();
} else {
strings_.clear();
}
for (auto& [key, value] : j.items()) {
if (value.is_string()) {
strings_[key] = value.get<std::string>();
@@ -128,17 +145,323 @@ bool I18n::loadLanguage(const std::string& locale)
// If English, use built-in strings
if (locale == "en") {
loadBuiltinEnglish();
current_locale_ = "en";
return true;
}
return false;
}
void I18n::loadBuiltinEnglish()
{
strings_.clear();
// Navigation & Tabs
strings_["overview"] = "Overview";
strings_["balance"] = "Balance";
strings_["send"] = "Send";
strings_["receive"] = "Receive";
strings_["transactions"] = "Transactions";
strings_["history"] = "History";
strings_["mining"] = "Mining";
strings_["peers"] = "Peers";
strings_["market"] = "Market";
strings_["settings"] = "Settings";
strings_["console"] = "Console";
strings_["tools"] = "TOOLS";
strings_["advanced"] = "ADVANCED";
// Settings sections
strings_["appearance"] = "APPEARANCE";
strings_["wallet"] = "WALLET";
strings_["node_security"] = "NODE & SECURITY";
strings_["node"] = "NODE";
strings_["security"] = "SECURITY";
strings_["explorer"] = "EXPLORER";
strings_["about"] = "About";
strings_["backup_data"] = "BACKUP & DATA";
strings_["balance_layout"] = "Balance Layout";
strings_["low_spec_mode"] = "Low-spec mode";
strings_["simple_background"] = "Simple background";
strings_["console_scanline"] = "Console scanline";
strings_["theme_effects"] = "Theme effects";
strings_["acrylic"] = "Acrylic";
strings_["noise"] = "Noise";
strings_["ui_opacity"] = "UI Opacity";
strings_["window_opacity"] = "Window Opacity";
strings_["font_scale"] = "Font Scale";
strings_["refresh"] = "Refresh";
strings_["website"] = "Website";
strings_["report_bug"] = "Report Bug";
strings_["save_settings"] = "Save Settings";
strings_["reset_to_defaults"] = "Reset to Defaults";
// Wallet settings
strings_["save_z_transactions"] = "Save shielded tx history";
strings_["auto_shield"] = "Auto-shield";
strings_["use_tor"] = "Use Tor";
strings_["keep_daemon"] = "Keep daemon running";
strings_["stop_external"] = "Stop external daemon";
strings_["verbose_logging"] = "Verbose logging";
strings_["mine_when_idle"] = "Mine when idle";
strings_["setup_wizard"] = "Run Setup Wizard...";
// RPC / Explorer settings
strings_["rpc_host"] = "Host";
strings_["rpc_port"] = "Port";
strings_["rpc_user"] = "Username";
strings_["rpc_pass"] = "Password";
strings_["transaction_url"] = "Transaction URL";
strings_["address_url"] = "Address URL";
strings_["custom_fees"] = "Allow custom transaction fees";
strings_["fetch_prices"] = "Fetch price data from CoinGecko";
strings_["block_explorer"] = "Block Explorer";
strings_["test_connection"] = "Test Connection";
strings_["rescan"] = "Rescan Blockchain";
// Settings: buttons
strings_["settings_address_book"] = "Address Book...";
strings_["settings_validate_address"] = "Validate Address...";
strings_["settings_request_payment"] = "Request Payment...";
strings_["settings_shield_mining"] = "Shield Mining...";
strings_["settings_merge_to_address"] = "Merge to Address...";
strings_["settings_clear_ztx"] = "Clear Z-Tx History";
strings_["settings_import_key"] = "Import Key...";
strings_["settings_export_key"] = "Export Key...";
strings_["settings_export_all"] = "Export All...";
strings_["settings_backup"] = "Backup...";
strings_["settings_export_csv"] = "Export CSV...";
strings_["settings_encrypt_wallet"] = "Encrypt Wallet";
strings_["settings_change_passphrase"] = "Change Passphrase";
strings_["settings_lock_now"] = "Lock Now";
strings_["settings_remove_encryption"] = "Remove Encryption";
strings_["settings_set_pin"] = "Set PIN";
strings_["settings_change_pin"] = "Change PIN";
strings_["settings_remove_pin"] = "Remove PIN";
strings_["settings_restart_daemon"] = "Restart daemon";
strings_["clear_anyway"] = "Clear Anyway";
// Settings: labels / text
strings_["settings_builtin"] = "Built-in";
strings_["settings_custom"] = "Custom";
strings_["settings_not_found"] = "Not found";
strings_["settings_idle_after"] = "after";
strings_["settings_not_encrypted"] = "Not encrypted";
strings_["settings_locked"] = "Locked";
strings_["settings_unlocked"] = "Unlocked";
strings_["settings_quick_unlock_pin"] = "Quick-unlock PIN";
strings_["settings_pin_active"] = "PIN";
strings_["settings_encrypt_first_pin"] = "Encrypt wallet first to enable PIN";
strings_["settings_data_dir"] = "Data Dir:";
strings_["settings_wallet_size_label"] = "Wallet Size:";
strings_["settings_debug_changed"] = "Debug categories changed \xe2\x80\x94 restart daemon to apply";
strings_["settings_auto_detected"] = "Auto-detected from DRAGONX.conf";
strings_["settings_visual_effects"] = "Visual Effects";
strings_["settings_acrylic_level"] = "Acrylic Level:";
strings_["settings_noise_opacity"] = "Noise Opacity:";
strings_["settings_privacy"] = "Privacy";
strings_["settings_other"] = "Other";
strings_["settings_rpc_connection"] = "RPC Connection";
strings_["settings_configure_rpc"] = "Configure connection to dragonxd daemon";
strings_["settings_wallet_maintenance"] = "Wallet Maintenance";
strings_["settings_wallet_info"] = "Wallet Info";
strings_["settings_block_explorer_urls"] = "Block Explorer URLs";
strings_["settings_configure_explorer"] = "Configure external block explorer links";
strings_["settings_auto_lock"] = "AUTO-LOCK";
strings_["settings_wallet_file_size"] = "Wallet file size: %s";
strings_["settings_wallet_location"] = "Wallet location: %s";
strings_["settings_rpc_note"] = "Note: Connection settings are usually auto-detected from DRAGONX.conf";
strings_["settings_explorer_hint"] = "URLs should include a trailing slash. The txid/address will be appended.";
strings_["settings_connection"] = "Connection";
strings_["settings_reduce_transparency"] = "Reduce transparency";
strings_["settings_save_shielded_local"] = "Save shielded transaction history locally";
strings_["settings_auto_shield_funds"] = "Auto-shield transparent funds";
strings_["settings_use_tor_network"] = "Use Tor for network connections";
strings_["settings_gradient_bg"] = "Gradient bg";
// Settings: tooltips
strings_["tt_theme_hotkey"] = "Hotkey: Ctrl+Left/Right to cycle themes";
strings_["tt_layout_hotkey"] = "Hotkey: Left/Right arrow keys to cycle Balance layouts";
strings_["tt_language"] = "Interface language for the wallet UI";
strings_["tt_scan_themes"] = "Scan for new themes.\nPlace theme folders in:\n%s";
strings_["tt_low_spec"] = "Disable all heavy visual effects\nHotkey: Ctrl+Shift+Down";
strings_["tt_simple_bg"] = "Use a simple gradient for the background\nHotkey: Ctrl+Up";
strings_["tt_simple_bg_alt"] = "Use a gradient version of the theme background image\nHotkey: Ctrl+Up";
strings_["tt_scanline"] = "CRT scanline effect in console";
strings_["tt_theme_effects"] = "Shimmer, glow, hue-cycling per theme";
strings_["tt_blur"] = "Blur amount (0%% = off, 100%% = maximum)";
strings_["tt_noise"] = "Grain texture intensity (0%% = off, 100%% = maximum)";
strings_["tt_ui_opacity"] = "Card and sidebar opacity (100%% = fully opaque, lower = more see-through)";
strings_["tt_window_opacity"] = "Background opacity (lower = desktop visible through window)";
strings_["tt_font_scale"] = "Scale all text and UI (1.0x = default, up to 1.5x).";
strings_["tt_custom_theme"] = "Custom theme active";
strings_["tt_address_book"] = "Manage saved addresses for quick sending";
strings_["tt_validate"] = "Check if a DragonX address is valid";
strings_["tt_request_payment"] = "Generate a payment request with QR code";
strings_["tt_shield_mining"] = "Move transparent mining rewards to a shielded address";
strings_["tt_merge"] = "Consolidate multiple UTXOs into one address";
strings_["tt_clear_ztx"] = "Delete locally cached z-transaction history";
strings_["tt_save_ztx"] = "Store z-address transaction history locally for faster loading";
strings_["tt_auto_shield"] = "Automatically move transparent balance to shielded addresses for privacy";
strings_["tt_tor"] = "Route daemon connections through the Tor network for anonymity";
strings_["tt_keep_daemon"] = "Daemon will still stop when running the setup wizard";
strings_["tt_stop_external"] = "Applies when connecting to a daemon\nyou started outside this wallet";
strings_["tt_verbose"] = "Log detailed connection diagnostics,\ndaemon state, and port owner info\nto the Console tab";
strings_["tt_mine_idle"] = "Automatically start mining when the\nsystem is idle (no keyboard/mouse input)";
strings_["tt_idle_delay"] = "How long to wait before starting mining";
strings_["tt_wizard"] = "Re-run the initial setup wizard\nDaemon will be restarted";
strings_["tt_open_dir"] = "Click to open in file explorer";
strings_["tt_rpc_host"] = "Hostname of the DragonX daemon";
strings_["tt_rpc_user"] = "RPC authentication username";
strings_["tt_rpc_port"] = "Port for daemon RPC connections";
strings_["tt_rpc_pass"] = "RPC authentication password";
strings_["tt_test_conn"] = "Verify the RPC connection to the daemon";
strings_["tt_rescan"] = "Rescan the blockchain for missing transactions";
strings_["tt_encrypt"] = "Encrypt wallet.dat with a passphrase";
strings_["tt_change_pass"] = "Change the wallet encryption passphrase";
strings_["tt_lock"] = "Lock the wallet immediately";
strings_["tt_remove_encrypt"] = "Remove encryption and store wallet unprotected";
strings_["tt_auto_lock"] = "Lock wallet after this much inactivity";
strings_["tt_set_pin"] = "Set a 4-8 digit PIN for quick unlock";
strings_["tt_change_pin"] = "Change your unlock PIN";
strings_["tt_remove_pin"] = "Remove PIN and require passphrase to unlock";
strings_["tt_tx_url"] = "Base URL for viewing transactions in a block explorer";
strings_["tt_addr_url"] = "Base URL for viewing addresses in a block explorer";
strings_["tt_custom_fees"] = "Enable manual fee entry when sending transactions";
strings_["tt_fetch_prices"] = "Retrieve DRGX market prices from CoinGecko API";
strings_["tt_block_explorer"] = "Open the DragonX block explorer in your browser";
strings_["tt_website"] = "Open the DragonX website";
strings_["tt_report_bug"] = "Report an issue on the project tracker";
strings_["tt_save_settings"] = "Save all settings to disk";
strings_["tt_reset_settings"] = "Reload settings from disk (undo unsaved changes)";
strings_["tt_debug_collapse"] = "Collapse debug logging options";
strings_["tt_debug_expand"] = "Expand debug logging options";
strings_["tt_restart_daemon"] = "Restart the daemon to apply debug logging changes";
// Settings: additional tooltips (keys/data row)
strings_["tt_import_key"] = "Import a private key (zkey or tkey) into this wallet";
strings_["tt_export_key"] = "Export the private key for the selected address";
strings_["tt_export_all"] = "Export all private keys to a file";
strings_["tt_backup"] = "Create a backup of your wallet.dat file";
strings_["tt_export_csv"] = "Export transaction history as a CSV spreadsheet";
// Settings: about / debug
strings_["settings_about_text"] = "A shielded cryptocurrency wallet for DragonX (DRGX), built with Dear ImGui for a lightweight, portable experience.";
strings_["settings_copyright"] = "Copyright 2024-2026 DragonX Developers | GPLv3 License";
strings_["debug_logging"] = "DEBUG LOGGING";
strings_["settings_debug_select"] = "Select categories to enable daemon debug logging (-debug= flags).";
strings_["settings_debug_restart_note"] = "Changes take effect after restarting the daemon.";
// Settings window (legacy dialog) descriptions
strings_["settings_language_note"] = "Note: Some text requires restart to update";
strings_["settings_solid_colors_desc"] = "Use solid colors instead of blur effects (accessibility)";
strings_["settings_gradient_desc"] = "Replace textured backgrounds with smooth gradients";
strings_["settings_save_shielded_desc"] = "Stores z-addr transactions in a local file for viewing";
strings_["settings_auto_shield_desc"] = "Automatically move transparent funds to shielded addresses";
strings_["settings_tor_desc"] = "Route all connections through Tor for enhanced privacy";
strings_["settings_rescan_desc"] = "Rescan blockchain for missing transactions";
strings_["settings_clear_ztx_long"] = "Clear Saved Z-Transaction History";
strings_["settings_clear_ztx_desc"] = "Delete locally stored shielded transaction data";
strings_["settings_wallet_not_found"] = "Wallet file not found";
// Balance tab: address actions
strings_["hide_zero_balances"] = "Hide 0 Balances";
strings_["restore_address"] = "Restore Address";
strings_["hide_address"] = "Hide Address";
strings_["remove_favorite"] = "Remove Favorite";
strings_["favorite_address"] = "Favorite Address";
strings_["show_hidden"] = "Show Hidden (%d)";
// Misc dialog strings
strings_["shield_operation_id"] = "Operation ID: %s";
strings_["peers_peer_label"] = "Peer: %s";
strings_["key_export_click_retrieve"] = "Click to retrieve the key from your wallet";
strings_["backup_source"] = "Source: %s";
strings_["export_keys_progress"] = "Exporting %d/%d...";
strings_["import_key_progress"] = "Importing %d/%d...";
strings_["block_click_copy"] = "Click to copy";
strings_["confirm_clear_ztx_title"] = "Confirm Clear Z-Tx History";
strings_["confirm_clear_ztx_warning1"] = "Clearing z-transaction history may cause your shielded balance to show as 0 until a wallet rescan is performed.";
strings_["confirm_clear_ztx_warning2"] = "If this happens, you will need to re-import your z-address private keys with rescan enabled to recover your balance.";
// Send tab
strings_["sending_from"] = "SENDING FROM";
strings_["recent_sends"] = "RECENT SENDS";
strings_["recipient"] = "RECIPIENT";
strings_["memo_optional"] = "MEMO (OPTIONAL)";
strings_["no_recent_sends"] = "No recent sends";
strings_["network_fee"] = "NETWORK FEE";
strings_["amount_details"] = "AMOUNT DETAILS";
strings_["not_connected_to_daemon"] = "Not connected to daemon";
strings_["select_source_address"] = "Select a source address...";
strings_["no_addresses_with_balance"] = "No addresses with balance";
strings_["blockchain_syncing"] = "Blockchain syncing (%.1f%%)... Balances may be inaccurate.";
strings_["wallet_empty"] = "Your wallet is empty";
strings_["wallet_empty_hint"] = "Switch to Receive to get your address and start receiving funds.";
strings_["go_to_receive"] = "Go to Receive";
strings_["review_send"] = "Review Send";
strings_["fee_low"] = "Low";
strings_["fee_normal"] = "Normal";
strings_["fee_high"] = "High";
strings_["submitting_transaction"] = "Submitting transaction...";
strings_["transaction_sent_msg"] = "Transaction sent!";
strings_["copy_error"] = "Copy Error";
strings_["dismiss"] = "Dismiss";
strings_["clear_form_confirm"] = "Clear all form fields?";
strings_["yes_clear"] = "Yes, Clear";
strings_["keep"] = "Keep";
strings_["undo_clear"] = "Undo Clear";
// Receive tab
strings_["recent_received"] = "RECENT RECEIVED";
strings_["payment_request"] = "PAYMENT REQUEST";
strings_["copy"] = "Copy";
strings_["new"] = "+ New";
strings_["share"] = "Share";
strings_["select_receiving_address"] = "Select a receiving address...";
strings_["no_addresses_match"] = "No addresses match filter";
strings_["no_recent_receives"] = "No recent receives";
strings_["waiting_for_daemon"] = "Waiting for daemon connection...";
strings_["addresses_appear_here"] = "Your receiving addresses will appear here once connected.";
strings_["loading_addresses"] = "Loading addresses...";
strings_["clear_request"] = "Clear Request";
strings_["copy_uri"] = "Copy URI";
strings_["qr_unavailable"] = "QR unavailable";
strings_["received_label"] = "Received";
// Transactions tab
strings_["no_transactions"] = "No transactions found";
strings_["no_matching"] = "No matching transactions";
strings_["transaction_id"] = "TRANSACTION ID";
strings_["search_placeholder"] = "Search...";
strings_["all_filter"] = "All";
strings_["sent_filter"] = "Sent";
strings_["received_filter"] = "Received";
strings_["mined_filter"] = "Mined";
strings_["export_csv"] = "Export CSV";
strings_["transactions_upper"] = "TRANSACTIONS";
strings_["received_upper"] = "RECEIVED";
strings_["sent_upper"] = "SENT";
strings_["mined_upper"] = "MINED";
strings_["from_upper"] = "FROM";
strings_["to_upper"] = "TO";
strings_["shielded_to"] = "SHIELDED TO";
strings_["address_upper"] = "ADDRESS";
strings_["memo_upper"] = "MEMO";
strings_["shielded_type"] = "Shielded";
strings_["recv_type"] = "Recv";
strings_["sent_type"] = "Sent";
strings_["immature_type"] = "Immature";
strings_["mined_type"] = "Mined";
strings_["mature"] = "Mature";
strings_["copy_txid"] = "Copy TxID";
strings_["view_details"] = "View Details";
strings_["full_details"] = "Full Details";
strings_["showing_transactions"] = "Showing %d\xe2\x80\x93%d of %d transactions (total: %zu)";
strings_["txs_count"] = "%d txs";
strings_["conf_count"] = "%d conf";
strings_["confirmations_display"] = "%d confirmations | %s";
// Balance Tab
strings_["summary"] = "Summary";
@@ -281,17 +604,454 @@ bool I18n::loadLanguage(const std::string& locale)
strings_["amount_exceeds_balance"] = "Amount exceeds balance";
strings_["transaction_sent"] = "Transaction sent successfully";
current_locale_ = "en";
DEBUG_LOGF("Using built-in English strings (%zu strings)\n", strings_.size());
return true;
}
// --- Common / Shared ---
strings_["add"] = "Add";
strings_["address_copied"] = "Address copied to clipboard";
strings_["address_label"] = "Address:";
strings_["amount_label"] = "Amount:";
strings_["date_label"] = "Date:";
strings_["delete"] = "Delete";
strings_["fee_label"] = "Fee:";
strings_["file_save_location"] = "File will be saved in: ~/.config/ObsidianDragon/";
strings_["hide"] = "Hide";
strings_["label"] = "Label:";
strings_["loading"] = "Loading...";
strings_["memo_label"] = "Memo:";
strings_["notes"] = "Notes";
strings_["notes_optional"] = "Notes (optional):";
strings_["output_filename"] = "Output filename:";
strings_["paste_from_clipboard"] = "Paste from Clipboard";
strings_["show"] = "Show";
strings_["time_days_ago"] = "%d days ago";
strings_["time_hours_ago"] = "%d hours ago";
strings_["time_minutes_ago"] = "%d minutes ago";
strings_["time_seconds_ago"] = "%d seconds ago";
strings_["unknown"] = "Unknown";
strings_["validating"] = "Validating...";
strings_["warning_upper"] = "WARNING!";
// Fallback: reload English so we never leave stale strings
DEBUG_LOGF("Language file not found: %s — falling back to English\n", lang_file.c_str());
if (locale != "en") {
loadLanguage("en");
}
return false;
// --- About Dialog ---
strings_["about_block_explorer"] = "Block Explorer";
strings_["about_block_height"] = "Block Height:";
strings_["about_build_date"] = "Build Date:";
strings_["about_build_type"] = "Build Type:";
strings_["about_chain"] = "Chain:";
strings_["about_connections"] = "Connections:";
strings_["about_credits"] = "Credits";
strings_["about_daemon"] = "Daemon:";
strings_["about_debug"] = "Debug";
strings_["about_edition"] = "ImGui Edition";
strings_["about_github"] = "GitHub";
strings_["about_imgui"] = "ImGui:";
strings_["about_license"] = "License";
strings_["about_license_text"] = "This software is released under the GNU General Public License v3 (GPLv3). You are free to use, modify, and distribute this software under the terms of the license.";
strings_["about_peers_count"] = "%zu peers";
strings_["about_release"] = "Release";
strings_["about_title"] = "About ObsidianDragon";
strings_["about_version"] = "Version:";
strings_["about_website"] = "Website";
// --- Address Book Dialog ---
strings_["address_book_add"] = "Add Address";
strings_["address_book_add_new"] = "Add New";
strings_["address_book_added"] = "Address added to book";
strings_["address_book_count"] = "%zu addresses saved";
strings_["address_book_deleted"] = "Entry deleted";
strings_["address_book_edit"] = "Edit Address";
strings_["address_book_empty"] = "No saved addresses. Click 'Add New' to add one.";
strings_["address_book_exists"] = "Address already exists in book";
strings_["address_book_title"] = "Address Book";
strings_["address_book_update_failed"] = "Failed to update - address may be duplicate";
strings_["address_book_updated"] = "Address updated";
// --- Backup Dialog ---
strings_["backup_backing_up"] = "Backing up...";
strings_["backup_create"] = "Create Backup";
strings_["backup_created"] = "Wallet backup created";
strings_["backup_description"] = "Create a backup of your wallet.dat file. This file contains all your private keys and transaction history. Store the backup in a secure location.";
strings_["backup_destination"] = "Backup destination:";
strings_["backup_tip_external"] = "Store backups on external drives or cloud storage";
strings_["backup_tip_multiple"] = "Create multiple backups in different locations";
strings_["backup_tip_test"] = "Test restoring from backup periodically";
strings_["backup_tips"] = "Tips:";
strings_["backup_title"] = "Backup Wallet";
strings_["backup_wallet_not_found"] = "Warning: wallet.dat not found at expected location";
// --- Block Info Dialog ---
strings_["block_bits"] = "Bits:";
strings_["block_click_next"] = "Click to view next block";
strings_["block_click_prev"] = "Click to view previous block";
strings_["block_get_info"] = "Get Block Info";
strings_["block_hash"] = "Block Hash:";
strings_["block_height"] = "Block Height:";
strings_["block_info_title"] = "Block Information";
strings_["block_merkle_root"] = "Merkle Root:";
strings_["block_nav_next"] = "Next >>";
strings_["block_nav_prev"] = "<< Previous";
strings_["block_next"] = "Next Block:";
strings_["block_previous"] = "Previous Block:";
strings_["block_size"] = "Size:";
strings_["block_timestamp"] = "Timestamp:";
strings_["block_transactions"] = "Transactions:";
// --- Console Tab ---
strings_["console_auto_scroll"] = "Auto-scroll";
strings_["console_available_commands"] = "Available commands:";
strings_["console_capturing_output"] = "Capturing daemon output...";
strings_["console_clear"] = "Clear";
strings_["console_clear_console"] = "Clear Console";
strings_["console_cleared"] = "Console cleared";
strings_["console_click_commands"] = "Click commands above to insert them";
strings_["console_click_insert"] = "Click to insert";
strings_["console_click_insert_params"] = "Click to insert with parameters";
strings_["console_close"] = "Close";
strings_["console_commands"] = "Commands";
strings_["console_common_rpc"] = "Common RPC commands:";
strings_["console_completions"] = "Completions:";
strings_["console_connected"] = "Connected to daemon";
strings_["console_copy_all"] = "Copy All";
strings_["console_copy_selected"] = "Copy";
strings_["console_daemon"] = "Daemon";
strings_["console_daemon_error"] = "Daemon error!";
strings_["console_daemon_started"] = "Daemon started";
strings_["console_daemon_stopped"] = "Daemon stopped";
strings_["console_disconnected"] = "Disconnected from daemon";
strings_["console_errors"] = "Errors";
strings_["console_filter_hint"] = "Filter output...";
strings_["console_help_clear"] = " clear - Clear the console";
strings_["console_help_getbalance"] = " getbalance - Show transparent balance";
strings_["console_help_getblockcount"] = " getblockcount - Show current block height";
strings_["console_help_getinfo"] = " getinfo - Show node information";
strings_["console_help_getmininginfo"] = " getmininginfo - Show mining status";
strings_["console_help_getpeerinfo"] = " getpeerinfo - Show connected peers";
strings_["console_help_gettotalbalance"] = " gettotalbalance - Show total balance";
strings_["console_help_help"] = " help - Show this help message";
strings_["console_help_setgenerate"] = " setgenerate - Control mining";
strings_["console_help_stop"] = " stop - Stop the daemon";
strings_["console_line_count"] = "%zu lines";
strings_["console_new_lines"] = "%d new lines";
strings_["console_no_daemon"] = "No daemon";
strings_["console_not_connected"] = "Error: Not connected to daemon";
strings_["console_rpc_reference"] = "RPC Command Reference";
strings_["console_search_commands"] = "Search commands...";
strings_["console_select_all"] = "Select All";
strings_["console_show_daemon_output"] = "Show daemon output";
strings_["console_show_errors_only"] = "Show errors only";
strings_["console_show_rpc_ref"] = "Show RPC command reference";
strings_["console_showing_lines"] = "Showing %zu of %zu lines";
strings_["console_starting_node"] = "Starting node...";
strings_["console_status_error"] = "Error";
strings_["console_status_running"] = "Running";
strings_["console_status_starting"] = "Starting";
strings_["console_status_stopped"] = "Stopped";
strings_["console_status_stopping"] = "Stopping";
strings_["console_status_unknown"] = "Unknown";
strings_["console_tab_completion"] = "Tab for completion";
strings_["console_type_help"] = "Type 'help' for available commands";
strings_["console_welcome"] = "Welcome to ObsidianDragon Console";
strings_["console_zoom_in"] = "Zoom in";
strings_["console_zoom_out"] = "Zoom out";
// --- Export All Keys Dialog ---
strings_["export_keys_btn"] = "Export Keys";
strings_["export_keys_danger"] = "DANGER: This will export ALL private keys from your wallet! Anyone with access to this file can steal your funds. Store it securely and delete after use.";
strings_["export_keys_include_t"] = "Include T-addresses (transparent)";
strings_["export_keys_include_z"] = "Include Z-addresses (shielded)";
strings_["export_keys_options"] = "Export options:";
strings_["export_keys_success"] = "Keys exported successfully";
strings_["export_keys_title"] = "Export All Private Keys";
// --- Export Transactions Dialog ---
strings_["export_tx_count"] = "Export %zu transactions to CSV file.";
strings_["export_tx_file_fail"] = "Failed to create CSV file";
strings_["export_tx_none"] = "No transactions to export";
strings_["export_tx_success"] = "Transactions exported successfully";
strings_["export_tx_title"] = "Export Transactions to CSV";
// --- Import Key Dialog ---
strings_["import_key_btn"] = "Import Key(s)";
strings_["import_key_formats"] = "Supported key formats:";
strings_["import_key_full_rescan"] = "(0 = full rescan)";
strings_["import_key_label"] = "Private Key(s):";
strings_["import_key_no_valid"] = "No valid keys found in input";
strings_["import_key_rescan"] = "Rescan blockchain after import";
strings_["import_key_start_height"] = "Start height:";
strings_["import_key_success"] = "Keys imported successfully";
strings_["import_key_t_format"] = "T-address WIF private keys";
strings_["import_key_title"] = "Import Private Key";
strings_["import_key_tooltip"] = "Enter one or more private keys, one per line.\nSupports both z-address and t-address keys.\nLines starting with # are treated as comments.";
strings_["import_key_warning"] = "Warning: Never share your private keys! Importing keys from untrusted sources can compromise your wallet.";
strings_["import_key_z_format"] = "Z-address spending keys (secret-extended-key-...)";
// --- Key Export Dialog ---
strings_["key_export_fetching"] = "Fetching key from wallet...";
strings_["key_export_private_key"] = "Private Key:";
strings_["key_export_private_warning"] = "Keep this key SECRET! Anyone with this key can spend your funds. Never share it online or with untrusted parties.";
strings_["key_export_reveal"] = "Reveal Key";
strings_["key_export_viewing_key"] = "Viewing Key:";
strings_["key_export_viewing_warning"] = "This viewing key allows others to see your incoming transactions and balance, but NOT spend your funds. Share only with trusted parties.";
// --- Market Tab ---
strings_["market_12h"] = "12h";
strings_["market_18h"] = "18h";
strings_["market_24h"] = "24h";
strings_["market_24h_volume"] = "24H VOLUME";
strings_["market_6h"] = "6h";
strings_["market_attribution"] = "Price data from NonKYC";
strings_["market_btc_price"] = "BTC PRICE";
strings_["market_no_history"] = "No price history available";
strings_["market_no_price"] = "No price data";
strings_["market_now"] = "Now";
strings_["market_pct_shielded"] = "%.0f%% Shielded";
strings_["market_portfolio"] = "PORTFOLIO";
strings_["market_price_unavailable"] = "Price data unavailable";
strings_["market_refresh_price"] = "Refresh price data";
strings_["market_trade_on"] = "Trade on %s";
// --- Mining Tab ---
strings_["mining_active"] = "Active";
strings_["mining_address_copied"] = "Mining address copied";
strings_["mining_all_time"] = "All Time";
strings_["mining_already_saved"] = "Pool URL already saved";
strings_["mining_block_copied"] = "Block hash copied";
strings_["mining_chart_1m_ago"] = "1m ago";
strings_["mining_chart_5m_ago"] = "5m ago";
strings_["mining_chart_now"] = "Now";
strings_["mining_chart_start"] = "Start";
strings_["mining_click"] = "Click";
strings_["mining_click_copy_address"] = "Click to copy address";
strings_["mining_click_copy_block"] = "Click to copy block hash";
strings_["mining_click_copy_difficulty"] = "Click to copy difficulty";
strings_["mining_connected"] = "Connected";
strings_["mining_connecting"] = "Connecting...";
strings_["mining_difficulty_copied"] = "Difficulty copied";
strings_["mining_est_block"] = "Est. Block";
strings_["mining_est_daily"] = "Est. Daily";
strings_["mining_filter_all"] = "All";
strings_["mining_filter_tip_all"] = "Show all earnings";
strings_["mining_filter_tip_pool"] = "Show pool earnings only";
strings_["mining_filter_tip_solo"] = "Show solo earnings only";
strings_["mining_idle_off_tooltip"] = "Enable idle mining";
strings_["mining_idle_on_tooltip"] = "Disable idle mining";
strings_["mining_local_hashrate"] = "Local Hashrate";
strings_["mining_mine"] = "Mine";
strings_["mining_mining_addr"] = "Mining Addr";
strings_["mining_network"] = "Network";
strings_["mining_no_blocks_yet"] = "No blocks found yet";
strings_["mining_no_payouts_yet"] = "No pool payouts yet";
strings_["mining_no_saved_addresses"] = "No saved addresses";
strings_["mining_no_saved_pools"] = "No saved pools";
strings_["mining_open_in_explorer"] = "Open in explorer";
strings_["mining_payout_address"] = "Payout Address";
strings_["mining_payout_tooltip"] = "Address to receive mining rewards";
strings_["mining_pool"] = "Pool";
strings_["mining_pool_hashrate"] = "Pool Hashrate";
strings_["mining_pool_url"] = "Pool URL";
strings_["mining_recent_blocks"] = "RECENT BLOCKS";
strings_["mining_recent_payouts"] = "RECENT POOL PAYOUTS";
strings_["mining_remove"] = "Remove";
strings_["mining_reset_defaults"] = "Reset Defaults";
strings_["mining_save_payout_address"] = "Save payout address";
strings_["mining_save_pool_url"] = "Save pool URL";
strings_["mining_saved_addresses"] = "Saved Addresses:";
strings_["mining_saved_pools"] = "Saved Pools:";
strings_["mining_shares"] = "Shares";
strings_["mining_show_chart"] = "Chart";
strings_["mining_show_log"] = "Log";
strings_["mining_solo"] = "Solo";
strings_["mining_starting"] = "Starting...";
strings_["mining_starting_tooltip"] = "Miner is starting...";
strings_["mining_stop"] = "Stop";
strings_["mining_stop_solo_for_pool"] = "Stop solo mining before starting pool mining";
strings_["mining_stop_solo_for_pool_settings"] = "Stop solo mining to change pool settings";
strings_["mining_stopping"] = "Stopping...";
strings_["mining_stopping_tooltip"] = "Miner is stopping...";
strings_["mining_syncing_tooltip"] = "Blockchain is syncing...";
strings_["mining_to_save"] = "to save";
strings_["mining_today"] = "Today";
strings_["mining_uptime"] = "Uptime";
strings_["mining_yesterday"] = "Yesterday";
// --- Peers Tab ---
strings_["peers_avg_ping"] = "Avg Ping";
strings_["peers_ban_24h"] = "Ban Peer 24h";
strings_["peers_ban_score"] = "Ban Score: %d";
strings_["peers_banned"] = "Banned";
strings_["peers_banned_count"] = "Banned: %d";
strings_["peers_best_block"] = "Best Block";
strings_["peers_blockchain"] = "BLOCKCHAIN";
strings_["peers_blocks"] = "Blocks";
strings_["peers_blocks_left"] = "%d blocks left";
strings_["peers_clear_all_bans"] = "Clear All Bans";
strings_["peers_click_copy"] = "Click to copy";
strings_["peers_connected"] = "Connected";
strings_["peers_connected_count"] = "Connected: %d";
strings_["peers_copy_ip"] = "Copy IP";
strings_["peers_dir_in"] = "In";
strings_["peers_dir_out"] = "Out";
strings_["peers_hash_copied"] = "Hash copied";
strings_["peers_hashrate"] = "Hashrate";
strings_["peers_in_out"] = "In/Out";
strings_["peers_longest"] = "Longest";
strings_["peers_longest_chain"] = "Longest Chain";
strings_["peers_memory"] = "Memory";
strings_["peers_no_banned"] = "No banned peers";
strings_["peers_no_connected"] = "No connected peers";
strings_["peers_no_tls"] = "No TLS";
strings_["peers_notarized"] = "Notarized";
strings_["peers_p2p_port"] = "P2P Port";
strings_["peers_protocol"] = "Protocol";
strings_["peers_received"] = "Received";
strings_["peers_refresh"] = "Refresh";
strings_["peers_refresh_tooltip"] = "Refresh peer list";
strings_["peers_refreshing"] = "Refreshing...";
strings_["peers_sent"] = "Sent";
strings_["peers_tt_id"] = "ID: %d";
strings_["peers_tt_received"] = "Received: %s";
strings_["peers_tt_sent"] = "Sent: %s";
strings_["peers_tt_services"] = "Services: %s";
strings_["peers_tt_start_height"] = "Start Height: %d";
strings_["peers_tt_synced"] = "Synced H/B: %d/%d";
strings_["peers_tt_tls_cipher"] = "TLS: %s";
strings_["peers_unban"] = "Unban";
strings_["peers_upper"] = "PEERS";
strings_["peers_version"] = "Version";
// --- QR Popup Dialog ---
strings_["qr_failed"] = "Failed to generate QR code";
strings_["qr_title"] = "QR Code";
// --- Receive Tab ---
strings_["click_copy_address"] = "Click to copy address";
strings_["click_copy_uri"] = "Click to copy URI";
strings_["failed_create_shielded"] = "Failed to create shielded address";
strings_["failed_create_transparent"] = "Failed to create transparent address";
strings_["new_shielded_created"] = "New shielded address created";
strings_["new_transparent_created"] = "New transparent address created";
strings_["payment_request_copied"] = "Payment request copied";
strings_["payment_uri_copied"] = "Payment URI copied";
// --- Request Payment Dialog ---
strings_["request_amount"] = "Amount (optional):";
strings_["request_copy_uri"] = "Copy URI";
strings_["request_description"] = "Generate a payment request that others can scan or copy. The QR code contains your address and optional amount/memo.";
strings_["request_label"] = "Label (optional):";
strings_["request_memo"] = "Memo (optional):";
strings_["request_payment_uri"] = "Payment URI:";
strings_["request_receive_address"] = "Receive Address:";
strings_["request_select_address"] = "Select address...";
strings_["request_shielded_addrs"] = "-- Shielded Addresses --";
strings_["request_title"] = "Request Payment";
strings_["request_transparent_addrs"] = "-- Transparent Addresses --";
strings_["request_uri_copied"] = "Payment URI copied to clipboard";
// --- Send Tab ---
strings_["send_amount"] = "Amount";
strings_["send_amount_details"] = "AMOUNT DETAILS";
strings_["send_amount_upper"] = "AMOUNT";
strings_["send_clear_fields"] = "Clear all form fields?";
strings_["send_copy_error"] = "Copy Error";
strings_["send_dismiss"] = "Dismiss";
strings_["send_error_copied"] = "Error copied to clipboard";
strings_["send_error_prefix"] = "Error: %s";
strings_["send_exceeds_available"] = "Exceeds available (%.8f)";
strings_["send_fee"] = "Fee";
strings_["send_fee_high"] = "High";
strings_["send_fee_low"] = "Low";
strings_["send_fee_normal"] = "Normal";
strings_["send_form_restored"] = "Form restored";
strings_["send_go_to_receive"] = "Go to Receive";
strings_["send_keep"] = "Keep";
strings_["send_network_fee"] = "NETWORK FEE";
strings_["send_no_balance"] = "No balance";
strings_["send_no_recent"] = "No recent sends";
strings_["send_recent_sends"] = "RECENT SENDS";
strings_["send_recipient"] = "RECIPIENT";
strings_["send_select_source"] = "Select a source address...";
strings_["send_sending_from"] = "SENDING FROM";
strings_["send_submitting"] = "Submitting transaction...";
strings_["send_switch_to_receive"] = "Switch to Receive to get your address and start receiving funds.";
strings_["send_tooltip_enter_amount"] = "Enter an amount to send";
strings_["send_tooltip_exceeds_balance"] = "Amount exceeds available balance";
strings_["send_tooltip_in_progress"] = "Transaction already in progress";
strings_["send_tooltip_invalid_address"] = "Enter a valid recipient address";
strings_["send_tooltip_not_connected"] = "Not connected to daemon";
strings_["send_tooltip_select_source"] = "Select a source address first";
strings_["send_tooltip_syncing"] = "Wait for blockchain to sync";
strings_["send_total"] = "Total";
strings_["send_tx_failed"] = "Transaction failed";
strings_["send_tx_sent"] = "Transaction sent!";
strings_["send_tx_success"] = "Transaction sent successfully!";
strings_["send_txid_copied"] = "TxID copied to clipboard";
strings_["send_txid_label"] = "TxID: %s";
strings_["send_valid_shielded"] = "Valid shielded address";
strings_["send_valid_transparent"] = "Valid transparent address";
strings_["send_wallet_empty"] = "Your wallet is empty";
strings_["send_yes_clear"] = "Yes, Clear";
// --- Shield Dialog ---
strings_["shield_check_status"] = "Check Status";
strings_["shield_completed"] = "Operation completed successfully!";
strings_["shield_description"] = "Shield your mining rewards by sending coinbase outputs from transparent addresses to a shielded address. This improves privacy by hiding your mining income.";
strings_["shield_from_address"] = "From Address:";
strings_["shield_funds"] = "Shield Funds";
strings_["shield_in_progress"] = "Operation in progress...";
strings_["shield_max_utxos"] = "Max UTXOs per operation";
strings_["shield_merge_done"] = "Shield/merge completed!";
strings_["shield_select_z"] = "Select z-address...";
strings_["shield_started"] = "Shield operation started";
strings_["shield_title"] = "Shield Coinbase Rewards";
strings_["shield_to_address"] = "To Address (Shielded):";
strings_["shield_utxo_limit"] = "UTXO Limit:";
strings_["shield_wildcard_hint"] = "Use '*' to shield from all transparent addresses";
strings_["merge_description"] = "Merge multiple UTXOs into a single shielded address. This can help reduce wallet size and improve privacy.";
strings_["merge_funds"] = "Merge Funds";
strings_["merge_started"] = "Merge operation started";
strings_["merge_title"] = "Merge to Address";
// --- Transaction Details Dialog ---
strings_["tx_confirmations"] = "%d confirmations";
strings_["tx_details_title"] = "Transaction Details";
strings_["tx_from_address"] = "From Address:";
strings_["tx_id_label"] = "Transaction ID:";
strings_["tx_immature"] = "IMMATURE";
strings_["tx_mined"] = "MINED";
strings_["tx_received"] = "RECEIVED";
strings_["tx_sent"] = "SENT";
strings_["tx_to_address"] = "To Address:";
strings_["tx_view_explorer"] = "View on Explorer";
// --- Validate Address Dialog ---
strings_["validate_btn"] = "Validate";
strings_["validate_description"] = "Enter a DragonX address to check if it's valid and whether it belongs to this wallet.";
strings_["validate_invalid"] = "INVALID";
strings_["validate_is_mine"] = "This wallet owns this address";
strings_["validate_not_mine"] = "Not owned by this wallet";
strings_["validate_ownership"] = "Ownership:";
strings_["validate_results"] = "Results:";
strings_["validate_shielded_type"] = "Shielded (z-address)";
strings_["validate_status"] = "Status:";
strings_["validate_title"] = "Validate Address";
strings_["validate_transparent_type"] = "Transparent (t-address)";
strings_["validate_type"] = "Type:";
strings_["validate_valid"] = "VALID";
// Misc dialog/tab strings
strings_["ram_wallet_gb"] = "Wallet: %.1f GB";
strings_["ram_wallet_mb"] = "Wallet: %.0f MB";
strings_["ram_daemon_gb"] = "Daemon: %.1f GB (%s)";
strings_["ram_daemon_mb"] = "Daemon: %.0f MB (%s)";
strings_["ram_system_gb"] = "System: %.1f / %.0f GB";
strings_["shield_operation_id"] = "Operation ID: %s";
strings_["peers_peer_label"] = "Peer: %s";
strings_["error_format"] = "Error: %s";
strings_["key_export_click_retrieve"] = "Click to retrieve the key from your wallet";
strings_["key_export_viewing_keys_zonly"] = "Viewing keys are only available for shielded (z) addresses";
strings_["backup_source"] = "Source: %s";
strings_["export_keys_progress"] = "Exporting %d/%d...";
strings_["import_key_progress"] = "Importing %d/%d...";
strings_["click_to_copy"] = "Click to copy";
strings_["block_hash_copied"] = "Block hash copied";
}
const char* I18n::translate(const char* key) const
+1
View File
@@ -57,6 +57,7 @@ public:
private:
I18n();
void loadBuiltinEnglish();
std::string current_locale_ = "en";
std::unordered_map<std::string, std::string> strings_;