From b91b17789f848408e9a73723b73fe46a75ad9631 Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 4 Feb 2026 22:22:01 +0100 Subject: [PATCH 01/10] Update README with predefined OpenAI Compatible API configurations Added predefined OpenAI Compatible API configurations for various APIs. --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 95d1828f..d4b22e06 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,12 @@ Using an API integration, you can activate some automatic features: > - **OpenAI Compatible API** > - You can also use a local OpenAI Compatible API server, like LM Studio or Mistral AI! > - There is also an option to remove the "v1" segment from the API url, if needed, and to manually set the model name if the server doesn't have a models list endpoint. +> - You can also use one of these predefined configurations: +> - DeepSeek API +> - Grok API +> - Mistral API +> - OpenRouter API +> - Perpelxity API From ab3739521e52f8c140b414e3444bfa3c9b327d69 Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 4 Feb 2026 23:08:08 +0100 Subject: [PATCH 02/10] Fix typo in Perplexity API name --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d4b22e06..617a96ee 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Using an API integration, you can activate some automatic features: > - Grok API > - Mistral API > - OpenRouter API -> - Perpelxity API +> - Perplexity API From 32aa24c88d5a9f418894ba0b5ef7f9440d33b0b9 Mon Sep 17 00:00:00 2001 From: Mic Date: Tue, 10 Feb 2026 18:27:40 +0100 Subject: [PATCH 03/10] saving the selection when selected and not when the user clicks the button to prevent recent changes in the ChatGPT web interface. see #646 --- js/mzta-chatgpt.js | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/js/mzta-chatgpt.js b/js/mzta-chatgpt.js index eeda649e..e64d5eb8 100644 --- a/js/mzta-chatgpt.js +++ b/js/mzta-chatgpt.js @@ -30,6 +30,7 @@ let current_mailMessageId = null; let selectionChangeTimeout = null; let isDragging = false; let delay_wait_completion = 7000; // milliseconds +let lastSelectedHtml = ""; async function chatgpt_sendMsg(msg, method ='') { // return -1 send button not found, -2 textarea not found let textArea = document.getElementById('prompt-textarea') @@ -205,6 +206,10 @@ function addCustomDiv(prompt_action,tabId,mailMessageId) { var btn_ok = document.createElement('button'); btn_ok.id="mzta-btn_ok"; btn_ok.classList.add('mzta-btn'); + // Prevent the button from stealing focus and clearing the selection + btn_ok.addEventListener('mousedown', function(e) { + e.preventDefault(); + }); //console.log('>>>>>>>>>>>>>>> default: '+prompt_action) switch(String(prompt_action)){ default: @@ -247,6 +252,10 @@ function addCustomDiv(prompt_action,tabId,mailMessageId) { var btn_change_reply_type = document.createElement('button'); disableButton(btn_change_reply_type); btn_change_reply_type.id = 'mzta-btn_change_reply_type'; + // Prevent the button from stealing focus and clearing the selection + btn_change_reply_type.addEventListener('mousedown', function(e) { + e.preventDefault(); + }); btn_change_reply_type.classList.add('mzta-btn'); btn_change_reply_type.title = browser.i18n.getMessage("chatgpt_win_change_reply_type"); // Create SVG element @@ -320,6 +329,10 @@ function addCustomDiv(prompt_action,tabId,mailMessageId) { var btn_diff = document.createElement('button'); btn_diff.id='mzta-btn_diff'; btn_diff.classList.add('mzta-btn'); + // Prevent the button from stealing focus and clearing the selection + btn_diff.addEventListener('mousedown', function(e) { + e.preventDefault(); + }); btn_diff.textContent = browser.i18n.getMessage('btn_show_differences'); btn_diff.style.display = 'none'; disableButton(btn_diff); @@ -672,7 +685,7 @@ function replaceNewlinesWithBr(node) { function getSelectedHtml() { // Get the Selection object var selection = window.getSelection(); - + // console.log(">>>>>>>>>>>>> getSelectedHtml selection.rangeCount: " + selection.rangeCount); if (selection.rangeCount > 0) { // Get the first selected range var range = selection.getRangeAt(0); @@ -682,10 +695,14 @@ function getSelectedHtml() { // Clone the contents of the range into the temporary div tempDiv.appendChild(range.cloneContents()); - + // console.log(">>>>>>>>>>>>>>>>>> tempDiv.innerHTML: " + tempDiv.innerHTML); // Return the HTML of the selected content return tempDiv.innerHTML.replace(/^

"/, '

').replace(/"<\\/p>$/, '

'); // strip quotation marks; } + if (lastSelectedHtml) { + // console.log(">>>>>>>>>>>>> getSelectedHtml using cached selection lastSelectedHtml: "+ lastSelectedHtml); + return lastSelectedHtml; + } return ""; } @@ -708,6 +725,14 @@ document.addEventListener("selectionchange", function() { let btn_ok = document.getElementById('mzta-btn_ok'); let btn_diff = document.getElementById('mzta-btn_diff'); if (isSomethingSelected()) { + // Cache the selection + var selection = window.getSelection(); + if (selection.rangeCount > 0) { + var range = selection.getRangeAt(0); + var tempDiv = document.createElement("div"); + tempDiv.appendChild(range.cloneContents()); + lastSelectedHtml = tempDiv.innerHTML.replace(/^

"/, '

').replace(/"<\\/p>$/, '

'); + } enableButton(btn_ok); if(current_action == '1'){ let btn_reply_type = document.getElementById('mzta-btn_change_reply_type'); @@ -756,7 +781,8 @@ function selectContentOnMouseUp(event) { // If the click was inside the excluded area, do nothing return; } - + // console.log(">>>>>>>>>>>>> selectContentOnMouseUp isDragging: " + isDragging); + // Reset the dragging flag when the mouse is released") if ((!isDragging)&&(!isSomethingSelected())) { // If no dragging has occurred, execute the selection code selectContentOnClick(event); @@ -781,6 +807,8 @@ function selectContentOnClick(event) { // Traverse the DOM upwards to find the nearest parent div var parentDiv = clickedElement.closest('div'); + // console.log(">>>>>>>>>>>>> parentDiv: " + parentDiv.classList); + if (parentDiv) { // Create a range object var range = document.createRange(); @@ -796,6 +824,7 @@ function selectContentOnClick(event) { // Add the new range to the selection selection.addRange(range); + // console.log(">>>>>>>>>>>>> selectContentOnClick selection.rangeCount: " + selection.rangeCount); } } From e4e356de0db9163fb4e21ff0ecabfc96f90b330d Mon Sep 17 00:00:00 2001 From: Mic Date: Tue, 10 Feb 2026 18:28:17 +0100 Subject: [PATCH 04/10] version set to 3.8.4 and release notes updated --- CHANGELOG.md | 4 ++++ manifest.json | 2 +- options/mzta-release-notes.html | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31d24e43..bdfdc8c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ +

Version 3.8.4 - 10/02/2026

+
    +
  • [ChatGPT Web] Fix: Correctly importing the selected text into the compose windows also when ChatGPT shows the advanced mail editor in the response [#646].
  • +

Version 3.8.3 - 22/01/2026

  • Fix: Correctly saving the API settings in new custom prompts [#623].
  • diff --git a/manifest.json b/manifest.json index c70f8713..5c77e980 100644 --- a/manifest.json +++ b/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "ThunderAI", "description": "__MSG_extensionDescription__", - "version": "3.8.3", + "version": "3.8.4", "author": "Mic (m@micz.it)", "homepage_url": "https://micz.it/thunderbird-addon-thunderai/", "browser_specific_settings": { diff --git a/options/mzta-release-notes.html b/options/mzta-release-notes.html index c87ef83c..33f60cf8 100644 --- a/options/mzta-release-notes.html +++ b/options/mzta-release-notes.html @@ -7,6 +7,10 @@

    ThunderAI Release Notes

    +

    Version 3.8.4 - 10/02/2026

    +
      +
    • [ChatGPT Web] Fix: Correctly importing the selected text into the compose windows also when ChatGPT shows the advanced mail editor in the response [#646].
    • +

    Version 3.8.3 - 22/01/2026

    • Fix: Correctly saving the API settings in new custom prompts [#623].
    • From edd22529a25f00deeedbc7f7594e9ffe4bcad13f Mon Sep 17 00:00:00 2001 From: Luna Jernberg Date: Wed, 11 Feb 2026 06:16:19 +0100 Subject: [PATCH 05/10] Modify Swedish contributors in README.md Updated Swedish translation contributors in README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 617a96ee..1d4382fd 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ Are you using this addon in your Thunderbird? - Português Brasileiro (pt-br): Bruno Pereira de Souza - Russian (ru): [Maksim](https://hosted.weblate.org/user/law820314/) - Spanish (es): [Gerardo Sobarzo](https://hosted.weblate.org/user/gerardo.sobarzo/), [Andrés Rendón Hernández](https://hosted.weblate.org/user/arendon/), [Erick Limon](https://hosted.weblate.org/user/ErickLimonG/) -- Swedish (sv): [Andreas Pettersson](https://hosted.weblate.org/user/Andy_tb/) +- Swedish (sv): [Andreas Pettersson](https://hosted.weblate.org/user/Andy_tb/) , [Luna Jernberg] (https://hosted.weblate.org/user/bittin1ddc447d824349b2/)
      Do you want to help translate this addon? [Find out how!](https://micz.it/thunderbird-addon-thunderai/translate/)
      From fc578c42a40c5acc8f11cf8e631a4195da333e2f Mon Sep 17 00:00:00 2001 From: bittin1ddc447d824349b2 Date: Wed, 11 Feb 2026 06:15:06 +0100 Subject: [PATCH 06/10] Translated using Weblate (Swedish) Currently translated at 100.0% (468 of 468 strings) Translation: ThunderAI for Thunderbird/main Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/ --- _locales/sv/messages.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/_locales/sv/messages.json b/_locales/sv/messages.json index 5ac1a1b6..158be7fe 100644 --- a/_locales/sv/messages.json +++ b/_locales/sv/messages.json @@ -1403,5 +1403,14 @@ }, "Valid": { "message": "Giltig" + }, + "prefs_OptionText_spamfilter_show_msg_panel": { + "message": "Visa panelen för skräppostrapportering" + }, + "prefs_OptionText_spamfilter_show_msg_panel_Info": { + "message": "Om markerat visas en panel med skräppostrapportering högst upp av meddelandet." + }, + "SpamReport_infoline": { + "message": "Denna information sparas endast för den aktuella sessionen." } } From 378395d324b2530d7def28694537bab3bf1517c7 Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 11 Feb 2026 21:19:48 +0100 Subject: [PATCH 07/10] Fix link formatting for Swedish translation entry --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 88815e8b..e4847667 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ Are you using this addon in your Thunderbird? - Português Brasileiro (pt-br): Bruno Pereira de Souza - Russian (ru): [Maksim](https://hosted.weblate.org/user/law820314/) - Spanish (es): [Gerardo Sobarzo](https://hosted.weblate.org/user/gerardo.sobarzo/), [Andrés Rendón Hernández](https://hosted.weblate.org/user/arendon/), [Erick Limon](https://hosted.weblate.org/user/ErickLimonG/) -- Swedish (sv): [Andreas Pettersson](https://hosted.weblate.org/user/Andy_tb/) , [Luna Jernberg] (https://hosted.weblate.org/user/bittin1ddc447d824349b2/) +- Swedish (sv): [Andreas Pettersson](https://hosted.weblate.org/user/Andy_tb/) , [Luna Jernberg](https://hosted.weblate.org/user/bittin1ddc447d824349b2/)
      Do you want to help translate this addon? [Find out how!](https://micz.it/thunderbird-addon-thunderai/translate/)
      From 5fcf21a5e974b87a347ca25592dfb569dfe7f0e4 Mon Sep 17 00:00:00 2001 From: mic Date: Wed, 11 Feb 2026 21:21:21 +0100 Subject: [PATCH 08/10] indentation fixed --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0dd20ac..dc8b453f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,7 @@
    • Added a button to copy a prompt in the Custom Prompts page [#598].
    • [All APIs] Showing the spam filter info at the top of the message. The data is saved only for the session in which the message has been checked for spam [#506].
    • ...
    • -
    +

Version 3.8.4 - 10/02/2026

  • [ChatGPT Web] Fix: Correctly importing the selected text into the compose windows also when ChatGPT shows the advanced mail editor in the response [#646].
  • From c764a1ee2f21cfd49727cb03f76ec14e0f51378a Mon Sep 17 00:00:00 2001 From: Andreas Pettersson Date: Wed, 11 Feb 2026 17:30:39 +0100 Subject: [PATCH 09/10] Translated using Weblate (Swedish) Currently translated at 100.0% (468 of 468 strings) Translation: ThunderAI for Thunderbird/main Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/ --- _locales/sv/messages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_locales/sv/messages.json b/_locales/sv/messages.json index 158be7fe..f447b3d8 100644 --- a/_locales/sv/messages.json +++ b/_locales/sv/messages.json @@ -1408,7 +1408,7 @@ "message": "Visa panelen för skräppostrapportering" }, "prefs_OptionText_spamfilter_show_msg_panel_Info": { - "message": "Om markerat visas en panel med skräppostrapportering högst upp av meddelandet." + "message": "Om markerat visas en panel med skräppostrapporten högst upp i meddelandet." }, "SpamReport_infoline": { "message": "Denna information sparas endast för den aktuella sessionen." From 73d1795dc75c4f8ece2f55af33470e4972ee9d82 Mon Sep 17 00:00:00 2001 From: Christos Kanotidis Date: Wed, 11 Feb 2026 21:15:20 +0100 Subject: [PATCH 10/10] Translated using Weblate (Greek) Currently translated at 100.0% (468 of 468 strings) Translation: ThunderAI for Thunderbird/main Translate-URL: https://hosted.weblate.org/projects/thunderai/main/el/ --- _locales/el/messages.json | 126 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/_locales/el/messages.json b/_locales/el/messages.json index c240bfd7..5f6e056f 100644 --- a/_locales/el/messages.json +++ b/_locales/el/messages.json @@ -1286,5 +1286,131 @@ }, "prefs_anthropic_temperature_Info": { "message": "Ποσότητα τυχαιότητας που εισάγεται στην απόκριση. Προεπιλογή 1,0. Εύρος από 0,0 έως 1,0. Χρησιμοποιήστε θερμοκρασία πιο κοντά στο 0,0 για αναλυτική ανάλυση." + }, + "placeholder_mail_text_body_or_selected": { + "message": "Σώμα μηνύματος ή επιλεγμένο κείμενο" + }, + "placeholder_mail_html_body_or_selected": { + "message": "Σώμα μηνύματος ή επιλεγμένη HTML" + }, + "prompt_get_calendar_event_from_clipboard": { + "message": "Προσθήκη συμβάντος ημερολογίου από το πρόχειρο" + }, + "clipboard_read_error": { + "message": "Δεν ήταν δυνατή η ανάγνωση του προχείρου. Ελέγξτε τα δικαιώματα." + }, + "clipboard_empty_error": { + "message": "Το πρόχειρο είναι άδειο. Παρακαλώ αντιγράψτε πρώτα κάποιο κείμενο." + }, + "clipboard_permission_denied": { + "message": "Η άδεια χρήσης του πρόχειρου απορρίφθηκε. Ενεργοποιήστε ξανά τη λειτουργία στις ρυθμίσεις για να παραχωρήσετε άδεια." + }, + "clipboard_permission_error": { + "message": "Σφάλμα κατά την αίτηση άδειας στο πρόχειρο. Δοκιμάστε ξανά." + }, + "prefs_OptionText_get_calendar_event_from_clipboard": { + "message": "Λήψη συμβάντος ημερολογίου από το πρόχειρο" + }, + "prefs_OptionText_get_calendar_event_from_clipboard_Info": { + "message": "Εμφάνιση ενός επιπλέον στοιχείου μενού για τη δημιουργία συμβάντων ημερολογίου από περιεχόμενο κειμένου στο πρόχειρο." + }, + "Summarize_prompt_prefs_title": { + "message": "Προσθήκη επιλογών σύνοψης" + }, + "prompt_summarize": { + "message": "Συνοψίστε αυτό το μήνυμα ηλεκτρονικού ταχυδρομείου ή αυτά τα μηνύματα ηλεκτρονικού ταχυδρομείου" + }, + "prompt_summarize_full_text": { + "message": "Είστε βοηθός που συνοψίζει συνομιλίες μέσω email. \nΔεδομένου ενός νήματος email, δημιουργήστε μια συνοπτική και ακριβή περίληψη που να καταγράφει: \n- Το κύριο θέμα ή τον σκοπό της συζήτησης \n- Βασικές αποφάσεις, συμπεράσματα ή συμφωνίες \n- Σημαντικές ερωτήσεις, αιτήματα ή ενέργειες \n- Ποιος είναι υπεύθυνος για κάθε ενέργεια (εάν αναφέρεται) \nΠαραλείψτε χαιρετισμούς, υπογραφές, παρατιθέμενο κείμενο και περιττές ανταλλαγές απόψεων. Μην προσθέτετε υποθέσεις ή πληροφορίες που δεν υπάρχουν στα email. \nΓράψτε την περίληψη σε σαφή, ουδέτερη γλώσσα, κατάλληλη για έναν πολυάσχολο επαγγελματία." + }, + "prompt_summarize_email_template": { + "message": "Σύνοψη προτύπου email" + }, + "prompt_summarize_email_template_full_text": { + "message": "Από: {%author%} \nΠρος: {%recipients%} \nΚοινοποίηση: {%cc_list%} \nΘέμα: {%mail_subject%} \nΗμερομηνία: {%mail_datetime%} \nΣυνημμένα: {%mail_attachments_info%} \nΚύριο κείμενο: \n{%mail_text_body%}" + }, + "prompt_summarize_email_separator": { + "message": "Διαχωριστής email" + }, + "prompt_summarize_email_separator_full_text": { + "message": "\n\n---------- ΕΠΟΜΕΝΟ EMAIL -----------\n\n" + }, + "prefs_OptionText_Summarize_infoline2": { + "message": "Μπορείτε να αλλάξετε την προτροπή όπως επιθυμείτε. Το πρώτο πεδίο είναι η κύρια προτροπή, το δεύτερο πεδίο είναι το πρότυπο για ένα μόνο μήνυμα ηλεκτρονικού ταχυδρομείου. Η λίστα των email θα προσαρτηθεί στην κύρια προτροπή. Τα email θα διαχωρίζονται με το διαχωριστικό που καθορίζεται στο τρίτο πεδίο." + }, + "prefs_OptionText_Summarize_main_prompt": { + "message": "Η κύρια προτροπή που περιγράφει την εργασία που θα εκτελεστεί σε όλα τα επιλεγμένα email:" + }, + "prefs_OptionText_Summarize_email_template": { + "message": "Το πρότυπο για ένα μόνο email:" + }, + "prefs_OptionText_Summarize_email_separator": { + "message": "Το διαχωριστικό μεταξύ των email:" + }, + "prefs_OptionText_get_calendar_event_use_specific_integration_Info": { + "message": "Εάν επιλεγεί, το μοντέλο και το API που καθορίζονται παρακάτω θα χρησιμοποιηθούν για τη δημιουργία συμβάντων ημερολογίου, ανεξάρτητα από αυτό που έχει επιλεγεί στη σελίδα επιλογών ThunderAI." + }, + "prefs_OptionText_summarize": { + "message": "Σύνοψη αλληλογραφίας" + }, + "prefs_OptionText_summarize_use_specific_integration_Info": { + "message": "Εάν επιλεγεί, το μοντέλο και το API που καθορίζονται παρακάτω θα χρησιμοποιηθούν για τη σύνοψη email(s), ανεξάρτητα από αυτό που έχει επιλεγεί στη σελίδα επιλογών ThunderAI." + }, + "prefs_OptionText_summarize_Info": { + "message": "Εάν είναι επιλεγμένο, προσθέτει μια επιλογή στο μενού περιβάλλοντος για τη σύνοψη της αλληλογραφίας." + }, + "prefs_OptionText_btnManageSummarizeInfo": { + "message": "Διαχείριση ρυθμίσεων σύνοψης" + }, + "Summarize_PageTitle": { + "message": "Διαχείριση ρυθμίσεων σύνοψης" + }, + "Summarize_info_default": { + "message": "Σε αυτήν τη σελίδα μπορείτε να τροποποιήσετε την προεπιλεγμένη προτροπή που χρησιμοποιείται για τη σύνοψη των μηνυμάτων ηλεκτρονικού ταχυδρομείου." + }, + "Summarize_prompt_text_title": { + "message": "Τρέχον κείμενο προτροπής" + }, + "prefs_OptionText_spamfilter_show_msg_panel": { + "message": "Εμφάνιση πλαισίου αναφοράς ανεπιθύμητων μηνυμάτων" + }, + "prefs_OptionText_spamfilter_show_msg_panel_Info": { + "message": "Εάν είναι επιλεγμένο, θα εμφανίζεται ένα πλαίσιο με την αναφορά ανεπιθύμητης αλληλογραφίας στο επάνω μέρος του μηνύματος." + }, + "SpamReport_infoline": { + "message": "Αυτές οι πληροφορίες αποθηκεύονται μόνο για την τρέχουσα συνεδρία." + }, + "Spam": { + "message": "Ανεπιθύμητα μηνύματα" + }, + "Valid": { + "message": "Έγκυρα Μηνύματα" + }, + "context_menu_mzta-summarize": { + "message": "Σύνοψη" + }, + "CORS_alternative_2_new": { + "message": "Πατήστε το παρακάτω κουμπί για να δώσετε άδεια στον τρέχοντα κεντρικό υπολογιστή να αποφύγει οποιοδήποτε πρόβλημα με το CORS." + }, + "CORS_give_host_perm": { + "message": "Δώστε άδεια στον τρέχοντα κεντρικό υπολογιστή" + }, + "CORS_localhost_warn": { + "message": "Εάν χρησιμοποιείτε localhost ή 127.0.0.1 επειδή ο διακομιστής AI φιλοξενείται στον υπολογιστή σας, απαιτείται το δικαίωμα ." + }, + "customPrompts_export_include_api_settings": { + "message": "Θέλετε να συμπεριλάβετε τις ρυθμίσεις API στην εξαγωγή; Λάβετε υπόψη ότι και το Κλειδί API θα αποθηκευτεί στο αρχείο!" + }, + "prefs_OptionText_calendar_no_selection": { + "message": "Μην ζητάτε να επιλέξετε κείμενο" + }, + "prefs_OptionText_calendar_no_selection_Info": { + "message": "Εάν είναι επιλεγμένο, δεν χρειάζεται να επιλέξετε κάποιο κείμενο. Το πλήρες σώμα του μηνύματος θα χρησιμοποιηθεί για τη λήψη του συμβάντος ημερολογίου." + }, + "customPrompts_btnCopy": { + "message": "Αντιγραφή" + }, + "copy_text": { + "message": "αντιγραφή" } }