From e97eff1f3198cb71f0de82c5208043d456d7cbd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20AYDINO=C4=9ELU?= Date: Sun, 20 Jul 2025 14:27:56 +0300 Subject: [PATCH 01/11] Added Turkish Language --- public/locales/de.json | 3 +- public/locales/en.json | 3 +- public/locales/es.json | 3 +- public/locales/ja.json | 3 +- public/locales/tr.json | 619 +++++++++++++++++++++++++++++++++++++++++ public/locales/zh.json | 3 +- 6 files changed, 629 insertions(+), 5 deletions(-) create mode 100644 public/locales/tr.json diff --git a/public/locales/de.json b/public/locales/de.json index 0742cc23..4b27e068 100644 --- a/public/locales/de.json +++ b/public/locales/de.json @@ -600,6 +600,7 @@ "es": "Spanisch", "ja": "Japanisch", "zh": "Chinesisch", - "de": "Deutsch" + "de": "Deutsch", + "tr": "Türkisch" } } diff --git a/public/locales/en.json b/public/locales/en.json index fe8d4ff8..e6b7ab34 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -613,6 +613,7 @@ "es": "Spanish", "ja": "Japanese", "zh": "Chinese", - "de": "German" + "de": "German", + "tr": "Turkish" } } diff --git a/public/locales/es.json b/public/locales/es.json index e83776b2..26e12b52 100644 --- a/public/locales/es.json +++ b/public/locales/es.json @@ -601,6 +601,7 @@ "es": "Español", "ja": "Japonés", "zh": "Chino", - "de": "Alemán" + "de": "Alemán", + "tr": "Turco" } } diff --git a/public/locales/ja.json b/public/locales/ja.json index ee42a837..3a2458d7 100644 --- a/public/locales/ja.json +++ b/public/locales/ja.json @@ -601,6 +601,7 @@ "es": "スペイン語", "ja": "日本語", "zh": "中国語", - "de": "ドイツ語" + "de": "ドイツ語", + "tr": "トルコ語" } } diff --git a/public/locales/tr.json b/public/locales/tr.json new file mode 100644 index 00000000..68c9613b --- /dev/null +++ b/public/locales/tr.json @@ -0,0 +1,619 @@ +{ + "login": { + "title": "Tekrar Hoş Geldiniz!", + "email": "İş E‑postası Girin", + "password": "Şifre", + "button": "Giriş Yap", + "loading": "Yükleniyor", + "register_prompt": "Hesabınız yok mu?", + "register_link": "Kaydol", + "welcome_notification": "Maxun’a Hoş Geldiniz!", + "validation": { + "required_fields": "E‑posta ve şifre zorunludur", + "password_length": "Şifre en az 6 karakter olmalıdır" + }, + "error": { + "user_not_found": "Kullanıcı mevcut değil", + "invalid_credentials": "Geçersiz e‑posta veya şifre", + "server_error": "Giriş başarısız. Lütfen daha sonra tekrar deneyin", + "generic": "Bir hata oluştu. Lütfen tekrar deneyin" + } + }, + "register": { + "title": "Hesap Oluştur", + "email": "İş E‑postası Girin", + "password": "Şifre", + "button": "Kaydol", + "loading": "Yükleniyor", + "register_prompt": "Zaten hesabınız var mı?", + "login_link": "Giriş Yap", + "welcome_notification": "Maxun’a Hoş Geldiniz!", + "validation": { + "email_required": "E‑posta zorunludur", + "password_requirements": "Şifre en az 6 karakter olmalıdır" + }, + "error": { + "user_exists": "Bu e‑posta ile kullanıcı zaten mevcut", + "creation_failed": "Hesap oluşturulamadı", + "server_error": "Sunucu hatası oluştu", + "generic": "Kayıt başarısız. Lütfen tekrar deneyin" + } + }, + "recordingtable": { + "run": "Çalıştır", + "name": "Ad", + "schedule": "Zamanlama", + "integrate": "Entegre Et", + "settings": "Ayarlar", + "options": "Seçenekler", + "heading": "Robotlarım", + "new": "Robot Oluştur", + "modal": { + "title": "URL’yi Girin", + "login_title": "Bu web sitesine giriş gerekiyor mu?", + "label": "URL", + "button": "Kaydı Başlat" + }, + "warning_modal": { + "title": "Aktif Tarayıcı Tespit Edildi", + "message": "Hâlihazırda çalışan bir tarayıcı kayıt oturumu var. İptal edip yeni bir kayıt başlatmak ister misiniz?", + "discard_and_create": "İptal Et ve Yenisi Oluştur", + "cancel": "İptal" + }, + "retrain": "Yeniden Eğit", + "edit": "Düzenle", + "delete": "Sil", + "duplicate": "Çoğalt", + "search": "Robot Ara...", + "notifications": { + "delete_warning": "Robota bağlı çalıştırmalar var. Robotu silmeden önce çalıştırmaları silin", + "delete_success": "Robot başarıyla silindi", + "auth_success": "Robot başarıyla kimlik doğrulandı", + "browser_limit_warning": "Uzak tarayıcılar şu anda meşgul. Lütfen birkaç dakika bekleyip tekrar deneyin" + } + }, + "mainmenu": { + "recordings": "Robotlar", + "runs": "Çalıştırmalar", + "proxy": "Proxy", + "apikey": "API Anahtarı", + "feedback": "Maxun Cloud’a Katıl", + "apidocs": "Web Siteyi API’ye Dönüştür" + }, + "runstable": { + "runs": "Tüm Çalıştırmalar", + "runStatus": "Durum", + "runName": "Ad", + "startedAt": "Başlama", + "finishedAt": "Bitiş", + "delete": "Sil", + "settings": "Ayarlar", + "search": "Çalıştırma Ara...", + "sort_tooltip": "Sıralamak için tıkla", + "notifications": { + "no_runs": "Çalıştırma bulunamadı. Lütfen tekrar deneyin.", + "delete_success": "Çalıştırma başarıyla silindi" + } + }, + "proxy": { + "title": "Proxy Yapılandırması", + "tab_standard": "Standart Proxy", + "tab_rotation": "Otomatik Proxy Döndürme", + "server_url": "Proxy Sunucu URL’si", + "server_url_helper": "Tüm robotlar için kullanılacak proxy. HTTP ve SOCKS desteklenir. Örnek http://myproxy.com:3128 veya socks5://myproxy.com:3128. Kısa biçim myproxy.com:3128 HTTP proxy kabul edilir.", + "requires_auth": "Kimlik Doğrulama Gerekli mi?", + "username": "Kullanıcı Adı", + "password": "Şifre", + "add_proxy": "Proxy Ekle", + "test_proxy": "Proxy’yi Test Et", + "remove_proxy": "Proxy’yi Kaldır", + "table": { + "proxy_url": "Proxy URL", + "requires_auth": "Kimlik Doğrulama Gerekli" + }, + "coming_soon": "Yakında — Açık Kaynak (Temel Döndürme) & Cloud (Gelişmiş Döndürme). Altyapı yönetmek istemiyorsanız, erken erişim için cloud bekleme listemize katılın.", + "join_waitlist": "Maxun Cloud Bekleme Listesine Katıl", + "alert": { + "title": "Proxy’niz kullanıcı adı ve şifre gerektiriyorsa, bunları her zaman URL’den ayrı girin.", + "right_way": "Doğru yol", + "wrong_way": "Yanlış yol", + "proxy_url": "Proxy URL:", + "username": "Kullanıcı Adı:", + "password": "Şifre:" + }, + "notifications": { + "config_success": "Proxy yapılandırması başarıyla gönderildi", + "config_error": "Proxy yapılandırması gönderilemedi. Tekrar deneyin.", + "test_success": "Proxy yapılandırması çalışıyor", + "test_error": "Proxy testi başarısız. Tekrar deneyin.", + "fetch_success": "Proxy yapılandırması alındı", + "remove_success": "Proxy yapılandırması kaldırıldı", + "remove_error": "Proxy kaldırma başarısız. Tekrar deneyin." + } + }, + "apikey": { + "title": "API Anahtarını Yönet", + "default_name": "Maxun API Anahtarı", + "table": { + "name": "API Anahtar Adı", + "key": "API Anahtarı", + "actions": "Eylemler" + }, + "actions": { + "copy": "Kopyala", + "show": "Göster", + "hide": "Gizle", + "delete": "Sil" + }, + "no_key_message": "Henüz bir API anahtarı oluşturmadınız.", + "generate_button": "API Anahtarı Oluştur", + "notifications": { + "fetch_error": "API Anahtarı alınamadı - ${error}", + "generate_success": "API anahtarı oluşturuldu", + "generate_error": "API anahtarı oluşturulamadı - ${error}", + "delete_success": "API anahtarı silindi", + "delete_error": "API anahtarı silinemedi - ${error}", + "copy_success": "API anahtarı kopyalandı" + } + }, + "action_description": { + "text": { + "title": "Metin Yakala", + "description": "Çıkarmak istediğiniz metinlerin üzerine gelin ve tıklayarak seçin" + }, + "screenshot": { + "title": "Ekran Görüntüsü Yakala", + "description": "Sayfanın tamamının veya bir bölümünün ekran görüntüsünü alın" + }, + "list": { + "title": "Liste Yakala", + "description": "Çıkarmak istediğiniz listenin üzerine gelin. Seçtikten sonra, listenin içindeki tüm metinleri seçebilirsiniz." + }, + "default": { + "title": "Hangi verileri çıkarmak istiyorsunuz?", + "description": "Bir robot bir veya birden fazla işlem gerçekleştirebilir. Aşağıdaki seçeneklerden seçim yapın." + }, + "list_stages": { + "initial": "Listeyi ve içindeki metinleri seçin", + "pagination": "Robotun listenin geri kalanını nasıl yakalayacağını seçin", + "limit": "Çıkarılacak öğe sayısını seçin", + "complete": "Yakalama tamamlandı" + }, + "actions": { + "text": "Metin Yakala", + "list": "Liste Yakala", + "screenshot": "Ekran Görüntüsü Yakala" + } + }, + "right_panel": { + "buttons": { + "capture_list": "Liste Yakala", + "capture_text": "Metin Yakala", + "capture_screenshot": "Ekran Görüntüsü Yakala", + "confirm": "Onayla", + "discard": "İptal", + "confirm_capture": "Yakalamayı Onayla", + "confirm_pagination": "Onayla", + "confirm_limit": "Onayla", + "confirm_reset": "Onayla", + "finish_capture": "Yakalamayı Bitir", + "back": "Geri", + "reset": "Kaydı Yeniden Başlat", + "finish": "Bitir", + "cancel": "İptal", + "delete": "Sil" + }, + "screenshot": { + "capture_fullpage": "Tam Sayfa Yakala", + "capture_visible": "Görünen Kısmı Yakala", + "display_fullpage": "Tam Sayfa Görüntü Al", + "display_visible": "Görünen Kısmın Görüntüsünü Al" + }, + "pagination": { + "title": "Sayfada sonraki liste öğesini nasıl bulalım?", + "click_next": "Sonraki sayfaya gitmek için ‘sonraki’yi tıkla", + "click_load_more": "Daha fazla yüklemek için ‘daha fazla yükle’yi tıkla", + "scroll_down": "Daha fazla öğe için aşağı kaydır", + "scroll_up": "Daha fazla öğe için yukarı kaydır", + "none": "Yüklenecek başka öğe yok" + }, + "limit": { + "title": "En fazla kaç satır çıkarmak istiyorsunuz?", + "custom": "Özel", + "enter_number": "Sayı gir" + }, + "fields": { + "label": "Etiket", + "data": "Veri", + "field_label": "Alan Etiketi", + "field_data": "Alan Verisi" + }, + "messages": { + "list_selected": "Liste başarıyla seçildi", + "list_empty": "Liste seçildi. Lütfen listenin içindeki alanları seçin." + }, + "errors": { + "select_pagination": "Lütfen bir sayfalama tipi seçin.", + "select_pagination_element": "Lütfen önce sayfalama öğesini seçin.", + "select_limit": "Lütfen bir limit seçin veya özel limit girin.", + "invalid_limit": "Geçerli bir limit girin.", + "confirm_text_fields": "Lütfen tüm metin alanlarını onaylayın", + "unable_create_settings": "Liste ayarları oluşturulamadı. Bir alan tanımladığınızdan emin olun.", + "capture_text_discarded": "Metin Yakalama İptal Edildi", + "capture_list_discarded": "Liste Yakalama İptal Edildi", + "label_required": "Etiket boş olamaz" + } + }, + "save_recording": { + "title": "Robotu Kaydet", + "robot_name": "Robot Adı", + "buttons": { + "save": "Kaydet", + "confirm": "Onayla" + }, + "notifications": { + "save_success": "Robot kaydedildi", + "retrain_success": "Robot yeniden eğitildi", + "save_error": "Robot kaydedilirken hata" + }, + "errors": { + "user_not_logged": "Kullanıcı girişi yok. Kaydedilemedi.", + "exists_warning": "Bu isimde robot zaten var; üzerine yazmayı onaylayın." + }, + "tooltips": { + "saving": "Akış optimize ediliyor ve kaydediliyor" + } + }, + "browser_recording": { + "modal": { + "confirm_discard": "Kaydı iptal etmek istediğinize emin misiniz?", + "confirm_reset": "Kaydı yeniden başlatmak istediğinize emin misiniz?", + "reset_warning": "Bu işlem, mevcut oturumdaki tüm yakalamaları temizler ve aynı site için kaydı yeniden başlatır." + }, + "notifications": { + "terminated": "Kayıt sonlandırıldı", + "environment_reset": "Tarayıcı ortamı sıfırlandı", + "reset_successful": "Yakalamalar sıfırlandı ve başlangıç durumuna dönüldü" + } + }, + "interpretation_log": { + "titles": { + "output_preview": "Çıktı Verisi Önizlemesi", + "screenshot": "Ekran Görüntüsü" + }, + "messages": { + "additional_rows": "Kaydı bitirdiğinizde ek satırlar çıkarılacak.", + "successful_training": "Robotu başarıyla eğittiniz! Çıkaracağı verilerin önizlemesi için aşağıdaki butona tıklayın.", + "no_selection": "Henüz seçim yapmadınız. Seçim yaptığınızda önizleme burada görünecek." + }, + "data_sections": { + "binary_received": "---------- İkili çıktı verisi alındı ----------", + "serializable_received": "---------- Serileştirilebilir çıktı verisi alındı ----------", + "mimetype": "mimetype: ", + "image_below": "Görüntü aşağıda:", + "separator": "--------------------------------------------------" + }, + "notifications": { + "reset_success": "Önizleme sıfırlandı" + } + }, + "interpretation_buttons": { + "buttons": { + "preview": "Çıktı Önizle", + "reset": "Sıfırla", + "yes": "Evet", + "no": "Hayır" + }, + "messages": { + "extracting": "Veri çıkarılıyor... lütfen bekleyin", + "restart_required": "Kaydı güncelledikten sonra yorumlamayı yeniden başlatın", + "run_finished": "Çalıştırma tamamlandı", + "run_failed": "Çalıştırma başlatılamadı" + }, + "modal": { + "use_previous": "Bu işlem için önceki seçiminizi koşul olarak kullanmak ister misiniz?", + "previous_action": "Önceki işleminiz:", + "element_text": " metnine sahip öğe" + } + }, + "recording_page": { + "loader": { + "browser_startup": "Tarayıcı başlatılıyor... Lütfen bekleyin" + } + }, + "integration_settings": { + "title": "Entegrasyon Ayarları", + "descriptions": { + "authenticated_as": "Kimlik doğrulandı: {{email}}" + }, + "buttons": { + "submit": "Gönder", + "remove_integration": "Entegrasyonu Kaldır" + }, + "google": { + "title": "Google Sheet ile Entegrasyon", + "descriptions": { + "sync_info": "Bu seçenek etkinse robot başarılı olduğunda veriler Google Sheet’e eklenir.", + "authenticated_as": "Kimlik doğrulandı: {{email}}" + }, + "alerts": { + "success": { + "title": "Google Sheet entegrasyonu başarılı", + "content": "Robot her başarılı çalıştırmada veriyi {{sheetName}} sayfanıza ekler. Kontrol etmek için", + "here": "buraya", + "note": "Not:", + "sync_limitation": "Entegrasyon öncesi veriler senkronize edilmez." + } + }, + "buttons": { + "authenticate": "Google ile Giriş Yap", + "fetch_sheets": "E‑Tabloları Getir", + "remove_integration": "Entegrasyonu Kaldır", + "submit": "Gönder" + }, + "fields": { + "select_sheet": "Google Sheet Seç", + "selected_sheet": "Seçilen Sheet: {{name}} (ID: {{id}})" + }, + "errors": { + "auth_error": "Google kimlik doğrulama hatası", + "fetch_error": "E‑tablo alma hatası: {{message}}", + "update_error": "Sheet ID güncelleme hatası: {{message}}", + "remove_error": "Google Sheets entegrasyon kaldırma hatası: {{message}}" + }, + "notifications": { + "sheet_selected": "Google Sheet seçildi", + "integration_removed": "Google Sheets entegrasyonu kaldırıldı" + } + }, + "airtable": { + "title": "Airtable ile Entegrasyon", + "descriptions": { + "sync_info": "Bu seçenek etkinse robot başarılı olduğunda veriler Airtable Base’e eklenir.", + "authenticated_as": "Airtable kimlik doğrulandı. Base ve tablo seçebilirsiniz." + }, + "alerts": { + "success": { + "title": "Airtable entegrasyonu başarılı", + "content": "Robot her başarılı çalıştırmada veriyi {{baseName}} > {{tableName}}’e ekler. Kontrol etmek için", + "here": "buraya", + "note": "Not:", + "sync_limitation": "Yalnızca entegrasyon sonrası veriler senkronize edilir." + } + }, + "buttons": { + "authenticate": "Airtable’a Bağlan", + "fetch_bases": "Base’leri Getir", + "fetch_tables": "Tabloları Getir", + "remove_integration": "Entegrasyonu Kaldır", + "submit": "Base ve Tablo Seç" + }, + "fields": { + "select_base": "Airtable Base Seç", + "select_table": "Airtable Tablo Seç", + "selected_base": "Seçilen Base: {{name}}", + "selected_table": "Seçilen Tablo: {{name}}" + }, + "errors": { + "auth_error": "Airtable kimlik doğrulama hatası", + "fetch_error": "Base alma hatası: {{message}}", + "fetch_tables_error": "Tablo alma hatası: {{message}}", + "update_error": "Base güncelleme hatası: {{message}}", + "remove_error": "Airtable entegrasyon kaldırma hatası: {{message}}" + }, + "notifications": { + "base_selected": "Base seçildi", + "table_selected": "Tablo seçildi", + "integration_removed": "Airtable entegrasyonu kaldırıldı" + } + } + }, + "robot_duplication": { + "title": "Robotu Çoğalt", + "descriptions": { + "purpose": "Aynı yapıya sahip sayfalarda veri toplamak için kullanılır.", + "example": "Örnek: {{url1}} için robot oluşturduysanız, benzer {{url2}} sayfaları için çoğaltabilirsiniz.", + "warning": "⚠️ Yeni sayfanın yapısının aynı olduğundan emin olun." + }, + "fields": { + "target_url": "Robot Hedef URL" + }, + "buttons": { + "duplicate": "Robotu Çoğalt", + "cancel": "İptal" + }, + "notifications": { + "robot_not_found": "Robot bulunamadı. Tekrar deneyin.", + "url_required": "Hedef URL gerekli.", + "duplicate_success": "Robot çoğaltıldı", + "duplicate_error": "Hedef URL güncellenemedi. Tekrar deneyin.", + "unknown_error": "Hedef URL güncellenirken hata oluştu" + } + }, + "robot_settings": { + "title": "Robot Ayarları", + "target_url": "Robot Hedef URL", + "robot_id": "Robot ID", + "robot_limit": "Robot Limiti", + "created_by_user": "Oluşturan", + "created_at": "Oluşturulma", + "errors": { + "robot_not_found": "Robot bulunamadı. Tekrar deneyin." + } + }, + "robot_edit": { + "title": "Robotu Düzenle", + "change_name": "Robot Adı", + "robot_limit": "Robot Limiti", + "save": "Değişiklikleri Kaydet", + "cancel": "İptal", + "notifications": { + "update_success": "Robot güncellendi", + "update_failed": "Robot güncellenemedi. Tekrar deneyin.", + "update_error": "Güncelleme sırasında hata" + } + }, + "schedule_settings": { + "title": "Zamanlama Ayarları", + "run_every": "Çalıştırma aralığı", + "start_from": "Başlangıç", + "on_day": "Gününde", + "at_around": "Saat civarı", + "timezone": "Zaman Dilimi", + "buttons": { + "delete_schedule": "Zamanlamayı Sil", + "save_schedule": "Zamanlamayı Kaydet", + "cancel": "İptal" + }, + "labels": { + "in_between": "Arasında", + "run_once_every": "Her", + "start_from_label": "Başlangıç", + "on_day_of_month": "Ayın Günü", + "on_day": { + "st": ".", + "nd": ".", + "rd": ".", + "th": "." + } + } + }, + "main_page": { + "notifications": { + "interpretation_success": "Robot {{name}} yorumlandı", + "interpretation_failed": "Robot {{name}} yorumlanamadı", + "run_started": "Robot çalıştırılıyor: {{name}}", + "run_start_failed": "Robot çalıştırılamadı: {{name}}", + "schedule_success": "Robot {{name}} zamanlandı", + "schedule_failed": "Robot {{name}} zamanlanamadı", + "abort_success": "Robot {{name}} yorumlaması iptal edildi", + "abort_failed": "Robot {{name}} yorumlaması iptal edilemedi", + "abort_initiated": "Robot {{name}} yorumu iptal ediliyor" + }, + "menu": { + "recordings": "Robotlar", + "runs": "Çalıştırmalar", + "proxy": "Proxy", + "apikey": "API Anahtarı" + } + }, + "browser_window": { + "attribute_modal": { + "title": "Öznitelik Seç", + "notifications": { + "list_select_success": "Liste seçildi. Çıkarılacak verileri seçin.", + "pagination_select_success": "Sayfalama öğesi seçildi" + } + }, + "attribute_options": { + "anchor": { + "text": "Metin: {{text}}", + "url": "URL: {{url}}" + }, + "image": { + "alt_text": "Alternatif Metin: {{altText}}", + "image_url": "Görsel URL: {{imageUrl}}" + }, + "default": { + "text": "Metin: {{text}}" + } + } + }, + "runs_table": { + "run_type_chips": { + "manual_run": "Manuel", + "scheduled_run": "Zamanlanmış", + "api": "API", + "unknown_run_type": "Bilinmeyen" + }, + "run_status_chips": { + "success": "Başarılı", + "running": "Çalışıyor", + "scheduled": "Zamanlandı", + "queued": "Kuyrukta", + "failed": "Başarısız", + "aborted": "İptal" + }, + "run_settings_modal": { + "title": "Çalıştırma Ayarları", + "labels": { + "run_id": "Çalıştırma ID", + "run_by_user": "Kullanıcı", + "run_by_schedule": "Zamanlama ID", + "run_by_api": "API", + "run_type": "Tür" + } + } + }, + "run_content": { + "tabs": { + "output_data": "Çıktı Verisi", + "log": "Kayıt" + }, + "buttons": { + "stop": "Durdur" + }, + "loading": "Veriler yükleniyor...", + "empty_output": "Çıktı verisi yok", + "captured_data": { + "title": "Yakalanan Veriler", + "download_csv": "CSV İndir", + "view_full": "Tam Veriyi Gör", + "items": "öğe", + "schema_title": "Yakalanan Metinler", + "list_title": "Yakalanan Listeler" + }, + "captured_screenshot": { + "title": "Yakalanan Görüntüler", + "download": "İndir", + "render_failed": "Görüntü render edilemedi" + } + }, + "navbar": { + "project_name": "Maxun", + "notifications": { + "success": { + "logout": "Çıkış yapıldı" + }, + "errors": { + "logout": { + "unauthorized": "Bu işlemi yapmaya yetkiniz yok", + "server": "Çıkış sırasında sunucu hatası", + "network": "Çıkış sırasında ağ hatası", + "unknown": "Bilinmeyen hata oluştu" + } + } + }, + "upgrade": { + "button": "Yükselt", + "modal": { + "up_to_date": "🎉 Güncelsiniz!", + "new_version_available": "Yeni sürüm mevcut: {{version}}. Güncelleyerek yeni özelliklere erişin!", + "view_updates": "Tüm güncellemeleri görüntüle", + "view_updates_link": "buradan", + "tabs": { + "manual_setup": "Manuel Kurulum", + "docker_setup": "Docker Kurulumu" + } + } + }, + "menu_items": { + "logout": "Çıkış Yap", + "discord": "Discord", + "youtube": "YouTube", + "twitter": "Twitter (X)", + "language": "Dil" + }, + "recording": { + "discard": "İptal" + } + }, + "language_menu": { + "en": "İngilizce", + "es": "İspanyolca", + "ja": "Japonca", + "zh": "Çince", + "de": "Almanca", + "tr": "Türkçe" + } +} diff --git a/public/locales/zh.json b/public/locales/zh.json index 37d3b708..9c588908 100644 --- a/public/locales/zh.json +++ b/public/locales/zh.json @@ -601,6 +601,7 @@ "es": "西班牙语", "ja": "日语", "zh": "中文", - "de": "德语" + "de": "德语", + "tr": "土耳其语" } } From 714911687ac2e0df99e01566bd5da61efb95bd0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20AYDINO=C4=9ELU?= Date: Sun, 20 Jul 2025 14:44:42 +0300 Subject: [PATCH 02/11] fix: replaced ${error} with {{error}} in all locale files for i18next compatibility --- public/locales/de.json | 6 +++--- public/locales/en.json | 6 +++--- public/locales/es.json | 6 +++--- public/locales/ja.json | 6 +++--- public/locales/tr.json | 6 +++--- public/locales/zh.json | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/public/locales/de.json b/public/locales/de.json index 4b27e068..eef6ace5 100644 --- a/public/locales/de.json +++ b/public/locales/de.json @@ -141,11 +141,11 @@ "no_key_message": "Sie haben noch keinen API-Schlüssel generiert.", "generate_button": "API-Schlüssel generieren", "notifications": { - "fetch_error": "API-Schlüssel konnte nicht abgerufen werden - ${error}", + "fetch_error": "API-Schlüssel konnte nicht abgerufen werden - {{error}}", "generate_success": "API-Schlüssel erfolgreich generiert", - "generate_error": "API-Schlüssel konnte nicht generiert werden - ${error}", + "generate_error": "API-Schlüssel konnte nicht generiert werden - {{error}}", "delete_success": "API-Schlüssel erfolgreich gelöscht", - "delete_error": "API-Schlüssel konnte nicht gelöscht werden - ${error}", + "delete_error": "API-Schlüssel konnte nicht gelöscht werden - {{error}}", "copy_success": "API-Schlüssel erfolgreich kopiert" } }, diff --git a/public/locales/en.json b/public/locales/en.json index e6b7ab34..7721231e 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -148,11 +148,11 @@ "no_key_message": "You haven't generated an API key yet.", "generate_button": "Generate API Key", "notifications": { - "fetch_error": "Failed to fetch API Key - ${error}", + "fetch_error": "Failed to fetch API Key - {{error}}", "generate_success": "Generated API Key successfully", - "generate_error": "Failed to generate API Key - ${error}", + "generate_error": "Failed to generate API Key - {{error}}", "delete_success": "API Key deleted successfully", - "delete_error": "Failed to delete API Key - ${error}", + "delete_error": "Failed to delete API Key - {{error}}", "copy_success": "Copied API Key successfully" } }, diff --git a/public/locales/es.json b/public/locales/es.json index 26e12b52..c98b2c8b 100644 --- a/public/locales/es.json +++ b/public/locales/es.json @@ -142,11 +142,11 @@ "no_key_message": "Aún no has generado una clave API.", "generate_button": "Generar Clave API", "notifications": { - "fetch_error": "Error al obtener la clave API - ${error}", + "fetch_error": "Error al obtener la clave API - {{error}}", "generate_success": "Clave API generada con éxito", - "generate_error": "Error al generar la clave API - ${error}", + "generate_error": "Error al generar la clave API - {{error}}", "delete_success": "Clave API eliminada con éxito", - "delete_error": "Error al eliminar la clave API - ${error}", + "delete_error": "Error al eliminar la clave API - {{error}}", "copy_success": "Clave API copiada con éxito" } }, diff --git a/public/locales/ja.json b/public/locales/ja.json index 3a2458d7..32ca0654 100644 --- a/public/locales/ja.json +++ b/public/locales/ja.json @@ -142,11 +142,11 @@ "no_key_message": "APIキーはまだ生成されていません。", "generate_button": "APIキーを生成", "notifications": { - "fetch_error": "APIキーの取得に失敗しました - ${error}", + "fetch_error": "APIキーの取得に失敗しました - {{error}}", "generate_success": "APIキーの生成に成功しました", - "generate_error": "APIキーの生成に失敗しました - ${error}", + "generate_error": "APIキーの生成に失敗しました - {{error}}", "delete_success": "APIキーの削除に成功しました", - "delete_error": "APIキーの削除に失敗しました - ${error}", + "delete_error": "APIキーの削除に失敗しました - {{error}}", "copy_success": "APIキーのコピーに成功しました" } }, diff --git a/public/locales/tr.json b/public/locales/tr.json index 68c9613b..6c714fe0 100644 --- a/public/locales/tr.json +++ b/public/locales/tr.json @@ -148,11 +148,11 @@ "no_key_message": "Henüz bir API anahtarı oluşturmadınız.", "generate_button": "API Anahtarı Oluştur", "notifications": { - "fetch_error": "API Anahtarı alınamadı - ${error}", + "fetch_error": "API Anahtarı alınamadı - {{error}}", "generate_success": "API anahtarı oluşturuldu", - "generate_error": "API anahtarı oluşturulamadı - ${error}", + "generate_error": "API anahtarı oluşturulamadı - {{error}}", "delete_success": "API anahtarı silindi", - "delete_error": "API anahtarı silinemedi - ${error}", + "delete_error": "API anahtarı silinemedi - {{error}}", "copy_success": "API anahtarı kopyalandı" } }, diff --git a/public/locales/zh.json b/public/locales/zh.json index 9c588908..6bb6e9b3 100644 --- a/public/locales/zh.json +++ b/public/locales/zh.json @@ -142,11 +142,11 @@ "no_key_message": "您还未生成API密钥。", "generate_button": "生成API密钥", "notifications": { - "fetch_error": "获取API密钥失败 - ${error}", + "fetch_error": "获取API密钥失败 - {{error}}", "generate_success": "成功生成API密钥", - "generate_error": "生成API密钥失败 - ${error}", + "generate_error": "生成API密钥失败 - {{error}}", "delete_success": "成功删除API密钥", - "delete_error": "删除API密钥失败 - ${error}", + "delete_error": "删除API密钥失败 - {{error}}", "copy_success": "成功复制API密钥" } }, From 0fd40c3d1a7fec8e8b79d681ce5a7167b2a6212d Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 21 Jul 2025 19:31:29 +0530 Subject: [PATCH 03/11] fix: adjust modal vertical alignment --- src/components/recorder/AddWhereCondModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/recorder/AddWhereCondModal.tsx b/src/components/recorder/AddWhereCondModal.tsx index 7c5c284c..758c9e75 100644 --- a/src/components/recorder/AddWhereCondModal.tsx +++ b/src/components/recorder/AddWhereCondModal.tsx @@ -140,7 +140,7 @@ export const AddWhereCondModal = ({ isOpen, onClose, pair, index }: AddWhereCond } export const modalStyle = { - top: '40%', + top: '45%', left: '50%', transform: 'translate(-50%, -50%)', width: '30%', From 9d209d42161bfc491f882c8a2d03d433cc2f3a8a Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 21 Jul 2025 19:35:20 +0530 Subject: [PATCH 04/11] feat: add backend frontend in docker pull command --- src/components/dashboard/NavBar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/dashboard/NavBar.tsx b/src/components/dashboard/NavBar.tsx index 1f36879e..aaa5c9f8 100644 --- a/src/components/dashboard/NavBar.tsx +++ b/src/components/dashboard/NavBar.tsx @@ -338,7 +338,7 @@ export const NavBar: React.FC = ({
# pull latest docker images
- docker-compose pull + docker-compose pull backend frontend

# start maxun From 276ca85b35c8ed765bc3d53af441096fdd4c6916 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 21 Jul 2025 19:45:59 +0530 Subject: [PATCH 05/11] feat: -rm existing be & fe images --- src/components/dashboard/NavBar.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/dashboard/NavBar.tsx b/src/components/dashboard/NavBar.tsx index aaa5c9f8..ebde0702 100644 --- a/src/components/dashboard/NavBar.tsx +++ b/src/components/dashboard/NavBar.tsx @@ -335,6 +335,11 @@ export const NavBar: React.FC = ({
docker-compose down
+
+ # Remove existing backend and frontend images +
+ docker rmi getmaxun/maxun-frontend:latest getmaxun/maxun-backend:latest +

# pull latest docker images
From 16c0f990806a35a0dae728a79c50f2b99f290fe6 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 21 Jul 2025 19:55:24 +0530 Subject: [PATCH 06/11] feat: increase width --- src/components/dashboard/NavBar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/dashboard/NavBar.tsx b/src/components/dashboard/NavBar.tsx index 1f36879e..6a47e6bb 100644 --- a/src/components/dashboard/NavBar.tsx +++ b/src/components/dashboard/NavBar.tsx @@ -267,7 +267,7 @@ export const NavBar: React.FC = ({ top: "50%", left: "50%", transform: "translate(-50%, -50%)", - width: 500, + width: 700, bgcolor: "background.paper", boxShadow: 24, p: 4, From 717cb07bb3e7aef77252a676491e1312da6a483a Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 21 Jul 2025 19:56:01 +0530 Subject: [PATCH 07/11] feat: !center tabs --- src/components/dashboard/NavBar.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/dashboard/NavBar.tsx b/src/components/dashboard/NavBar.tsx index 6a47e6bb..e4b42a40 100644 --- a/src/components/dashboard/NavBar.tsx +++ b/src/components/dashboard/NavBar.tsx @@ -292,7 +292,6 @@ export const NavBar: React.FC = ({ value={tab} onChange={handleUpdateTabChange} sx={{ marginTop: 2, marginBottom: 2 }} - centered > From 7f7e2aa52cedafa4342ce95abd9b78a7105d41d7 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 21 Jul 2025 19:56:20 +0530 Subject: [PATCH 08/11] feat: margin left for tabs --- src/components/dashboard/NavBar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/dashboard/NavBar.tsx b/src/components/dashboard/NavBar.tsx index e4b42a40..02d733d2 100644 --- a/src/components/dashboard/NavBar.tsx +++ b/src/components/dashboard/NavBar.tsx @@ -291,7 +291,7 @@ export const NavBar: React.FC = ({ From 6852a25133c7a8bb859eb0a12584a43c828466c4 Mon Sep 17 00:00:00 2001 From: Rohit Date: Wed, 23 Jul 2025 01:13:10 +0530 Subject: [PATCH 09/11] feat: normalize classes, ignore framework specific attr --- src/helpers/clientSelectorGenerator.ts | 30 ++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/helpers/clientSelectorGenerator.ts b/src/helpers/clientSelectorGenerator.ts index ff0e10d0..2710f806 100644 --- a/src/helpers/clientSelectorGenerator.ts +++ b/src/helpers/clientSelectorGenerator.ts @@ -164,7 +164,12 @@ class ClientSelectorGenerator { return Array.from(classList) .filter((cls) => { // Filter out classes that look like they contain IDs or dynamic content - return !cls.match(/\d{3,}|uuid|hash|id-|_\d+$/i); + return ( + !cls.match(/\d{3,}|uuid|hash|id-|_\d+$/i) && + !cls.startsWith("_ngcontent-") && + !cls.startsWith("_nghost-") && + !cls.match(/^ng-tns-c\d+-\d+$/) + ); }) .sort() .join(" "); @@ -2950,7 +2955,7 @@ class ClientSelectorGenerator { return tagName; } - const classes = Array.from(element.classList); + const classes = this.normalizeClasses(element.classList).split(" "); if (classes.length > 0 && !addPositionToAll) { const classSelector = classes .map((cls) => `contains(@class, '${cls}')`) @@ -2961,7 +2966,7 @@ class ClientSelectorGenerator { .filter((el) => el !== element) .some((el) => classes.every((cls) => - (el as HTMLElement).classList.contains(cls) + this.normalizeClasses((el as HTMLElement).classList).split(" ").includes(cls) ) ) : false; @@ -3119,14 +3124,14 @@ class ClientSelectorGenerator { // Build path from target up to root while (current && current !== rootElement) { // Calculate conflicts for each element in the path - const classes = Array.from(current.classList); + const classes = this.normalizeClasses(current.classList).split(" "); const hasConflictingElement = classes.length > 0 && rootElement ? this.queryElementsInScope(rootElement, current.tagName.toLowerCase()) .filter((el) => el !== current) .some((el) => classes.every((cls) => - (el as HTMLElement).classList.contains(cls) + this.normalizeClasses((el as HTMLElement).classList).split(" ").includes(cls) ) ) : false; @@ -4002,6 +4007,7 @@ class ClientSelectorGenerator { const commonAttributes = this.getCommonAttributes(elements, [ "id", "style", + "class" ]); for (const [attr, value] of Object.entries(commonAttributes)) { predicates.push(`@${attr}='${value}'`); @@ -4052,7 +4058,19 @@ class ClientSelectorGenerator { const attrMap: Record = {}; for (const attr of Array.from(firstEl.attributes)) { - if (excludeAttrs.includes(attr.name)) continue; + if (excludeAttrs.includes(attr.name) || !attr.value || attr.value.trim() === '') { + continue; + } + + if (attr.name.startsWith('_ngcontent-') || attr.name.startsWith('_nghost-')) { + continue; + } + + if (attr.name.match(/^(data-reactid|data-react-checksum|ng-reflect-)/) || + attr.name.includes('-c') && attr.name.match(/\d+$/)) { + continue; + } + attrMap[attr.name] = attr.value; } From c7b253ce2af086c9cf447f2fdde04c44241a4e32 Mon Sep 17 00:00:00 2001 From: Rohit Date: Thu, 24 Jul 2025 15:02:59 +0530 Subject: [PATCH 10/11] feat: rm timeout attr selection --- src/components/browser/BrowserWindow.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/components/browser/BrowserWindow.tsx b/src/components/browser/BrowserWindow.tsx index 9f5cedc2..707776ec 100644 --- a/src/components/browser/BrowserWindow.tsx +++ b/src/components/browser/BrowserWindow.tsx @@ -1159,10 +1159,6 @@ export const BrowserWindow = () => { setShowAttributeModal(false); setSelectedElement(null); setAttributeOptions([]); - - setTimeout(() => { - setShowAttributeModal(false); - }, 0); }; const resetPaginationSelector = useCallback(() => { From 33723a4b653ea6c4f4ccc0942daf4bd9bef339ee Mon Sep 17 00:00:00 2001 From: Rohit Date: Thu, 24 Jul 2025 15:03:45 +0530 Subject: [PATCH 11/11] fetat: stop propogation on generic modal click --- src/components/ui/GenericModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ui/GenericModal.tsx b/src/components/ui/GenericModal.tsx index a8d3c3e8..cdca071d 100644 --- a/src/components/ui/GenericModal.tsx +++ b/src/components/ui/GenericModal.tsx @@ -15,7 +15,7 @@ export const GenericModal: FC = ( return ( { }} > - + e.stopPropagation()}> {canBeClosed ?