diff --git a/Interface/static/css/style.css b/Interface/static/css/style.css index a5d9dcc..97aa545 100644 --- a/Interface/static/css/style.css +++ b/Interface/static/css/style.css @@ -56,7 +56,7 @@ body { } .navigate-title { - font-size: 16px; + font-size: 17px; font-weight: 600; letter-spacing: -0.2px; } diff --git a/Interface/static/js/i18n.js b/Interface/static/js/i18n.js index c15f180..d4e2351 100644 --- a/Interface/static/js/i18n.js +++ b/Interface/static/js/i18n.js @@ -1,1401 +1,1500 @@ window.AppI18n = { dict: { "traditional_switch": { - "PYAS Security": "PYAS Security", - "此裝置已受到防護": "此裝置已受到防護", - "智能掃描": "智能掃描", - "此選項可以快速掃描裝置安全性": "此選項可以快速掃描裝置安全性", - "日誌導出": "日誌導出", - "此選項可以篩選日誌並匯出存檔": "此選項可以篩選日誌並匯出存檔", - "病毒掃描": "病毒掃描", - "此選項可以選擇進階掃描方式": "此選項可以選擇進階掃描方式", - "刪除": "刪除", - "選擇": "選擇", - "檔案掃描": "檔案掃描", - "路徑掃描": "路徑掃描", - "全盤掃描": "全盤掃描", - "停止": "停止", - "進程防護": "進程防護", - "此選項可以終止惡意進程運行": "此選項可以終止惡意進程運行", - "檔案防護": "檔案防護", - "此選項可以隔離惡意檔案建立": "此選項可以隔離惡意檔案建立", - "系統防護": "系統防護", - "此選項可以實時修復系統異常": "此選項可以實時修復系統異常", - "驅動防護": "驅動防護", - "此選項可以實時攔截惡意行為": "此選項可以實時攔截惡意行為", - "網路防護": "網路防護", - "此選項可以攔截惡意網路連接": "此選項可以攔截惡意網路連接", - "自訂防護": "自訂防護", - "此選項可以導入自訂防護規則": "此選項可以導入自訂防護規則", - "進程管理": "進程管理", - "此選項可以實時查看系統進程": "此選項可以實時查看系統進程", - "垃圾清理": "垃圾清理", - "此選項可以清理暫存垃圾檔案": "此選項可以清理暫存垃圾檔案", - "系統修復": "系統修復", - "此選項可以修復系統註冊項目": "此選項可以修復系統登錄檔項目", - "彈窗攔截": "彈窗攔截", - "此選項可以選擇指定窗口攔截": "此選項可以選擇指定窗口攔截", - "白名單": "白名單", - "此選項可以查看並管理白名單": "此選項可以查看並管理白名單", - "隔離區": "隔離區", - "此選項可以查看並管理隔離區": "此選項可以查看並管理隔離區", - "增強模式": "增強模式", - "此選項可以增強靜態掃描引擎": "此選項可以增強靜態掃描引擎", - "擴展引擎": "擴展引擎", - "此選項可以使用擴展規則引擎": "此選項可以使用擴展規則引擎", - "雲端服務": "雲端服務", - "此選項可以自動上報可疑檔案": "此選項可以自動上報可疑檔案", - "顯色主題": "顯色主題", - "此選項可以選擇主題顏色": "此選項可以選擇主題顏色", - "白色主題": "白色主題", - "紅色主題": "紅色主題", - "黃色主題": "黃色主題", - "綠色主題": "綠色主題", - "藍色主題": "藍色主題", - "黑色主題": "黑色主題", - "顯示語言": "顯示語言", - "此選項可以選擇顯示語言": "此選項可以選擇顯示語言", - "重置選項": "重置選項", - "此選項可以重置所有設定": "此選項可以重置所有設定", - "執行": "執行", - "產品金鑰": "產品金鑰", - "此選項可以啟用產品金鑰": "此選項可以啟用產品金鑰", - "官方網站": "官方網站", - "此選項可以前往官方網站": "此選項可以前往官方網站", - "檢查更新": "檢查更新", - "此選項可以檢查可用更新": "此選項可以檢查可用更新", - "搜尋進程...": "搜尋進程...", - "查看": "查看", - "結束": "結束", - "白名單管理": "白名單管理", - "搜尋檔案...": "搜尋檔案...", - "加入": "加入", - "移除": "移除", - "隔離區管理": "隔離區管理", - "掃描": "掃描", - "搜尋窗口...": "搜尋窗口...", - "搜尋規則...": "搜尋規則...", - "搜尋日誌...": "搜尋日誌...", - "導出": "導出", - "正在初始化中": "正在初始化中", - "檢查更新失敗": "檢查更新失敗", - "發現新版本": "發現新版本", - "當前已是最新版本": "當前已是最新版本", - "請選擇要導出的日誌": "請選擇要導出的日誌", - "確定刪除選取的日誌記錄嗎?": "確定刪除選取的日誌記錄嗎?", - "選取的日誌已刪除。": "選取的日誌已刪除。", - "結束進程?": "結束進程?", - "確定要結束選取的進程嗎?": "確定要結束選取的進程嗎?", - "已清理 ": "已清理 ", - "設定已重置,請重新啟動程式以套用預設值。": "設定已重置,請重新啟動程式以套用預設值。", - "導出成功": "導出成功", - "選取進程路徑:\n": "選取進程路徑:\n", - "對 ": "對 ", - " 執行動作:\n1: 加入白名單\n2: 加入隔離區\n請輸入代碼:": " 執行動作:\n1: 加入白名單\n2: 加入隔離區\n請輸入代碼:", - "請在5秒內點擊目標視窗...": "請在5秒內點擊目標視窗...", - "確認攔截": "確認攔截", - "已修復選取項目": "已修復選取項目", - "修復": "修復", - "提示": "提示", - "錯誤": "錯誤", - "未知路徑": "未知路徑", - "修復系統 MBR": "修復系統 MBR", - "修復系統限制": "修復系統限制", - "修復檔案關聯": "修復檔案關聯", - "修復檔案圖標": "修復檔案圖標", - "修復映像劫持": "修復映像劫持", - "修復桌面壁紙": "修復桌面壁紙", - "正在掃描": "正在掃描", - "正在刪除": "正在刪除", - "選單掃描": "選單掃描", - "此選項可以啟用右鍵掃描功能": "此選項可以啟用右鍵掃描功能", - "刪除項目": "刪除項目", - "忽略項目": "忽略項目", - "加入隔離區": "加入隔離區", - "加入白名單": "加入白名單", - "日期": "日期", - "類型": "類型", - "功能": "功能", - "路徑": "路徑", - "名稱": "名稱", - "PID": "PID", - "大小": "大小", - "程式": "程式", - "類別": "類別", - "標題": "標題", - "修復項目": "修復項目", - "全選": "全選", - "打開檔案所在位置": "打開檔案所在位置" + "app_name": "PYAS Security", + "status_protected": "此裝置已受到防護", + "scan_smart": "智能掃描", + "scan_smart_desc": "此選項可以快速掃描裝置安全性", + "log_export": "日誌導出", + "log_export_desc": "此選項可以篩選日誌並匯出存檔", + "scan_virus": "病毒掃描", + "scan_virus_desc": "此選項可以選擇進階掃描方式", + "btn_delete": "刪除", + "btn_select": "選擇", + "scan_file": "檔案掃描", + "scan_path": "路徑掃描", + "scan_full": "全盤掃描", + "btn_stop": "停止", + "protect_proc": "進程防護", + "protect_proc_desc": "此選項可以終止惡意進程運行", + "protect_file": "檔案防護", + "protect_file_desc": "此選項可以隔離惡意檔案建立", + "protect_sys": "系統防護", + "protect_sys_desc": "此選項可以實時修復系統異常", + "protect_drv": "驅動防護", + "protect_drv_desc": "此選項可以實時攔截惡意行為", + "protect_net": "網路防護", + "protect_net_desc": "此選項可以攔截惡意網路連接", + "protect_custom": "自訂防護", + "protect_custom_desc": "此選項可以導入自訂防護規則", + "manage_proc": "進程管理", + "manage_proc_desc": "此選項可以實時查看系統進程", + "clean_junk": "垃圾清理", + "clean_junk_desc": "此選項可以清理暫存垃圾檔案", + "repair_sys": "系統修復", + "repair_sys_desc": "此選項可以修復系統登錄檔項目", + "block_popup": "彈窗攔截", + "block_popup_desc": "此選項可以選擇指定窗口攔截", + "list_white": "白名單", + "list_white_desc": "此選項可以查看並管理白名單", + "list_quarantine": "隔離區", + "list_quarantine_desc": "此選項可以查看並管理隔離區", + "mode_enhance": "增強模式", + "mode_enhance_desc": "此選項可以增強靜態掃描引擎", + "engine_ext": "擴展引擎", + "engine_ext_desc": "此選項可以使用擴展規則引擎", + "service_cloud": "雲端服務", + "service_cloud_desc": "此選項可以自動上報可疑檔案", + "scan_context": "選單掃描", + "scan_context_desc": "此選項可以啟用右鍵掃描功能", + "theme_color": "顯色主題", + "theme_color_desc": "此選項可以選擇主題顏色", + "theme_white": "白色主題", + "theme_red": "紅色主題", + "theme_yellow": "黃色主題", + "theme_green": "綠色主題", + "theme_blue": "藍色主題", + "theme_black": "黑色主題", + "lang_display": "顯示語言", + "lang_display_desc": "此選項可以選擇顯示語言", + "opt_reset": "重置選項", + "opt_reset_desc": "此選項可以重置所有設定", + "btn_execute": "執行", + "key_product": "產品金鑰", + "key_product_desc": "此選項可以啟用產品金鑰", + "web_official": "官方網站", + "web_official_desc": "此選項可以前往官方網站", + "update_check": "檢查更新", + "update_check_desc": "此選項可以檢查可用更新", + "search_proc": "搜尋進程...", + "btn_view": "查看", + "btn_end": "結束", + "manage_white": "白名單管理", + "search_file": "搜尋檔案...", + "btn_add": "加入", + "btn_remove": "移除", + "manage_quarantine": "隔離區管理", + "btn_scan": "掃描", + "search_window": "搜尋窗口...", + "search_rule": "搜尋規則...", + "search_log": "搜尋日誌...", + "btn_export": "導出", + "msg_init": "正在初始化中", + "msg_update_fail": "檢查更新失敗", + "msg_new_version": "發現新版本", + "msg_latest_version": "當前已是最新版本", + "msg_sel_log_export": "請選擇要導出的日誌", + "msg_del_log_confirm": "確定刪除選取的日誌記錄嗎?", + "msg_log_deleted": "選取的日誌已刪除。", + "msg_end_proc_title": "結束進程?", + "msg_end_proc_confirm": "確定要結束選取的進程嗎?", + "msg_cleaned": "已清理 ", + "msg_reset_success": "設定已重置,請重新啟動程式以套用預設值。", + "msg_export_success": "導出成功", + "msg_sel_proc_path": "選取進程路徑:\n", + "msg_action_for": "對 ", + "msg_action_opts": " 執行動作:\n1: 加入白名單\n2: 加入隔離區\n請輸入代碼:", + "msg_click_target": "請在5秒內點擊目標視窗...", + "msg_confirm_block": "確認攔截", + "msg_repaired": "已修復選取項目", + "btn_repair": "修復", + "title_prompt": "提示", + "title_error": "錯誤", + "path_unknown": "未知路徑", + "repair_mbr": "修復系統 MBR", + "repair_limit": "修復系統限制", + "repair_assoc": "修復檔案關聯", + "repair_icon": "修復檔案圖標", + "repair_hijack": "修復映像劫持", + "repair_wallpaper": "修復桌面壁紙", + "status_scanning": "正在掃描", + "status_deleting": "正在刪除", + "act_del": "刪除項目", + "act_ignore": "忽略項目", + "act_quarantine": "加入隔離區", + "act_white": "加入白名單", + "col_date": "日期", + "col_type": "類型", + "col_func": "功能", + "col_path": "路徑", + "col_name": "名稱", + "col_pid": "PID", + "col_size": "大小", + "col_prog": "程式", + "col_class": "類別", + "col_title": "標題", + "col_repair": "修復項目", + "btn_select_all": "全選", + "ctx_open_loc": "打開檔案所在位置", + "msg_too_many": "(資料過多,僅顯示前 {0} 筆以確保效能流暢)", + "res_scan_comp": "掃描完成", + "res_virus_det": "發現病毒", + "res_proc_block": "進程攔截", + "res_file_block": "檔案攔截", + "res_net_block": "網路攔截", + "res_drv_block": "驅動攔截", + "res_sys_repair": "系統修復", + "res_cfg_update": "設定更新" }, "simplified_switch": { - "PYAS Security": "PYAS Security", - "此裝置已受到防護": "此设备已受到防护", - "智能掃描": "智能扫描", - "此選項可以快速掃描裝置安全性": "此选项可以快速扫描设备安全性", - "日誌導出": "日志导出", - "此選項可以篩選日誌並匯出存檔": "此选项可以筛选日志并导出存档", - "病毒掃描": "病毒扫描", - "此選項可以選擇進階掃描方式": "此选项可以选择高级扫描方式", - "刪除": "删除", - "選擇": "选择", - "檔案掃描": "文件扫描", - "路徑掃描": "路径扫描", - "全盤掃描": "全盘扫描", - "停止": "停止", - "進程防護": "进程防护", - "此選項可以終止惡意進程運行": "此选项可以终止恶意进程运行", - "檔案防護": "文件防护", - "此選項可以隔離惡意檔案建立": "此选项可以隔离恶意文件建立", - "系統防護": "系统防护", - "此選項可以實時修復系統異常": "此选项可以实时修复系统异常", - "驅動防護": "驱动防护", - "此選項可以實時攔截惡意行為": "此选项可以实时拦截恶意行为", - "網路防護": "网络防护", - "此選項可以攔截惡意網路連接": "此选项可以拦截恶意网络连接", - "自訂防護": "自订防护", - "此選項可以導入自訂防護規則": "此选项可以导入自定义防护规则", - "進程管理": "进程管理", - "此選項可以實時查看系統進程": "此选项可以实时查看系统进程", - "垃圾清理": "垃圾清理", - "此選項可以清理暫存垃圾檔案": "此选项可以清理暂存垃圾文件", - "系統修復": "系统修复", - "此選項可以修復系統註冊項目": "此选项可以修复系统注册表项目", - "彈窗攔截": "弹窗拦截", - "此選項可以選擇指定窗口攔截": "此选项可以选择指定窗口拦截", - "白名單": "白名单", - "此選項可以查看並管理白名單": "此选项可以查看并管理白名单", - "隔離區": "隔离区", - "此選項可以查看並管理隔離區": "此选项可以查看并管理隔离区", - "增強模式": "增强模式", - "此選項可以增強靜態掃描引擎": "此选项可以增强静态扫描引擎", - "擴展引擎": "扩展引擎", - "此選項可以使用擴展規則引擎": "此选项可以使用扩展规则引擎", - "雲端服務": "云端服务", - "此選項可以自動上報可疑檔案": "此选项可以自动上报可疑文件", - "顯色主題": "显色主题", - "此選項可以選擇主題顏色": "此选项可以选择主题颜色", - "白色主題": "白色主题", - "紅色主題": "红色主题", - "黃色主題": "黄色主题", - "綠色主題": "绿色主题", - "藍色主題": "蓝色主题", - "黑色主題": "黑色主题", - "顯示語言": "显示语言", - "此選項可以選擇顯示語言": "此选项可以选择显示语言", - "重置選項": "重置选项", - "此選項可以重置所有設定": "此选项可以重置所有设定", - "執行": "执行", - "產品金鑰": "产品密钥", - "此選項可以啟用產品金鑰": "此选项可以启用产品密钥", - "官方網站": "官方网站", - "此選項可以前往官方網站": "此选项可以前往官方网站", - "檢查更新": "检查更新", - "此選項可以檢查可用更新": "此选项可以检查可用更新", - "搜尋進程...": "搜索进程...", - "查看": "查看", - "結束": "结束", - "白名單管理": "白名单管理", - "搜尋檔案...": "搜索文件...", - "加入": "加入", - "移除": "移除", - "隔離區管理": "隔离区管理", - "掃描": "扫描", - "搜尋窗口...": "搜索窗口...", - "搜尋規則...": "搜索规则...", - "搜尋日誌...": "搜索日志...", - "導出": "导出", - "正在初始化中": "正在初始化中", - "檢查更新失敗": "检查更新失败", - "發現新版本": "发现新版本", - "當前已是最新版本": "当前已是最新版本", - "請選擇要導出的日誌": "请选择要导出的日志", - "確定刪除選取的日誌記錄嗎?": "确定删除选取的日志记录吗?", - "選取的日誌已刪除。": "选取的日志已删除。", - "結束進程?": "结束进程?", - "確定要結束選取的進程嗎?": "确定要结束选取的进程吗?", - "已清理 ": "已清理 ", - "設定已重置,請重新啟動程式以套用預設值。": "设定已重置,请重新启动程序以应用默认值。", - "導出成功": "导出成功", - "選取進程路徑:\n": "选取进程路径:\n", - "對 ": "对 ", - " 執行動作:\n1: 加入白名單\n2: 加入隔離區\n請輸入代碼:": " 执行动作:\n1: 加入白名单\n2: 加入隔离区\n请输入代码:", - "請在5秒內點擊目標視窗...": "请在5秒内点击目标窗口...", - "確認攔截": "确认拦截", - "已修復選取項目": "已修复选取项目", - "修復": "修复", - "提示": "提示", - "錯誤": "错误", - "未知路徑": "未知路径", - "修復系統 MBR": "修复系统 MBR", - "修復系統限制": "修复系统限制", - "修復檔案關聯": "修复文件关联", - "修復檔案圖標": "修复文件图标", - "修復映像劫持": "修复映像劫持", - "修復桌面壁紙": "修复桌面壁纸", - "正在掃描": "正在扫描", - "正在刪除": "正在删除", - "選單掃描": "菜单扫描", - "此選項可以啟用右鍵掃描功能": "此选项可以启用右键扫描功能", - "刪除項目": "删除项目", - "忽略項目": "忽略项目", - "加入隔離區": "加入隔离区", - "加入白名單": "加入白名单", - "日期": "日期", - "類型": "类型", - "功能": "功能", - "路徑": "路径", - "名稱": "名称", - "PID": "PID", - "大小": "大小", - "程式": "程序", - "類別": "类别", - "標題": "标题", - "修復項目": "修复项目", - "全選": "全选", - "打開檔案所在位置": "打开文件所在位置" + "app_name": "PYAS Security", + "status_protected": "此设备已受到防护", + "scan_smart": "智能扫描", + "scan_smart_desc": "此选项可以快速扫描设备安全性", + "log_export": "日志导出", + "log_export_desc": "此选项可以筛选日志并导出存档", + "scan_virus": "病毒扫描", + "scan_virus_desc": "此选项可以选择高级扫描方式", + "btn_delete": "删除", + "btn_select": "选择", + "scan_file": "文件扫描", + "scan_path": "路径扫描", + "scan_full": "全盘扫描", + "btn_stop": "停止", + "protect_proc": "进程防护", + "protect_proc_desc": "此选项可以终止恶意进程运行", + "protect_file": "文件防护", + "protect_file_desc": "此选项可以隔离恶意文件建立", + "protect_sys": "系统防护", + "protect_sys_desc": "此选项可以实时修复系统异常", + "protect_drv": "驱动防护", + "protect_drv_desc": "此选项可以实时拦截恶意行为", + "protect_net": "网络防护", + "protect_net_desc": "此选项可以拦截恶意网络连接", + "protect_custom": "自订防护", + "protect_custom_desc": "此选项可以导入自定义防护规则", + "manage_proc": "进程管理", + "manage_proc_desc": "此选项可以实时查看系统进程", + "clean_junk": "垃圾清理", + "clean_junk_desc": "此选项可以清理暂存垃圾文件", + "repair_sys": "系统修复", + "repair_sys_desc": "此选项可以修复系统注册表项目", + "block_popup": "弹窗拦截", + "block_popup_desc": "此选项可以选择指定窗口拦截", + "list_white": "白名单", + "list_white_desc": "此选项可以查看并管理白名单", + "list_quarantine": "隔离区", + "list_quarantine_desc": "此选项可以查看并管理隔离区", + "mode_enhance": "增强模式", + "mode_enhance_desc": "此选项可以增强静态扫描引擎", + "engine_ext": "扩展引擎", + "engine_ext_desc": "此选项可以使用扩展规则引擎", + "service_cloud": "云端服务", + "service_cloud_desc": "此选项可以自动上报可疑文件", + "scan_context": "菜单扫描", + "scan_context_desc": "此选项可以启用右键扫描功能", + "theme_color": "显色主题", + "theme_color_desc": "此选项可以选择主题颜色", + "theme_white": "白色主题", + "theme_red": "红色主题", + "theme_yellow": "黄色主题", + "theme_green": "绿色主题", + "theme_blue": "蓝色主题", + "theme_black": "黑色主题", + "lang_display": "显示语言", + "lang_display_desc": "此选项可以选择显示语言", + "opt_reset": "重置选项", + "opt_reset_desc": "此选项可以重置所有设定", + "btn_execute": "执行", + "key_product": "产品密钥", + "key_product_desc": "此选项可以启用产品密钥", + "web_official": "官方网站", + "web_official_desc": "此选项可以前往官方网站", + "update_check": "检查更新", + "update_check_desc": "此选项可以检查可用更新", + "search_proc": "搜索进程...", + "btn_view": "查看", + "btn_end": "结束", + "manage_white": "白名单管理", + "search_file": "搜索文件...", + "btn_add": "加入", + "btn_remove": "移除", + "manage_quarantine": "隔离区管理", + "btn_scan": "扫描", + "search_window": "搜索窗口...", + "search_rule": "搜索规则...", + "search_log": "搜索日志...", + "btn_export": "导出", + "msg_init": "正在初始化中", + "msg_update_fail": "检查更新失败", + "msg_new_version": "发现新版本", + "msg_latest_version": "当前已是最新版本", + "msg_sel_log_export": "请选择要导出的日志", + "msg_del_log_confirm": "确定删除选取的日志记录吗?", + "msg_log_deleted": "选取的日志已删除。", + "msg_end_proc_title": "结束进程?", + "msg_end_proc_confirm": "确定要结束选取的进程吗?", + "msg_cleaned": "已清理 ", + "msg_reset_success": "设定已重置,请重新启动程序以应用默认值。", + "msg_export_success": "导出成功", + "msg_sel_proc_path": "选取进程路径:\n", + "msg_action_for": "对 ", + "msg_action_opts": " 执行动作:\n1: 加入白名单\n2: 加入隔离区\n请输入代码:", + "msg_click_target": "请在5秒内点击目标窗口...", + "msg_confirm_block": "确认拦截", + "msg_repaired": "已修复选取项目", + "btn_repair": "修复", + "title_prompt": "提示", + "title_error": "错误", + "path_unknown": "未知路径", + "repair_mbr": "修复系统 MBR", + "repair_limit": "修复系统限制", + "repair_assoc": "修复文件关联", + "repair_icon": "修复文件图标", + "repair_hijack": "修复映像劫持", + "repair_wallpaper": "修复桌面壁纸", + "status_scanning": "正在扫描", + "status_deleting": "正在删除", + "act_del": "删除项目", + "act_ignore": "忽略项目", + "act_quarantine": "加入隔离区", + "act_white": "加入白名单", + "col_date": "日期", + "col_type": "类型", + "col_func": "功能", + "col_path": "路径", + "col_name": "名称", + "col_pid": "PID", + "col_size": "大小", + "col_prog": "程序", + "col_class": "类别", + "col_title": "标题", + "col_repair": "修复项目", + "btn_select_all": "全选", + "ctx_open_loc": "打开文件所在位置", + "msg_too_many": "(数据过多,仅显示前 {0} 条以确保性能流畅)", + "res_scan_comp": "扫描完成", + "res_virus_det": "发现病毒", + "res_proc_block": "进程拦截", + "res_file_block": "文件拦截", + "res_net_block": "网络拦截", + "res_drv_block": "驱动拦截", + "res_sys_repair": "系统修复", + "res_cfg_update": "设置更新" }, "english_switch": { - "PYAS Security": "PYAS Security", - "此裝置已受到防護": "This Device is Protected", - "智能掃描": "Smart Scan", - "此選項可以快速掃描裝置安全性": "Quickly scan device security", - "日誌導出": "Export Logs", - "此選項可以篩選日誌並匯出存檔": "Filter logs and export to archive", - "病毒掃描": "Virus Scan", - "此選項可以選擇進階掃描方式": "Select an advanced scanning method", - "刪除": "Delete", - "選擇": "Select", - "檔案掃描": "File Scan", - "路徑掃描": "Path Scan", - "全盤掃描": "Full Scan", - "停止": "Stop", - "進程防護": "Process Protection", - "此選項可以終止惡意進程運行": "Terminate malicious process execution", - "檔案防護": "File Protection", - "此選項可以隔離惡意檔案建立": "Quarantine malicious file creation", - "系統防護": "System Protection", - "此選項可以實時修復系統異常": "Real-time repair of system anomalies", - "驅動防護": "Driver Protection", - "此選項可以實時攔截惡意行為": "Real-time interception of malicious behavior", - "網路防護": "Network Protection", - "此選項可以攔截惡意網路連接": "Block malicious network connections", - "自訂防護": "Custom Protection", - "此選項可以導入自訂防護規則": "Import custom protection rules", - "進程管理": "Process Manager", - "此選項可以實時查看系統進程": "Monitor real-time system processes", - "垃圾清理": "Junk Cleanup", - "此選項可以清理暫存垃圾檔案": "Clean temporary and junk files", - "系統修復": "System Repair", - "此選項可以修復系統註冊項目": "Repair system registry items", - "彈窗攔截": "Popup Blocker", - "此選項可以選擇指定窗口攔截": "Block specific popup windows", - "白名單": "Whitelist", - "此選項可以查看並管理白名單": "View and manage the whitelist", - "隔離區": "Quarantine", - "此選項可以查看並管理隔離區": "View and manage the quarantine", - "增強模式": "Enhanced Mode", - "此選項可以增強靜態掃描引擎": "Enhance the static scanning engine", - "擴展引擎": "Extension Engine", - "此選項可以使用擴展規則引擎": "Enable extension rule engines", - "雲端服務": "Cloud Service", - "此選項可以自動上報可疑檔案": "Automatically report suspicious files", - "顯色主題": "Color Theme", - "此選項可以選擇主題顏色": "Select application color theme", - "白色主題": "Light Mode", - "紅色主題": "Red Theme", - "黃色主題": "Yellow Theme", - "綠色主題": "Green Theme", - "藍色主題": "Blue Theme", - "黑色主題": "Dark Mode", - "顯示語言": "Display Language", - "此選項可以選擇顯示語言": "Select application display language", - "重置選項": "Reset Options", - "此選項可以重置所有設定": "Restore all settings to default", - "執行": "Execute", - "產品金鑰": "Product Key", - "此選項可以啟用產品金鑰": "Activate your product key", - "官方網站": "Official Website", - "此選項可以前往官方網站": "Visit our official website", - "檢查更新": "Check for Updates", - "此選項可以檢查可用更新": "Check for the latest updates", - "搜尋進程...": "Search processes...", - "查看": "View", - "結束": "End Task", - "白名單管理": "Whitelist Manager", - "搜尋檔案...": "Search files...", - "加入": "Add", - "移除": "Remove", - "隔離區管理": "Quarantine Manager", - "掃描": "Scan", - "搜尋窗口...": "Search windows...", - "搜尋規則...": "Search rules...", - "搜尋日誌...": "Search logs...", - "導出": "Export", - "正在初始化中": "Initializing...", - "檢查更新失敗": "Update check failed", - "發現新版本": "New version found", - "當前已是最新版本": "Currently at latest version", - "請選擇要導出的日誌": "Please select logs to export", - "確定刪除選取的日誌記錄嗎?": "Are you sure you want to delete selected logs?", - "選取的日誌已刪除。": "Selected logs have been deleted.", - "結束進程?": "End process?", - "確定要結束選取的進程嗎?": "Are you sure you want to end the selected processes?", - "已清理 ": "Cleaned ", - "設定已重置,請重新啟動程式以套用預設值。": "Settings reset. Please restart the application to apply defaults.", - "導出成功": "Export successful", - "選取進程路徑:\n": "Selected process paths:\n", - "對 ": "Action for ", - " 執行動作:\n1: 加入白名單\n2: 加入隔離區\n請輸入代碼:": ":\n1: Add to Whitelist\n2: Add to Quarantine\nEnter code:", - "請在5秒內點擊目標視窗...": "Click the target window within 5s...", - "確認攔截": "Confirm Block", - "已修復選取項目": "Selected items repaired", - "修復": "Repair", - "提示": "Prompt", - "錯誤": "Error", - "未知路徑": "Unknown Path", - "修復系統 MBR": "Repair System MBR", - "修復系統限制": "Repair System Restrictions", - "修復檔案關聯": "Repair File Associations", - "修復檔案圖標": "Repair File Icons", - "修復映像劫持": "Repair Image Hijacking", - "修復桌面壁紙": "Repair Desktop Wallpaper", - "正在掃描": "Scanning...", - "正在刪除": "Deleting...", - "選單掃描": "Context Menu Scan", - "此選項可以啟用右鍵掃描功能": "Enable right-click scan functionality", - "刪除項目": "Delete Items", - "忽略項目": "Ignore Items", - "加入隔離區": "Add to Quarantine", - "加入白名單": "Add to Whitelist", - "日期": "Date", - "類型": "Type", - "功能": "Function", - "路徑": "Path", - "名稱": "Name", - "PID": "PID", - "大小": "Size", - "程式": "Process", - "類別": "Class", - "標題": "Title", - "修復項目": "Repair Items", - "全選": "Select All", - "打開檔案所在位置": "Open file location" + "app_name": "PYAS Security", + "status_protected": "This Device is Protected", + "scan_smart": "Smart Scan", + "scan_smart_desc": "Quickly scan device security", + "log_export": "Export Logs", + "log_export_desc": "Filter logs and export to archive", + "scan_virus": "Virus Scan", + "scan_virus_desc": "Select an advanced scanning method", + "btn_delete": "Delete", + "btn_select": "Select", + "scan_file": "File Scan", + "scan_path": "Path Scan", + "scan_full": "Full Scan", + "btn_stop": "Stop", + "protect_proc": "Process Protection", + "protect_proc_desc": "Terminate malicious process execution", + "protect_file": "File Protection", + "protect_file_desc": "Quarantine malicious file creation", + "protect_sys": "System Protection", + "protect_sys_desc": "Real-time repair of system anomalies", + "protect_drv": "Driver Protection", + "protect_drv_desc": "Real-time interception of malicious behavior", + "protect_net": "Network Protection", + "protect_net_desc": "Block malicious network connections", + "protect_custom": "Custom Protection", + "protect_custom_desc": "Import custom protection rules", + "manage_proc": "Process Manager", + "manage_proc_desc": "Monitor real-time system processes", + "clean_junk": "Junk Cleanup", + "clean_junk_desc": "Clean temporary and junk files", + "repair_sys": "System Repair", + "repair_sys_desc": "Repair system registry items", + "block_popup": "Popup Blocker", + "block_popup_desc": "Block specific popup windows", + "list_white": "Whitelist", + "list_white_desc": "View and manage the whitelist", + "list_quarantine": "Quarantine", + "list_quarantine_desc": "View and manage the quarantine", + "mode_enhance": "Enhanced Mode", + "mode_enhance_desc": "Enhance the static scanning engine", + "engine_ext": "Extension Engine", + "engine_ext_desc": "Enable extension rule engines", + "service_cloud": "Cloud Service", + "service_cloud_desc": "Automatically report suspicious files", + "scan_context": "Context Menu Scan", + "scan_context_desc": "Enable right-click scan functionality", + "theme_color": "Color Theme", + "theme_color_desc": "Select application color theme", + "theme_white": "Light Mode", + "theme_red": "Red Theme", + "theme_yellow": "Yellow Theme", + "theme_green": "Green Theme", + "theme_blue": "Blue Theme", + "theme_black": "Dark Mode", + "lang_display": "Display Language", + "lang_display_desc": "Select application display language", + "opt_reset": "Reset Options", + "opt_reset_desc": "Restore all settings to default", + "btn_execute": "Execute", + "key_product": "Product Key", + "key_product_desc": "Activate your product key", + "web_official": "Official Website", + "web_official_desc": "Visit our official website", + "update_check": "Check for Updates", + "update_check_desc": "Check for the latest updates", + "search_proc": "Search processes...", + "btn_view": "View", + "btn_end": "End Task", + "manage_white": "Whitelist Manager", + "search_file": "Search files...", + "btn_add": "Add", + "btn_remove": "Remove", + "manage_quarantine": "Quarantine Manager", + "btn_scan": "Scan", + "search_window": "Search windows...", + "search_rule": "Search rules...", + "search_log": "Search logs...", + "btn_export": "Export", + "msg_init": "Initializing...", + "msg_update_fail": "Update check failed", + "msg_new_version": "New version found", + "msg_latest_version": "Currently at latest version", + "msg_sel_log_export": "Please select logs to export", + "msg_del_log_confirm": "Are you sure you want to delete selected logs?", + "msg_log_deleted": "Selected logs have been deleted.", + "msg_end_proc_title": "End process?", + "msg_end_proc_confirm": "Are you sure you want to end the selected processes?", + "msg_cleaned": "Cleaned ", + "msg_reset_success": "Settings reset. Please restart the application to apply defaults.", + "msg_export_success": "Export successful", + "msg_sel_proc_path": "Selected process paths:\n", + "msg_action_for": "Action for ", + "msg_action_opts": ":\n1: Add to Whitelist\n2: Add to Quarantine\nEnter code:", + "msg_click_target": "Click the target window within 5s...", + "msg_confirm_block": "Confirm Block", + "msg_repaired": "Selected items repaired", + "btn_repair": "Repair", + "title_prompt": "Prompt", + "title_error": "Error", + "path_unknown": "Unknown Path", + "repair_mbr": "Repair System MBR", + "repair_limit": "Repair System Restrictions", + "repair_assoc": "Repair File Associations", + "repair_icon": "Repair File Icons", + "repair_hijack": "Repair Image Hijacking", + "repair_wallpaper": "Repair Desktop Wallpaper", + "status_scanning": "Scanning...", + "status_deleting": "Deleting...", + "act_del": "Delete Items", + "act_ignore": "Ignore Items", + "act_quarantine": "Add to Quarantine", + "act_white": "Add to Whitelist", + "col_date": "Date", + "col_type": "Type", + "col_func": "Function", + "col_path": "Path", + "col_name": "Name", + "col_pid": "PID", + "col_size": "Size", + "col_prog": "Process", + "col_class": "Class", + "col_title": "Title", + "col_repair": "Repair Items", + "btn_select_all": "Select All", + "ctx_open_loc": "Open file location", + "msg_too_many": "(Too much data, showing only the top {0} records for performance)", + "res_scan_comp": "Scan Completed", + "res_virus_det": "Virus Detected", + "res_proc_block": "Process Blocked", + "res_file_block": "File Blocked", + "res_net_block": "Network Blocked", + "res_drv_block": "Driver Blocked", + "res_sys_repair": "System Repair", + "res_cfg_update": "Config Update" }, "japanese_switch": { - "PYAS Security": "PYAS Security", - "此裝置已受到防護": "このデバイスは保護されています", - "智能掃描": "スマートスキャン", - "此選項可以快速掃描裝置安全性": "デバイスのセキュリティを迅速にスキャンします", - "日誌導出": "ログのエクスポート", - "此選項可以篩選日誌並匯出存檔": "ログをフィルタリングしてアーカイブにエクスポートします", - "病毒掃描": "ウイルススキャン", - "此選項可以選擇進階掃描方式": "高度なスキャン方法を選択します", - "刪除": "削除", - "選擇": "選択", - "檔案掃描": "ファイルスキャン", - "路徑掃描": "パススキャン", - "全盤掃描": "フルスキャン", - "停止": "停止", - "進程防護": "プロセス保護", - "此選項可以終止惡意進程運行": "悪意のあるプロセスの実行を終了します", - "檔案防護": "ファイル保護", - "此選項可以隔離惡意檔案建立": "悪意のあるファイルの作成を隔離します", - "系統防護": "システム保護", - "此選項可以實時修復系統異常": "システムの異常をリアルタイムで修復します", - "驅動防護": "ドライバー保護", - "此選項可以實時攔截惡意行為": "悪意のある動作をリアルタイムでインターセプトします", - "網路防護": "ネットワーク保護", - "此選項可以攔截惡意網路連接": "悪意のあるネットワーク接続をブロックします", - "自訂防護": "カスタム保護", - "此選項可以導入自訂防護規則": "カスタム保護ルールをインポートします", - "進程管理": "プロセス管理", - "此選項可以實時查看系統進程": "システムプロセスをリアルタイムで監視します", - "垃圾清理": "ジャンククリーンアップ", - "此選項可以清理暫存垃圾檔案": "一時ファイルやジャンクファイルをクリーンアップします", - "系統修復": "システム修復", - "此選項可以修復系統註冊項目": "システムレジストリ項目を修復します", - "彈窗攔截": "ポップアップブロック", - "此選項可以選擇指定窗口攔截": "特定のポップアップウィンドウをブロックします", - "白名單": "ホワイトリスト", - "此選項可以查看並管理白名單": "ホワイトリストを表示および管理します", - "隔離區": "隔離", - "此選項可以查看並管理隔離區": "隔離領域を表示および管理します", - "增強模式": "強化モード", - "此選項可以增強靜態掃描引擎": "静的スキャンエンジンを強化します", - "擴展引擎": "拡張エンジン", - "此選項可以使用擴展規則引擎": "拡張ルールエンジンを有効にします", - "雲端服務": "クラウドサービス", - "此選項可以自動上報可疑檔案": "不審なファイルを自動的に報告します", - "顯色主題": "カラーテーマ", - "此選項可以選擇主題顏色": "アプリケーションのテーマカラーを選択します", - "白色主題": "ライトモード", - "紅色主題": "レッドテーマ", - "黃色主題": "イエローテーマ", - "綠色主題": "グリーンテーマ", - "藍色主題": "ブルーテーマ", - "黑色主題": "ダークモード", - "顯示語言": "表示言語", - "此選項可以選擇顯示語言": "アプリケーションの表示言語を選択します", - "重置選項": "オプションのリセット", - "此選項可以重置所有設定": "すべての設定をデフォルトに戻します", - "執行": "実行", - "產品金鑰": "プロダクトキー", - "此選項可以啟用產品金鑰": "プロダクトキーを有効にします", - "官方網站": "公式サイト", - "此選項可以前往官方網站": "当社の公式サイトにアクセスします", - "檢查更新": "アップデートの確認", - "此選項可以檢查可用更新": "利用可能なアップデートを確認します", - "搜尋進程...": "プロセスを検索...", - "查看": "表示", - "結束": "タスクの終了", - "白名單管理": "ホワイトリスト管理", - "搜尋檔案...": "ファイルを検索...", - "加入": "追加", - "移除": "削除", - "隔離區管理": "隔離管理", - "掃描": "スキャン", - "搜尋窗口...": "ウィンドウを検索...", - "搜尋規則...": "ルールを検索...", - "搜尋日誌...": "ログを検索...", - "導出": "エクスポート", - "正在初始化中": "初期化中...", - "檢查更新失敗": "アップデートの確認に失敗しました", - "發現新版本": "新しいバージョンが見つかりました", - "當前已是最新版本": "現在は最新バージョンです", - "請選擇要導出的日誌": "エクスポートするログを選択してください", - "確定刪除選取的日誌記錄嗎?": "選択したログを削除してもよろしいですか?", - "選取的日誌已刪除。": "選択したログが削除されました。", - "結束進程?": "プロセスを終了しますか?", - "確定要結束選取的進程嗎?": "選択したプロセスを終了してもよろしいですか?", - "已清理 ": "クリーンアップ完了 ", - "設定已重置,請重新啟動程式以套用預設值。": "設定がリセットされました。デフォルトを適用するにはプログラムを再起動してください。", - "導出成功": "エクスポート成功", - "選取進程路徑:\n": "選択されたプロセスのパス:\n", - "對 ": "対象: ", - " 執行動作:\n1: 加入白名單\n2: 加入隔離區\n請輸入代碼:": " に対するアクション:\n1: ホワイトリストに追加\n2: 隔離に追加\nコードを入力してください:", - "請在5秒內點擊目標視窗...": "5秒以内にターゲットウィンドウをクリックしてください...", - "確認攔截": "ブロックの確認", - "已修復選取項目": "選択された項目が修復されました", - "修復": "修復", - "提示": "プロンプト", - "錯誤": "エラー", - "未知路徑": "不明なパス", - "修復系統 MBR": "システム MBR の修復", - "修復系統限制": "システム制限の修復", - "修復檔案關聯": "ファイルの関連付けを修復", - "修復檔案圖標": "ファイルアイコンの修復", - "修復映像劫持": "イメージハイジャックの修復", - "修復桌面壁紙": "デスクトップの壁紙を修復", - "正在掃描": "スキャン中...", - "正在刪除": "削除中...", - "選單掃描": "コンテキストメニュースキャン", - "此選項可以啟用右鍵掃描功能": "右クリックでスキャン機能を有効にします", - "刪除項目": "アイテムを削除", - "忽略項目": "アイテムを無視", - "加入隔離區": "隔離に追加", - "加入白名單": "ホワイトリストに追加", - "日期": "日付", - "類型": "タイプ", - "功能": "機能", - "路徑": "パス", - "名稱": "名前", - "PID": "PID", - "大小": "サイズ", - "程式": "プログラム", - "類別": "クラス", - "標題": "タイトル", - "修復項目": "修復項目", - "全選": "すべて選択", - "打開檔案所在位置": "ファイルの場所を開く" + "app_name": "PYAS Security", + "status_protected": "このデバイスは保護されています", + "scan_smart": "スマートスキャン", + "scan_smart_desc": "デバイスのセキュリティを迅速にスキャンします", + "log_export": "ログのエクスポート", + "log_export_desc": "ログをフィルタリングしてアーカイブにエクスポートします", + "scan_virus": "ウイルススキャン", + "scan_virus_desc": "高度なスキャン方法を選択します", + "btn_delete": "削除", + "btn_select": "選択", + "scan_file": "ファイルスキャン", + "scan_path": "パススキャン", + "scan_full": "フルスキャン", + "btn_stop": "停止", + "protect_proc": "プロセス保護", + "protect_proc_desc": "悪意のあるプロセスの実行を終了します", + "protect_file": "ファイル保護", + "protect_file_desc": "悪意のあるファイルの作成を隔離します", + "protect_sys": "システム保護", + "protect_sys_desc": "システムの異常をリアルタイムで修復します", + "protect_drv": "ドライバー保護", + "protect_drv_desc": "悪意のある動作をリアルタイムでインターセプトします", + "protect_net": "ネットワーク保護", + "protect_net_desc": "悪意のあるネットワーク接続をブロックします", + "protect_custom": "カスタム保護", + "protect_custom_desc": "カスタム保護ルールをインポートします", + "manage_proc": "プロセス管理", + "manage_proc_desc": "システムプロセスをリアルタイムで監視します", + "clean_junk": "ジャンククリーンアップ", + "clean_junk_desc": "一時ファイルやジャンクファイルをクリーンアップします", + "repair_sys": "システム修復", + "repair_sys_desc": "システムレジストリ項目を修復します", + "block_popup": "ポップアップブロック", + "block_popup_desc": "特定のポップアップウィンドウをブロックします", + "list_white": "ホワイトリスト", + "list_white_desc": "ホワイトリストを表示および管理します", + "list_quarantine": "隔離", + "list_quarantine_desc": "隔離領域を表示および管理します", + "mode_enhance": "強化モード", + "mode_enhance_desc": "静的スキャンエンジンを強化します", + "engine_ext": "拡張エンジン", + "engine_ext_desc": "拡張ルールエンジンを有効にします", + "service_cloud": "クラウドサービス", + "service_cloud_desc": "不審なファイルを自動的に報告します", + "scan_context": "コンテキストメニュースキャン", + "scan_context_desc": "右クリックでスキャン機能を有効にします", + "theme_color": "カラーテーマ", + "theme_color_desc": "アプリケーションのテーマカラーを選択します", + "theme_white": "ライトモード", + "theme_red": "レッドテーマ", + "theme_yellow": "イエローテーマ", + "theme_green": "グリーンテーマ", + "theme_blue": "ブルーテーマ", + "theme_black": "ダークモード", + "lang_display": "表示言語", + "lang_display_desc": "アプリケーションの表示言語を選択します", + "opt_reset": "オプションのリセット", + "opt_reset_desc": "すべての設定をデフォルトに戻します", + "btn_execute": "実行", + "key_product": "プロダクトキー", + "key_product_desc": "プロダクトキーを有効にします", + "web_official": "公式サイト", + "web_official_desc": "当社の公式サイトにアクセスします", + "update_check": "アップデートの確認", + "update_check_desc": "利用可能なアップデートを確認します", + "search_proc": "プロセスを検索...", + "btn_view": "表示", + "btn_end": "タスクの終了", + "manage_white": "ホワイトリスト管理", + "search_file": "ファイルを検索...", + "btn_add": "追加", + "btn_remove": "削除", + "manage_quarantine": "隔離管理", + "btn_scan": "スキャン", + "search_window": "ウィンドウを検索...", + "search_rule": "ルールを検索...", + "search_log": "ログを検索...", + "btn_export": "エクスポート", + "msg_init": "初期化中...", + "msg_update_fail": "アップデートの確認に失敗しました", + "msg_new_version": "新しいバージョンが見つかりました", + "msg_latest_version": "現在は最新バージョンです", + "msg_sel_log_export": "エクスポートするログを選択してください", + "msg_del_log_confirm": "選択したログを削除してもよろしいですか?", + "msg_log_deleted": "選択したログが削除されました。", + "msg_end_proc_title": "プロセスを終了しますか?", + "msg_end_proc_confirm": "選択したプロセスを終了してもよろしいですか?", + "msg_cleaned": "クリーンアップ完了 ", + "msg_reset_success": "設定がリセットされました。デフォルトを適用するにはプログラムを再起動してください。", + "msg_export_success": "エクスポート成功", + "msg_sel_proc_path": "選択されたプロセスのパス:\n", + "msg_action_for": "対象: ", + "msg_action_opts": " に対するアクション:\n1: ホワイトリストに追加\n2: 隔離に追加\nコードを入力してください:", + "msg_click_target": "5秒以内にターゲットウィンドウをクリックしてください...", + "msg_confirm_block": "ブロックの確認", + "msg_repaired": "選択された項目が修復されました", + "btn_repair": "修復", + "title_prompt": "プロンプト", + "title_error": "エラー", + "path_unknown": "不明なパス", + "repair_mbr": "システム MBR の修復", + "repair_limit": "システム制限の修復", + "repair_assoc": "ファイルの関連付けを修復", + "repair_icon": "ファイルアイコンの修復", + "repair_hijack": "イメージハイジャックの修復", + "repair_wallpaper": "デスクトップの壁紙を修復", + "status_scanning": "スキャン中...", + "status_deleting": "削除中...", + "act_del": "アイテムを削除", + "act_ignore": "アイテムを無視", + "act_quarantine": "隔離に追加", + "act_white": "ホワイトリストに追加", + "col_date": "日付", + "col_type": "タイプ", + "col_func": "機能", + "col_path": "パス", + "col_name": "名前", + "col_pid": "PID", + "col_size": "サイズ", + "col_prog": "プログラム", + "col_class": "クラス", + "col_title": "タイトル", + "col_repair": "修復項目", + "btn_select_all": "すべて選択", + "ctx_open_loc": "ファイルの場所を開く", + "msg_too_many": "(データが多すぎるため、パフォーマンスを確保するために上位 {0} 件のみを表示します)", + "res_scan_comp": "スキャン完了", + "res_virus_det": "ウイルスを検出", + "res_proc_block": "プロセスブロック", + "res_file_block": "ファイルブロック", + "res_net_block": "ネットワークブロック", + "res_drv_block": "ドライバーブロック", + "res_sys_repair": "システム修復", + "res_cfg_update": "設定の更新" }, "korean_switch": { - "PYAS Security": "PYAS Security", - "此裝置已受到防護": "이 장치는 보호되고 있습니다", - "智能掃描": "스마트 스캔", - "此選項可以快速掃描裝置安全性": "디바이스 보안을 빠르게 스캔합니다", - "日誌導出": "로그 내보내기", - "此選項可以篩選日誌並匯出存檔": "로그를 필터링하고 아카이브로 내보냅니다", - "病毒掃描": "바이러스 스캔", - "此選項可以選擇進階掃描方式": "고급 스캔 방법을 선택합니다", - "刪除": "삭제", - "選擇": "선택", - "檔案掃描": "파일 스캔", - "路徑掃描": "경로 스캔", - "全盤掃描": "전체 스캔", - "停止": "정지", - "進程防護": "프로세스 보호", - "此選項可以終止惡意進程運行": "악성 프로세스 실행을 종료합니다", - "檔案防護": "파일 보호", - "此選項可以隔離惡意檔案建立": "악성 파일 생성을 격리합니다", - "系統防護": "시스템 보호", - "此選項可以實時修復系統異常": "시스템 이상을 실시간으로 복구합니다", - "驅動防護": "드라이버 보호", - "此選項可以實時攔截惡意行為": "악의적인 행동을 실시간으로 차단합니다", - "網路防護": "네트워크 보호", - "此選項可以攔截惡意網路連接": "악의적인 네트워크 연결을 차단합니다", - "自訂防護": "사용자 지정 보호", - "此選項可以導入自訂防護規則": "사용자 지정 보호 규칙을 가져옵니다", - "進程管理": "프로세스 관리", - "此選項可以實時查看系統進程": "실시간으로 시스템 프로세스를 모니터링합니다", - "垃圾清理": "정크 정리", - "此選項可以清理暫存垃圾檔案": "임시 파일 및 정크 파일을 정리합니다", - "系統修復": "시스템 복구", - "此選項可以修復系統註冊項目": "시스템 레지스트리 항목을 복구합니다", - "彈窗攔截": "팝업 차단", - "此選項可以選擇指定窗口攔截": "특정 팝업 창을 차단합니다", - "白名單": "화이트리스트", - "此選項可以查看並管理白名單": "화이트리스트를 보고 관리합니다", - "隔離區": "격리소", - "此選項可以查看並管理隔離區": "격리 구역을 보고 관리합니다", - "增強模式": "고급 모드", - "此選項可以增強靜態掃描引擎": "정적 스캔 엔진을 강화합니다", - "擴展引擎": "확장 엔진", - "此選項可以使用擴展規則引擎": "확장 규칙 엔진을 활성화합니다", - "雲端服務": "클라우드 서비스", - "此選項可以自動上報可疑檔案": "의심스러운 파일을 자동으로 보고합니다", - "顯色主題": "색상 테마", - "此選項可以選擇主題顏色": "응용 프로그램 테마 색상을 선택합니다", - "白色主題": "라이트 모드", - "紅色主題": "레드 테마", - "黃色主題": "옐로우 테마", - "綠色主題": "그린 테마", - "藍色主題": "블루 테마", - "黑色主題": "다크 모드", - "顯示語言": "표시 언어", - "此選項可以選擇顯示語言": "응용 프로그램 표시 언어를 선택합니다", - "重置選項": "옵션 초기화", - "此選項可以重置所有設定": "모든 설정을 기본값으로 되돌립니다", - "執行": "실행", - "產品金鑰": "제품 키", - "此選項可以啟用產品金鑰": "제품 키를 활성화합니다", - "官方網站": "공식 웹사이트", - "此選項可以前往官方網站": "공식 웹사이트를 방문합니다", - "檢查更新": "업데이트 확인", - "此選項可以檢查可用更新": "사용 가능한 최신 업데이트를 확인합니다", - "搜尋進程...": "프로세스 검색...", - "查看": "보기", - "結束": "작업 끝내기", - "白名單管理": "화이트리스트 관리", - "搜尋檔案...": "파일 검색...", - "加入": "추가", - "移除": "제거", - "隔離區管理": "격리소 관리", - "掃描": "스캔", - "搜尋窗口...": "창 검색...", - "搜尋規則...": "규칙 검색...", - "搜尋日誌...": "로그 검색...", - "導出": "내보내기", - "正在初始化中": "초기화 중...", - "檢查更新失敗": "업데이트 확인 실패", - "發現新版本": "새 버전을 찾았습니다", - "當前已是最新版本": "현재 최신 버전입니다", - "請選擇要導出的日誌": "내보낼 로그를 선택하십시오", - "確定刪除選取的日誌記錄嗎?": "선택한 로그를 삭제하시겠습니까?", - "選取的日誌已刪除。": "선택한 로그가 삭제되었습니다.", - "結束進程?": "프로세스를 종료하시겠습니까?", - "確定要結束選取的進程嗎?": "선택한 프로세스를 종료하시겠습니까?", - "已清理 ": "정리 완료 ", - "設定已重置,請重新啟動程式以套用預設值。": "설정이 초기화되었습니다. 기본값을 적용하려면 프로그램을 다시 시작하십시오.", - "導出成功": "내보내기 성공", - "選取進程路徑:\n": "선택된 프로세스 경로:\n", - "對 ": "대상: ", - " 執行動作:\n1: 加入白名單\n2: 加入隔離區\n請輸入代碼:": "에 대한 작업:\n1: 화이트리스트에 추가\n2: 격리소에 추가\n코드를 입력하십시오:", - "請在5秒內點擊目標視窗...": "5초 이내에 대상 창을 클릭하십시오...", - "確認攔截": "차단 확인", - "已修復選取項目": "선택한 항목이 복구되었습니다", - "修復": "복구", - "提示": "프롬프트", - "錯誤": "오류", - "未知路徑": "알 수 없는 경로", - "修復系統 MBR": "시스템 MBR 복구", - "修復系統限制": "시스템 제한 복구", - "修復檔案關聯": "파일 연결 복구", - "修復檔案圖標": "파일 아이콘 복구", - "修復映像劫持": "이미지 하이재킹 복구", - "修復桌面壁紙": "바탕 화면 배경 복구", - "正在掃描": "스캔 중...", - "正在刪除": "삭제 중...", - "選單掃描": "컨텍스트 메뉴 스캔", - "此選項可以啟用右鍵掃描功能": "우클릭 스캔 기능을 활성화합니다", - "刪除項目": "항목 삭제", - "忽略項目": "항목 무시", - "加入隔離區": "격리소에 추가", - "加入白名單": "화이트리스트에 추가", - "日期": "날짜", - "類型": "유형", - "功能": "기능", - "路徑": "경로", - "名稱": "이름", - "PID": "PID", - "大小": "크기", - "程式": "프로그램", - "類別": "클래스", - "標題": "제목", - "修復項目": "복구 항목", - "全選": "전체 선택", - "打開檔案所在位置": "파일 위치 열기" + "app_name": "PYAS Security", + "status_protected": "이 장치는 보호되고 있습니다", + "scan_smart": "스마트 스캔", + "scan_smart_desc": "디바이스 보안을 빠르게 스캔합니다", + "log_export": "로그 내보내기", + "log_export_desc": "로그를 필터링하고 아카이브로 내보냅니다", + "scan_virus": "바이러스 스캔", + "scan_virus_desc": "고급 스캔 방법을 선택합니다", + "btn_delete": "삭제", + "btn_select": "선택", + "scan_file": "파일 스캔", + "scan_path": "경로 스캔", + "scan_full": "전체 스캔", + "btn_stop": "정지", + "protect_proc": "프로세스 보호", + "protect_proc_desc": "악성 프로세스 실행을 종료합니다", + "protect_file": "파일 보호", + "protect_file_desc": "악성 파일 생성을 격리합니다", + "protect_sys": "시스템 보호", + "protect_sys_desc": "시스템 이상을 실시간으로 복구합니다", + "protect_drv": "드라이버 보호", + "protect_drv_desc": "악의적인 행동을 실시간으로 차단합니다", + "protect_net": "네트워크 보호", + "protect_net_desc": "악의적인 네트워크 연결을 차단합니다", + "protect_custom": "사용자 지정 보호", + "protect_custom_desc": "사용자 지정 보호 규칙을 가져옵니다", + "manage_proc": "프로세스 관리", + "manage_proc_desc": "실시간으로 시스템 프로세스를 모니터링합니다", + "clean_junk": "정크 정리", + "clean_junk_desc": "임시 파일 및 정크 파일을 정리합니다", + "repair_sys": "시스템 복구", + "repair_sys_desc": "시스템 레지스트리 항목을 복구합니다", + "block_popup": "팝업 차단", + "block_popup_desc": "특정 팝업 창을 차단합니다", + "list_white": "화이트리스트", + "list_white_desc": "화이트리스트를 보고 관리합니다", + "list_quarantine": "격리소", + "list_quarantine_desc": "격리 구역을 보고 관리합니다", + "mode_enhance": "고급 모드", + "mode_enhance_desc": "정적 스캔 엔진을 강화합니다", + "engine_ext": "확장 엔진", + "engine_ext_desc": "확장 규칙 엔진을 활성화합니다", + "service_cloud": "클라우드 서비스", + "service_cloud_desc": "의심스러운 파일을 자동으로 보고합니다", + "scan_context": "컨텍스트 메뉴 스캔", + "scan_context_desc": "우클릭 스캔 기능을 활성화합니다", + "theme_color": "색상 테마", + "theme_color_desc": "응용 프로그램 테마 색상을 선택합니다", + "theme_white": "라이트 모드", + "theme_red": "레드 테마", + "theme_yellow": "옐로우 테마", + "theme_green": "그린 테마", + "theme_blue": "블루 테마", + "theme_black": "다크 모드", + "lang_display": "표시 언어", + "lang_display_desc": "응용 프로그램 표시 언어를 선택합니다", + "opt_reset": "옵션 초기화", + "opt_reset_desc": "모든 설정을 기본값으로 되돌립니다", + "btn_execute": "실행", + "key_product": "제품 키", + "key_product_desc": "제품 키를 활성화합니다", + "web_official": "공식 웹사이트", + "web_official_desc": "공식 웹사이트를 방문합니다", + "update_check": "업데이트 확인", + "update_check_desc": "사용 가능한 최신 업데이트를 확인합니다", + "search_proc": "프로세스 검색...", + "btn_view": "보기", + "btn_end": "작업 끝내기", + "manage_white": "화이트리스트 관리", + "search_file": "파일 검색...", + "btn_add": "추가", + "btn_remove": "제거", + "manage_quarantine": "격리소 관리", + "btn_scan": "스캔", + "search_window": "창 검색...", + "search_rule": "규칙 검색...", + "search_log": "로그 검색...", + "btn_export": "내보내기", + "msg_init": "초기화 중...", + "msg_update_fail": "업데이트 확인 실패", + "msg_new_version": "새 버전을 찾았습니다", + "msg_latest_version": "현재 최신 버전입니다", + "msg_sel_log_export": "내보낼 로그를 선택하십시오", + "msg_del_log_confirm": "선택한 로그를 삭제하시겠습니까?", + "msg_log_deleted": "선택한 로그가 삭제되었습니다.", + "msg_end_proc_title": "프로세스를 종료하시겠습니까?", + "msg_end_proc_confirm": "선택한 프로세스를 종료하시겠습니까?", + "msg_cleaned": "정리 완료 ", + "msg_reset_success": "설정이 초기화되었습니다. 기본값을 적용하려면 프로그램을 다시 시작하십시오.", + "msg_export_success": "내보내기 성공", + "msg_sel_proc_path": "선택된 프로세스 경로:\n", + "msg_action_for": "대상: ", + "msg_action_opts": "에 대한 작업:\n1: 화이트리스트에 추가\n2: 격리소에 추가\n코드를 입력하십시오:", + "msg_click_target": "5초 이내에 대상 창을 클릭하십시오...", + "msg_confirm_block": "차단 확인", + "msg_repaired": "선택한 항목이 복구되었습니다", + "btn_repair": "복구", + "title_prompt": "프롬프트", + "title_error": "오류", + "path_unknown": "알 수 없는 경로", + "repair_mbr": "시스템 MBR 복구", + "repair_limit": "시스템 제한 복구", + "repair_assoc": "파일 연결 복구", + "repair_icon": "파일 아이콘 복구", + "repair_hijack": "이미지 하이재킹 복구", + "repair_wallpaper": "바탕 화면 배경 복구", + "status_scanning": "스캔 중...", + "status_deleting": "삭제 중...", + "act_del": "항목 삭제", + "act_ignore": "항목 무시", + "act_quarantine": "격리소에 추가", + "act_white": "화이트리스트에 추가", + "col_date": "날짜", + "col_type": "유형", + "col_func": "기능", + "col_path": "경로", + "col_name": "이름", + "col_pid": "PID", + "col_size": "크기", + "col_prog": "프로그램", + "col_class": "클래스", + "col_title": "제목", + "col_repair": "복구 항목", + "btn_select_all": "전체 선택", + "ctx_open_loc": "파일 위치 열기", + "msg_too_many": "(데이터가 너무 많아 성능 유지를 위해 상위 {0}개만 표시합니다)", + "res_scan_comp": "스캔 완료", + "res_virus_det": "바이러스 발견", + "res_proc_block": "프로세스 차단", + "res_file_block": "파일 차단", + "res_net_block": "네트워크 차단", + "res_drv_block": "드라이버 차단", + "res_sys_repair": "시스템 복구", + "res_cfg_update": "설정 업데이트" }, "french_switch": { - "PYAS Security": "PYAS Security", - "此裝置已受到防護": "Cet appareil est protégé", - "智能掃描": "Analyse intelligente", - "此選項可以快速掃描裝置安全性": "Analyser rapidement la sécurité de l'appareil", - "日誌導出": "Exporter les journaux", - "此選項可以篩選日誌並匯出存檔": "Filtrer les journaux et les exporter vers l'archive", - "病毒掃描": "Analyse antivirus", - "此選項可以選擇進階掃描方式": "Sélectionnez une méthode d'analyse avancée", - "刪除": "Supprimer", - "選擇": "Sélectionner", - "檔案掃描": "Analyse de fichier", - "路徑掃描": "Analyse de chemin", - "全盤掃描": "Analyse complète", - "停止": "Arrêter", - "進程防護": "Protection des processus", - "此選項可以終止惡意進程運行": "Mettre fin à l'exécution de processus malveillants", - "檔案防護": "Protection des fichiers", - "此選項可以隔離惡意檔案建立": "Mettre en quarantaine la création de fichiers malveillants", - "系統防護": "Protection du système", - "此選項可以實時修復系統異常": "Réparation en temps réel des anomalies du système", - "驅動防護": "Protection des pilotes", - "此選項可以實時攔截惡意行為": "Interception en temps réel des comportements malveillants", - "網路防護": "Protection réseau", - "此選項可以攔截惡意網路連接": "Bloquer les connexions réseau malveillantes", - "自訂防護": "Protection personnalisée", - "此選項可以導入自訂防護規則": "Importer des règles de protection personnalisées", - "進程管理": "Gestionnaire de processus", - "此選項可以實時查看系統進程": "Surveille les processus système en temps réel", - "垃圾清理": "Nettoyage des déchets", - "此選項可以清理暫存垃圾檔案": "Nettoie les fichiers temporaires et inutiles", - "系統修復": "Réparation du système", - "此選項可以修復系統註冊項目": "Répare les éléments du registre système", - "彈窗攔截": "Bloqueur de fenêtres contextuelles", - "此選項可以選擇指定窗口攔截": "Bloque les fenêtres contextuelles spécifiques", - "白名單": "Liste blanche", - "此選項可以查看並管理白名單": "Afficher et gérer la liste blanche", - "隔離區": "Quarantaine", - "此選項可以查看並管理隔離區": "Afficher et gérer la zone de quarantaine", - "增強模式": "Mode amélioré", - "此選項可以增強靜態掃描引擎": "Améliorer le moteur d'analyse statique", - "擴展引擎": "Moteur d'extension", - "此選項可以使用擴展規則引擎": "Activer les moteurs de règles d'extension", - "雲端服務": "Service cloud", - "此選項可以自動上報可疑檔案": "Signaler automatiquement les fichiers suspects", - "顯色主題": "Thème de couleur", - "此選項可以選擇主題顏色": "Sélectionnez le thème de couleur de l'application", - "白色主題": "Mode clair", - "紅色主題": "Thème rouge", - "黃色主題": "Thème jaune", - "綠色主題": "Thème vert", - "藍色主題": "Thème bleu", - "黑色主題": "Mode sombre", - "顯示語言": "Langue d'affichage", - "此選項可以選擇顯示語言": "Sélectionnez la langue d'affichage", - "重置選項": "Réinitialiser", - "此選項可以重置所有設定": "Restaurer tous les paramètres par défaut", - "執行": "Exécuter", - "產品金鑰": "Clé de produit", - "此選項可以啟用產品金鑰": "Activer votre clé de produit", - "官方網站": "Site officiel", - "此選項可以前往官方網站": "Visitez notre site officiel", - "檢查更新": "Vérifier les mises à jour", - "此選項可以檢查可用更新": "Vérifier les dernières mises à jour", - "搜尋進程...": "Rechercher des processus...", - "查看": "Voir", - "結束": "Fin de tâche", - "白名單管理": "Gestionnaire de liste blanche", - "搜尋檔案...": "Rechercher des fichiers...", - "加入": "Ajouter", - "移除": "Retirer", - "隔離區管理": "Gestionnaire de quarantaine", - "掃描": "Analyser", - "搜尋窗口...": "Rechercher des fenêtres...", - "搜尋規則...": "Rechercher des règles...", - "搜尋日誌...": "Rechercher des journaux...", - "導出": "Exporter", - "正在初始化中": "Initialisation...", - "檢查更新失敗": "Échec de la vérification des mises à jour", - "發現新版本": "Nouvelle version trouvée", - "當前已是最新版本": "Actuellement à la dernière version", - "請選擇要導出的日誌": "Veuillez sélectionner les journaux à exporter", - "確定刪除選取的日誌記錄嗎?": "Êtes-vous sûr de vouloir supprimer les journaux sélectionnés ?", - "選取的日誌已刪除。": "Les journaux sélectionnés ont été supprimés.", - "結束進程?": "Terminer le processus ?", - "確定要結束選取的進程嗎?": "Êtes-vous sûr de vouloir terminer les processus sélectionnés ?", - "已清理 ": "Nettoyé ", - "設定已重置,請重新啟動程式以套用預設值。": "Paramètres réinitialisés. Veuillez redémarrer l'application.", - "導出成功": "Exportation réussie", - "選取進程路徑:\n": "Chemins des processus sélectionnés :\n", - "對 ": "Action pour ", - " 執行動作:\n1: 加入白名單\n2: 加入隔離區\n請輸入代碼:": " :\n1 : Ajouter à la liste blanche\n2 : Ajouter à la quarantaine\nEntrez le code :", - "請在5秒內點擊目標視窗...": "Cliquez sur la fenêtre cible dans les 5s...", - "確認攔截": "Confirmer le blocage", - "已修復選取項目": "Éléments sélectionnés réparés", - "修復": "Réparer", - "提示": "Indication", - "錯誤": "Erreur", - "未知路徑": "Chemin inconnu", - "修復系統 MBR": "Réparer le MBR du système", - "修復系統限制": "Réparer les restrictions du système", - "修復檔案關聯": "Réparer les associations de fichiers", - "修復檔案圖標": "Réparer les icônes de fichiers", - "修復映像劫持": "Réparer le détournement d'image", - "修復桌面壁紙": "Réparer le fond d'écran du bureau", - "正在掃描": "Analyse en cours...", - "正在刪除": "Suppression en cours...", - "選單掃描": "Analyse du menu contextuel", - "此選項可以啟用右鍵掃描功能": "Activer la fonctionnalité d'analyse par clic droit", - "刪除項目": "Supprimer les éléments", - "忽略項目": "Ignorer les éléments", - "加入隔離區": "Ajouter à la quarantaine", - "加入白名單": "Ajouter à la liste blanche", - "日期": "Date", - "類型": "Type", - "功能": "Fonction", - "路徑": "Chemin", - "名稱": "Nom", - "PID": "PID", - "大小": "Taille", - "程式": "Programme", - "類別": "Classe", - "標題": "Titre", - "修復項目": "Éléments de réparation", - "全選": "Tout sélectionner", - "打開檔案所在位置": "Ouvrir l'emplacement du fichier" + "app_name": "PYAS Security", + "status_protected": "Cet appareil est protégé", + "scan_smart": "Analyse intelligente", + "scan_smart_desc": "Analyser rapidement la sécurité de l'appareil", + "log_export": "Exporter les journaux", + "log_export_desc": "Filtrer les journaux et les exporter vers l'archive", + "scan_virus": "Analyse antivirus", + "scan_virus_desc": "Sélectionnez une méthode d'analyse avancée", + "btn_delete": "Supprimer", + "btn_select": "Sélectionner", + "scan_file": "Analyse de fichier", + "scan_path": "Analyse de chemin", + "scan_full": "Analyse complète", + "btn_stop": "Arrêter", + "protect_proc": "Protection des processus", + "protect_proc_desc": "Mettre fin à l'exécution de processus malveillants", + "protect_file": "Protection des fichiers", + "protect_file_desc": "Mettre en quarantaine la création de fichiers malveillants", + "protect_sys": "Protection du système", + "protect_sys_desc": "Réparation en temps réel des anomalies du système", + "protect_drv": "Protection des pilotes", + "protect_drv_desc": "Interception en temps réel des comportements malveillants", + "protect_net": "Protection réseau", + "protect_net_desc": "Bloquer les connexions réseau malveillantes", + "protect_custom": "Protection personnalisée", + "protect_custom_desc": "Importer des règles de protection personnalisées", + "manage_proc": "Gestionnaire de processus", + "manage_proc_desc": "Surveille les processus système en temps réel", + "clean_junk": "Nettoyage des déchets", + "clean_junk_desc": "Nettoie les fichiers temporaires et inutiles", + "repair_sys": "Réparation du système", + "repair_sys_desc": "Répare les éléments du registre système", + "block_popup": "Bloqueur de fenêtres contextuelles", + "block_popup_desc": "Bloque les fenêtres contextuelles spécifiques", + "list_white": "Liste blanche", + "list_white_desc": "Afficher et gérer la liste blanche", + "list_quarantine": "Quarantaine", + "list_quarantine_desc": "Afficher et gérer la zone de quarantaine", + "mode_enhance": "Mode amélioré", + "mode_enhance_desc": "Améliorer le moteur d'analyse statique", + "engine_ext": "Moteur d'extension", + "engine_ext_desc": "Activer les moteurs de règles d'extension", + "service_cloud": "Service cloud", + "service_cloud_desc": "Signaler automatiquement les fichiers suspects", + "scan_context": "Analyse du menu contextuel", + "scan_context_desc": "Activer la fonctionnalité d'analyse par clic droit", + "theme_color": "Thème de couleur", + "theme_color_desc": "Sélectionnez le thème de couleur de l'application", + "theme_white": "Mode clair", + "theme_red": "Thème rouge", + "theme_yellow": "Thème jaune", + "theme_green": "Thème vert", + "theme_blue": "Thème bleu", + "theme_black": "Mode sombre", + "lang_display": "Langue d'affichage", + "lang_display_desc": "Sélectionnez la langue d'affichage", + "opt_reset": "Réinitialiser", + "opt_reset_desc": "Restaurer tous les paramètres par défaut", + "btn_execute": "Exécuter", + "key_product": "Clé de produit", + "key_product_desc": "Activer votre clé de produit", + "web_official": "Site officiel", + "web_official_desc": "Visitez notre site officiel", + "update_check": "Vérifier les mises à jour", + "update_check_desc": "Vérifier les dernières mises à jour", + "search_proc": "Rechercher des processus...", + "btn_view": "Voir", + "btn_end": "Fin de tâche", + "manage_white": "Gestionnaire de liste blanche", + "search_file": "Rechercher des fichiers...", + "btn_add": "Ajouter", + "btn_remove": "Retirer", + "manage_quarantine": "Gestionnaire de quarantaine", + "btn_scan": "Analyser", + "search_window": "Rechercher des fenêtres...", + "search_rule": "Rechercher des règles...", + "search_log": "Rechercher des journaux...", + "btn_export": "Exporter", + "msg_init": "Initialisation...", + "msg_update_fail": "Échec de la vérification des mises à jour", + "msg_new_version": "Nouvelle version trouvée", + "msg_latest_version": "Actuellement à la dernière version", + "msg_sel_log_export": "Veuillez sélectionner les journaux à exporter", + "msg_del_log_confirm": "Êtes-vous sûr de vouloir supprimer les journaux sélectionnés ?", + "msg_log_deleted": "Les journaux sélectionnés ont été supprimés.", + "msg_end_proc_title": "Terminer le processus ?", + "msg_end_proc_confirm": "Êtes-vous sûr de vouloir terminer les processus sélectionnés ?", + "msg_cleaned": "Nettoyé ", + "msg_reset_success": "Paramètres réinitialisés. Veuillez redémarrer l'application.", + "msg_export_success": "Exportation réussie", + "msg_sel_proc_path": "Chemins des processus sélectionnés :\n", + "msg_action_for": "Action pour ", + "msg_action_opts": " :\n1 : Ajouter à la liste blanche\n2 : Ajouter à la quarantaine\nEntrez le code :", + "msg_click_target": "Cliquez sur la fenêtre cible dans les 5s...", + "msg_confirm_block": "Confirmer le blocage", + "msg_repaired": "Éléments sélectionnés réparés", + "btn_repair": "Réparer", + "title_prompt": "Indication", + "title_error": "Erreur", + "path_unknown": "Chemin inconnu", + "repair_mbr": "Réparer le MBR du système", + "repair_limit": "Réparer les restrictions du système", + "repair_assoc": "Réparer les associations de fichiers", + "repair_icon": "Réparer les icônes de fichiers", + "repair_hijack": "Réparer le détournement d'image", + "repair_wallpaper": "Réparer le fond d'écran du bureau", + "status_scanning": "Analyse en cours...", + "status_deleting": "Suppression en cours...", + "act_del": "Supprimer les éléments", + "act_ignore": "Ignorer les éléments", + "act_quarantine": "Ajouter à la quarantaine", + "act_white": "Ajouter à la liste blanche", + "col_date": "Date", + "col_type": "Type", + "col_func": "Fonction", + "col_path": "Chemin", + "col_name": "Nom", + "col_pid": "PID", + "col_size": "Taille", + "col_prog": "Programme", + "col_class": "Classe", + "col_title": "Titre", + "col_repair": "Éléments de réparation", + "btn_select_all": "Tout sélectionner", + "ctx_open_loc": "Ouvrir l'emplacement du fichier", + "msg_too_many": "(Trop de données, affichage des {0} premiers enregistrements pour des raisons de performances)", + "res_scan_comp": "Analyse terminée", + "res_virus_det": "Virus détecté", + "res_proc_block": "Processus bloqué", + "res_file_block": "Fichier bloqué", + "res_net_block": "Réseau bloqué", + "res_drv_block": "Pilote bloqué", + "res_sys_repair": "Réparation du système", + "res_cfg_update": "Mise à jour de la configuration" }, "spanish_switch": { - "PYAS Security": "PYAS Security", - "此裝置已受到防護": "Este dispositivo está protegido", - "智能掃描": "Escaneo inteligente", - "此選項可以快速掃描裝置安全性": "Escanear rápidamente la seguridad del dispositivo", - "日誌導出": "Exportar registros", - "此選項可以篩選日誌並匯出存檔": "Filtrar registros y exportar a un archivo", - "病毒掃描": "Escaneo de virus", - "此選項可以選擇進階掃描方式": "Seleccione un método de escaneo avanzado", - "刪除": "Eliminar", - "選擇": "Seleccionar", - "檔案掃描": "Escaneo de archivos", - "路徑掃描": "Escaneo de ruta", - "全盤掃描": "Escaneo completo", - "停止": "Detener", - "進程防護": "Protección de procesos", - "此選項可以終止惡意進程運行": "Terminar la ejecución de procesos maliciosos", - "檔案防護": "Protección de archivos", - "此選項可以隔離惡意檔案建立": "Poner en cuarentena la creación de archivos maliciosos", - "系統防護": "Protección del sistema", - "此選項可以實時修復系統異常": "Reparación en tiempo real de anomalías del sistema", - "驅動防護": "Protección de controladores", - "此選項可以實時攔截惡意行為": "Interceptación en tiempo real de comportamientos maliciosos", - "網路防護": "Protección de red", - "此選項可以攔截惡意網路連接": "Bloquear conexiones de red maliciosas", - "自訂防護": "Protección personalizada", - "此選項可以導入自訂防護規則": "Importar reglas de protección personalizadas", - "進程管理": "Administrador de procesos", - "此選項可以實時查看系統進程": "Monitorea procesos del sistema en tiempo real", - "垃圾清理": "Limpieza de basura", - "此選項可以清理暫存垃圾檔案": "Limpia archivos temporales y basura", - "系統修復": "Reparación del sistema", - "此選項可以修復系統註冊項目": "Repara elementos del registro del sistema", - "彈窗攔截": "Bloqueador de ventanas emergentes", - "此選項可以選擇指定窗口攔截": "Bloquea ventanas emergentes específicas", - "白名單": "Lista blanca", - "此選項可以查看並管理白名單": "Ver y administrar la lista blanca", - "隔離區": "Cuarentena", - "此選項可以查看並管理隔離區": "Ver y administrar la zona de cuarentena", - "增強模式": "Modo mejorado", - "此選項可以增強靜態掃描引擎": "Mejorar el motor de escaneo estático", - "擴展引擎": "Motor de extensión", - "此選項可以使用擴展規則引擎": "Habilitar motores de reglas de extensión", - "雲端服務": "Servicio en la nube", - "此選項可以自動上報可疑檔案": "Reportar automáticamente archivos sospechosos", - "顯色主題": "Tema de color", - "此選項可以選擇主題顏色": "Seleccione el tema de color de la aplicación", - "白色主題": "Modo claro", - "紅色主題": "Tema rojo", - "黃色主題": "Tema amarillo", - "綠色主題": "Tema verde", - "藍色主題": "Tema azul", - "黑色主題": "Modo oscuro", - "顯示語言": "Idioma de visualización", - "此選項可以選擇顯示語言": "Seleccione el idioma de visualización", - "重置選項": "Restablecer", - "此選項可以重置所有設定": "Restaurar todos los ajustes predeterminados", - "執行": "Ejecutar", - "產品金鑰": "Clave de producto", - "此選項可以啟用產品金鑰": "Activar clave de producto", - "官方網站": "Sitio web oficial", - "此選項可以前往官方網站": "Visite nuestro sitio web oficial", - "檢查更新": "Buscar actualizaciones", - "此選項可以檢查可用更新": "Comprobar las últimas actualizaciones", - "搜尋進程...": "Buscar procesos...", - "查看": "Ver", - "結束": "Finalizar tarea", - "白名單管理": "Gestor de lista blanca", - "搜尋檔案...": "Buscar archivos...", - "加入": "Añadir", - "移除": "Eliminar", - "隔離區管理": "Gestor de cuarentena", - "掃描": "Escanear", - "搜尋窗口...": "Buscar ventanas...", - "搜尋規則...": "Buscar reglas...", - "搜尋日誌...": "Buscar registros...", - "導出": "Exportar", - "正在初始化中": "Inicializando...", - "檢查更新失敗": "Fallo al buscar actualizaciones", - "發現新版本": "Nueva versión encontrada", - "當前已是最新版本": "Actualmente en la última versión", - "請選擇要導出的日誌": "Seleccione los registros a exportar", - "確定刪除選取的日誌記錄嗎?": "¿Seguro que desea eliminar los registros seleccionados?", - "選取的日誌已刪除。": "Los registros seleccionados han sido eliminados.", - "結束進程?": "¿Finalizar proceso?", - "確定要結束選取的進程嗎?": "¿Seguro que desea finalizar los procesos seleccionados?", - "已清理 ": "Limpiado ", - "設定已重置,請重新啟動程式以套用預設值。": "Ajustes restablecidos. Reinicie la aplicación.", - "導出成功": "Exportación exitosa", - "選取進程路徑:\n": "Rutas de procesos seleccionados:\n", - "對 ": "Acción para ", - " 執行動作:\n1: 加入白名單\n2: 加入隔離區\n請輸入代碼:": ":\n1: Añadir a la lista blanca\n2: Añadir a la cuarentena\nIngrese código:", - "請在5秒內點擊目標視窗...": "Haga clic en la ventana objetivo en 5s...", - "確認攔截": "Confirmar bloqueo", - "已修復選取項目": "Elementos seleccionados reparados", - "修復": "Reparar", - "提示": "Aviso", - "錯誤": "Error", - "未知路徑": "Ruta desconocida", - "修復系統 MBR": "Reparar MBR del sistema", - "修復系統限制": "Reparar restricciones del sistema", - "修復檔案關聯": "Reparar asociaciones de archivos", - "修復檔案圖標": "Reparar iconos de archivos", - "修復映像劫持": "Reparar secuestro de imagen", - "修復桌面壁紙": "Reparar fondo de escritorio", - "正在掃描": "Escaneando...", - "正在刪除": "Eliminando...", - "選單掃描": "Escaneo de menú contextual", - "此選項可以啟用右鍵掃描功能": "Habilitar la función de escaneo con el botón derecho", - "刪除項目": "Eliminar elementos", - "忽略項目": "Ignorar elementos", - "加入隔離區": "Añadir a la cuarentena", - "加入白名單": "Añadir a la lista blanca", - "日期": "Fecha", - "類型": "Tipo", - "功能": "Función", - "路徑": "Ruta", - "名稱": "Nombre", - "PID": "PID", - "大小": "Tamaño", - "程式": "Programa", - "類別": "Clase", - "標題": "Título", - "修復項目": "Elementos de reparación", - "全選": "Seleccionar todo", - "打開檔案所在位置": "Abrir ubicación de archivo" + "app_name": "PYAS Security", + "status_protected": "Este dispositivo está protegido", + "scan_smart": "Escaneo inteligente", + "scan_smart_desc": "Escanear rápidamente la seguridad del dispositivo", + "log_export": "Exportar registros", + "log_export_desc": "Filtrar registros y exportar a un archivo", + "scan_virus": "Escaneo de virus", + "scan_virus_desc": "Seleccione un método de escaneo avanzado", + "btn_delete": "Eliminar", + "btn_select": "Seleccionar", + "scan_file": "Escaneo de archivos", + "scan_path": "Escaneo de ruta", + "scan_full": "Escaneo completo", + "btn_stop": "Detener", + "protect_proc": "Protección de procesos", + "protect_proc_desc": "Terminar la ejecución de procesos maliciosos", + "protect_file": "Protección de archivos", + "protect_file_desc": "Poner en cuarentena la creación de archivos maliciosos", + "protect_sys": "Protección del sistema", + "protect_sys_desc": "Reparación en tiempo real de anomalías del sistema", + "protect_drv": "Protección de controladores", + "protect_drv_desc": "Interceptación en tiempo real de comportamientos maliciosos", + "protect_net": "Protección de red", + "protect_net_desc": "Bloquear conexiones de red maliciosas", + "protect_custom": "Protección personalizada", + "protect_custom_desc": "Importar reglas de protección personalizadas", + "manage_proc": "Administrador de procesos", + "manage_proc_desc": "Monitorea procesos del sistema en tiempo real", + "clean_junk": "Limpieza de basura", + "clean_junk_desc": "Limpia archivos temporales y basura", + "repair_sys": "Reparación del sistema", + "repair_sys_desc": "Repara elementos del registro del sistema", + "block_popup": "Bloqueador de ventanas emergentes", + "block_popup_desc": "Bloquea ventanas emergentes específicas", + "list_white": "Lista blanca", + "list_white_desc": "Ver y administrar la lista blanca", + "list_quarantine": "Cuarentena", + "list_quarantine_desc": "Ver y administrar la zona de cuarentena", + "mode_enhance": "Modo mejorado", + "mode_enhance_desc": "Mejorar el motor de escaneo estático", + "engine_ext": "Motor de extensión", + "engine_ext_desc": "Habilitar motores de reglas de extensión", + "service_cloud": "Servicio en la nube", + "service_cloud_desc": "Reportar automáticamente archivos sospechosos", + "scan_context": "Escaneo de menú contextual", + "scan_context_desc": "Habilitar la función de escaneo con el botón derecho", + "theme_color": "Tema de color", + "theme_color_desc": "Seleccione el tema de color de la aplicación", + "theme_white": "Modo claro", + "theme_red": "Tema rojo", + "theme_yellow": "Tema amarillo", + "theme_green": "Tema verde", + "theme_blue": "Tema azul", + "theme_black": "Modo oscuro", + "lang_display": "Idioma de visualización", + "lang_display_desc": "Seleccione el idioma de visualización", + "opt_reset": "Restablecer", + "opt_reset_desc": "Restaurar todos los ajustes predeterminados", + "btn_execute": "Ejecutar", + "key_product": "Clave de producto", + "key_product_desc": "Activar clave de producto", + "web_official": "Sitio web oficial", + "web_official_desc": "Visite nuestro sitio web oficial", + "update_check": "Buscar actualizaciones", + "update_check_desc": "Comprobar las últimas actualizaciones", + "search_proc": "Buscar procesos...", + "btn_view": "Ver", + "btn_end": "Finalizar tarea", + "manage_white": "Gestor de lista blanca", + "search_file": "Buscar archivos...", + "btn_add": "Añadir", + "btn_remove": "Eliminar", + "manage_quarantine": "Gestor de cuarentena", + "btn_scan": "Escanear", + "search_window": "Buscar ventanas...", + "search_rule": "Buscar reglas...", + "search_log": "Buscar registros...", + "btn_export": "Exportar", + "msg_init": "Inicializando...", + "msg_update_fail": "Fallo al buscar actualizaciones", + "msg_new_version": "Nueva versión encontrada", + "msg_latest_version": "Actualmente en la última versión", + "msg_sel_log_export": "Seleccione los registros a exportar", + "msg_del_log_confirm": "¿Seguro que desea eliminar los registros seleccionados?", + "msg_log_deleted": "Los registros seleccionados han sido eliminados.", + "msg_end_proc_title": "¿Finalizar proceso?", + "msg_end_proc_confirm": "¿Seguro que desea finalizar los procesos seleccionados?", + "msg_cleaned": "Limpiado ", + "msg_reset_success": "Ajustes restablecidos. Reinicie la aplicación.", + "msg_export_success": "Exportación exitosa", + "msg_sel_proc_path": "Rutas de procesos seleccionados:\n", + "msg_action_for": "Acción para ", + "msg_action_opts": ":\n1: Añadir a la lista blanca\n2: Añadir a la cuarentena\nIngrese código:", + "msg_click_target": "Haga clic en la ventana objetivo en 5s...", + "msg_confirm_block": "Confirmar bloqueo", + "msg_repaired": "Elementos seleccionados reparados", + "btn_repair": "Reparar", + "title_prompt": "Aviso", + "title_error": "Error", + "path_unknown": "Ruta desconocida", + "repair_mbr": "Reparar MBR del sistema", + "repair_limit": "Reparar restricciones del sistema", + "repair_assoc": "Reparar asociaciones de archivos", + "repair_icon": "Reparar iconos de archivos", + "repair_hijack": "Reparar secuestro de imagen", + "repair_wallpaper": "Reparar fondo de escritorio", + "status_scanning": "Escaneando...", + "status_deleting": "Eliminando...", + "act_del": "Eliminar elementos", + "act_ignore": "Ignorar elementos", + "act_quarantine": "Añadir a la cuarentena", + "act_white": "Añadir a la lista blanca", + "col_date": "Fecha", + "col_type": "Tipo", + "col_func": "Función", + "col_path": "Ruta", + "col_name": "Nombre", + "col_pid": "PID", + "col_size": "Tamaño", + "col_prog": "Programa", + "col_class": "Clase", + "col_title": "Título", + "col_repair": "Elementos de reparación", + "btn_select_all": "Seleccionar todo", + "ctx_open_loc": "Abrir ubicación de archivo", + "msg_too_many": "(Demasiados datos, mostrando solo los primeros {0} registros para mantener el rendimiento)", + "res_scan_comp": "Escaneo completado", + "res_virus_det": "Virus detectado", + "res_proc_block": "Proceso bloqueado", + "res_file_block": "Archivo bloqueado", + "res_net_block": "Red bloqueada", + "res_drv_block": "Controlador bloqueado", + "res_sys_repair": "Reparación del sistema", + "res_cfg_update": "Actualización de configuración" }, "hindi_switch": { - "PYAS Security": "PYAS Security", - "此裝置已受到防護": "यह डिवाइस सुरक्षित है", - "智能掃描": "स्मार्ट स्कैन", - "此選項可以快速掃描裝置安全性": "डिवाइस सुरक्षा को जल्दी स्कैन करें", - "日誌導出": "लॉग निर्यात", - "此選項可以篩選日誌並匯出存檔": "लॉग फ़िल्टर करें और संग्रह में निर्यात करें", - "病毒掃描": "वायरस स्कैन", - "此選項可以選擇進階掃描方式": "एक उन्नत स्कैनिंग विधि चुनें", - "刪除": "हटाएं", - "選擇": "चुनें", - "檔案掃描": "फ़ाइल स्कैन", - "路徑掃描": "पथ स्कैन", - "全盤掃描": "पूर्ण स्कैन", - "停止": "रोकें", - "進程防護": "प्रक्रिया सुरक्षा", - "此選項可以終止惡意進程運行": "दुर्भावनापूर्ण प्रक्रिया निष्पादन को समाप्त करें", - "檔案防護": "फ़ाइल सुरक्षा", - "此選項可以隔離惡意檔案建立": "दुर्भावनापूर्ण फ़ाइल निर्माण को संगरोध करें", - "系統防護": "सिस्टम सुरक्षा", - "此選項可以實時修復系統異常": "सिस्टम विसंगतियों की रीयल-टाइम मरम्मत", - "驅動防護": "ड्राइवर सुरक्षा", - "此選項可以實時攔截惡意行為": "दुर्भावनापूर्ण व्यवहार का रीयल-टाइम अवरोधन", - "網路防護": "नेटवर्क सुरक्षा", - "此選項可以攔截惡意網路連接": "दुर्भावनापूर्ण नेटवर्क कनेक्शन को रोकें", - "自訂防護": "कस्टम सुरक्षा", - "此選項可以導入自訂防護規則": "कस्टम सुरक्षा नियम आयात करें", - "進程管理": "प्रक्रिया प्रबंधक", - "此選項可以實時查看系統進程": "रीयल-टाइम में सिस्टम प्रक्रियाओं की निगरानी करें", - "垃圾清理": "कचरा सफाई", - "此選項可以清理暫存垃圾檔案": "अस्थायी और कचरा फ़ाइलों को साफ़ करें", - "系統修復": "सिस्टम मरम्मत", - "此選項可以修復系統註冊項目": "सिस्टम रजिस्ट्री आइटम की मरम्मत करें", - "彈窗攔截": "पॉपअप ब्लॉकर", - "此選項可以選擇指定窗口攔截": "विशिष्ट पॉपअप विंडो ब्लॉक करें", - "白名單": "श्वेतसूची", - "此選項可以查看並管理白名單": "श्वेतसूची देखें और प्रबंधित करें", - "隔離區": "संगरोध", - "此選項可以查看並管理隔離區": "संगरोध क्षेत्र देखें और प्रबंधित करें", - "增強模式": "उन्नत मोड", - "此選項可以增強靜態掃描引擎": "स्थिर स्कैनिंग इंजन को बढ़ाएं", - "擴展引擎": "विस्तार इंजन", - "此選項可以使用擴展規則引擎": "विस्तार नियम इंजन सक्षम करें", - "雲端服務": "क्लाउड सेवा", - "此選項可以自動上報可疑檔案": "संदिग्ध फ़ाइलों की स्वचालित रूप से रिपोर्ट करें", - "顯色主題": "रंग थीम", - "此選項可以選擇主題顏色": "एप्लिकेशन का रंग थीम चुनें", - "白色主題": "लाइट मोड", - "紅色主題": "लाल थीम", - "黃色主題": "पीला थीम", - "綠色主題": "हरा थीम", - "藍色主題": "नीला थीम", - "黑色主題": "डार्क मोड", - "顯示語言": "प्रदर्शन भाषा", - "此選項可以選擇顯示語言": "एप्लिकेशन प्रदर्शन भाषा चुनें", - "重置選項": "रीसेट विकल्प", - "此選項可以重置所有設定": "सभी सेटिंग्स को डिफ़ॉल्ट पर पुनर्स्थापित करें", - "執行": "निष्पादित करें", - "產品金鑰": "उत्पाद कुंजी", - "此選項可以啟用產品金鑰": "अपनी उत्पाद कुंजी सक्रिय करें", - "官方網站": "आधिकारिक वेबसाइट", - "此選項可以前往官方網站": "हमारी आधिकारिक वेबसाइट पर जाएँ", - "檢查更新": "अद्यतन जाँचे", - "此選項可以檢查可用更新": "नवीनतम अपडेट के लिए जाँचें", - "搜尋進程...": "प्रक्रियाएँ खोजें...", - "查看": "देखें", - "結束": "कार्य समाप्त करें", - "白名單管理": "श्वेतसूची प्रबंधक", - "搜尋檔案...": "फ़ाइलें खोजें...", - "加入": "जोड़ें", - "移除": "निकालें", - "隔離區管理": "संगरोध प्रबंधक", - "掃描": "स्कैन", - "搜尋窗口...": "विंडोज़ खोजें...", - "搜尋規則...": "नियम खोजें...", - "搜尋日誌...": "लॉग खोजें...", - "導出": "निर्यात", - "正在初始化中": "प्रारंभ हो रहा है...", - "檢查更新失敗": "अपडेट की जाँच विफल रही", - "發現新版本": "नया संस्करण मिला", - "當前已是最新版本": "वर्तमान में नवीनतम संस्करण है", - "請選擇要導出的日誌": "कृपया निर्यात करने के लिए लॉग चुनें", - "確定刪除選取的日誌記錄嗎?": "क्या आप वाकई चयनित लॉग हटाना चाहते हैं?", - "選取的日誌已刪除。": "चयनित लॉग हटा दिए गए हैं।", - "結束進程?": "प्रक्रिया समाप्त करें?", - "確定要結束選取的進程嗎?": "क्या आप वाकई चयनित प्रक्रियाओं को समाप्त करना चाहते हैं?", - "已清理 ": "साफ़ किया गया ", - "設定已重置,請重新啟動程式以套用預設值。": "सेटिंग्स रीसेट कर दी गईं। डिफ़ॉल्ट लागू करने के लिए एप्लिकेशन पुनः आरंभ करें।", - "導出成功": "सफलतापूर्वक निर्यात किया गया", - "選取進程路徑:\n": "चयनित प्रक्रिया पथ:\n", - "對 ": "कार्रवाई ", - " 執行動作:\n1: 加入白名單\n2: 加入隔離區\n請輸入代碼:": " के लिए:\n1: श्वेतसूची में जोड़ें\n2: संगरोध में जोड़ें\nकोड दर्ज करें:", - "請在5秒內點擊目標視窗...": "5 सेकंड के भीतर लक्ष्य विंडो पर क्लिक करें...", - "確認攔截": "ब्लॉक की पुष्टि करें", - "已修復選取項目": "चयनित आइटम मरम्मत किए गए", - "修復": "मरम्मत", - "提示": "सुझाव", - "錯誤": "त्रुटि", - "未知路徑": "अज्ञात पथ", - "修復系統 MBR": "सिस्टम MBR की मरम्मत", - "修復系統限制": "सिस्टम प्रतिबंधों की मरम्मत", - "修復檔案關聯": "फ़ाइल संघों की मरम्मत", - "修復檔案圖標": "फ़ाइल आइकन की मरम्मत", - "修復映像劫持": "छवि अपहरण की मरम्मत", - "修復桌面壁紙": "डेस्कटॉप वॉलपेपर की मरम्मत", - "正在掃描": "स्कैन कर रहा है...", - "正在刪除": "हटा रहा है...", - "選單掃描": "संदर्भ मेनू स्कैन", - "此選項可以啟用右鍵掃描功能": "राइट-क्लिक स्कैन कार्यक्षमता सक्षम करें", - "刪除項目": "आइटम हटाएं", - "忽略項目": "आइटम अनदेखा करें", - "加入隔離區": "संगरोध में जोड़ें", - "加入白名單": "श्वेतसूची में जोड़ें", - "日期": "तिथि", - "類型": "प्रकार", - "功能": "कार्य", - "路徑": "पथ", - "名稱": "नाम", - "PID": "PID", - "大小": "आकार", - "程式": "प्रोग्राम", - "類別": "वर्ग", - "標題": "शीर्षक", - "修復項目": "मरम्मत आइटम", - "全選": "सभी चुनें", - "打開檔案所在位置": "फ़ाइल स्थान खोलें" + "app_name": "PYAS Security", + "status_protected": "यह डिवाइस सुरक्षित है", + "scan_smart": "स्मार्ट स्कैन", + "scan_smart_desc": "डिवाइस सुरक्षा को जल्दी स्कैन करें", + "log_export": "लॉग निर्यात", + "log_export_desc": "लॉग फ़िल्टर करें और संग्रह में निर्यात करें", + "scan_virus": "वायरस स्कैन", + "scan_virus_desc": "एक उन्नत स्कैनिंग विधि चुनें", + "btn_delete": "हटाएं", + "btn_select": "चुनें", + "scan_file": "फ़ाइल स्कैन", + "scan_path": "पथ स्कैन", + "scan_full": "पूर्ण स्कैन", + "btn_stop": "रोकें", + "protect_proc": "प्रक्रिया सुरक्षा", + "protect_proc_desc": "दुर्भावनापूर्ण प्रक्रिया निष्पादन को समाप्त करें", + "protect_file": "फ़ाइल सुरक्षा", + "protect_file_desc": "दुर्भावनापूर्ण फ़ाइल निर्माण को संगरोध करें", + "protect_sys": "सिस्टम सुरक्षा", + "protect_sys_desc": "सिस्टम विसंगतियों की रीयल-टाइम मरम्मत", + "protect_drv": "ड्राइवर सुरक्षा", + "protect_drv_desc": "दुर्भावनापूर्ण व्यवहार का रीयल-टाइम अवरोधन", + "protect_net": "नेटवर्क सुरक्षा", + "protect_net_desc": "दुर्भावनापूर्ण नेटवर्क कनेक्शन को रोकें", + "protect_custom": "कस्टम सुरक्षा", + "protect_custom_desc": "कस्टम सुरक्षा नियम आयात करें", + "manage_proc": "प्रक्रिया प्रबंधक", + "manage_proc_desc": "रीयल-टाइम में सिस्टम प्रक्रियाओं की निगरानी करें", + "clean_junk": "कचरा सफाई", + "clean_junk_desc": "अस्थायी और कचरा फ़ाइलों को साफ़ करें", + "repair_sys": "सिस्टम मरम्मत", + "repair_sys_desc": "सिस्टम रजिस्ट्री आइटम की मरम्मत करें", + "block_popup": "पॉपअप ब्लॉकर", + "block_popup_desc": "विशिष्ट पॉपअप विंडो ब्लॉक करें", + "list_white": "श्वेतसूची", + "list_white_desc": "श्वेतसूची देखें और प्रबंधित करें", + "list_quarantine": "संगरोध", + "list_quarantine_desc": "संगरोध क्षेत्र देखें और प्रबंधित करें", + "mode_enhance": "उन्नत मोड", + "mode_enhance_desc": "स्थिर स्कैनिंग इंजन को बढ़ाएं", + "engine_ext": "विस्तार इंजन", + "engine_ext_desc": "विस्तार नियम इंजन सक्षम करें", + "service_cloud": "क्लाउड सेवा", + "service_cloud_desc": "संदिग्ध फ़ाइलों की स्वचालित रूप से रिपोर्ट करें", + "scan_context": "संदर्भ मेनू स्कैन", + "scan_context_desc": "राइट-क्लिक स्कैन कार्यक्षमता सक्षम करें", + "theme_color": "रंग थीम", + "theme_color_desc": "एप्लिकेशन का रंग थीम चुनें", + "theme_white": "लाइट मोड", + "theme_red": "लाल थीम", + "theme_yellow": "पीला थीम", + "theme_green": "हरा थीम", + "theme_blue": "नीला थीम", + "theme_black": "डार्क मोड", + "lang_display": "प्रदर्शन भाषा", + "lang_display_desc": "एप्लिकेशन प्रदर्शन भाषा चुनें", + "opt_reset": "रीसेट विकल्प", + "opt_reset_desc": "सभी सेटिंग्स को डिफ़ॉल्ट पर पुनर्स्थापित करें", + "btn_execute": "निष्पादित करें", + "key_product": "उत्पाद कुंजी", + "key_product_desc": "अपनी उत्पाद कुंजी सक्रिय करें", + "web_official": "आधिकारिक वेबसाइट", + "web_official_desc": "हमारी आधिकारिक वेबसाइट पर जाएँ", + "update_check": "अद्यतन जाँचे", + "update_check_desc": "नवीनतम अपडेट के लिए जाँचें", + "search_proc": "प्रक्रियाएँ खोजें...", + "btn_view": "देखें", + "btn_end": "कार्य समाप्त करें", + "manage_white": "श्वेतसूची प्रबंधक", + "search_file": "फ़ाइलें खोजें...", + "btn_add": "जोड़ें", + "btn_remove": "निकालें", + "manage_quarantine": "संगरोध प्रबंधक", + "btn_scan": "स्कैन", + "search_window": "विंडोज़ खोजें...", + "search_rule": "नियम खोजें...", + "search_log": "लॉग खोजें...", + "btn_export": "निर्यात", + "msg_init": "प्रारंभ हो रहा है...", + "msg_update_fail": "अपडेट की जाँच विफल रही", + "msg_new_version": "नया संस्करण मिला", + "msg_latest_version": "वर्तमान में नवीनतम संस्करण है", + "msg_sel_log_export": "कृपया निर्यात करने के लिए लॉग चुनें", + "msg_del_log_confirm": "क्या आप वाकई चयनित लॉग हटाना चाहते हैं?", + "msg_log_deleted": "चयनित लॉग हटा दिए गए हैं।", + "msg_end_proc_title": "प्रक्रिया समाप्त करें?", + "msg_end_proc_confirm": "क्या आप वाकई चयनित प्रक्रियाओं को समाप्त करना चाहते हैं?", + "msg_cleaned": "साफ़ किया गया ", + "msg_reset_success": "सेटिंग्स रीसेट कर दी गईं। डिफ़ॉल्ट लागू करने के लिए एप्लिकेशन पुनः आरंभ करें।", + "msg_export_success": "सफलतापूर्वक निर्यात किया गया", + "msg_sel_proc_path": "चयनित प्रक्रिया पथ:\n", + "msg_action_for": "कार्रवाई ", + "msg_action_opts": " के लिए:\n1: श्वेतसूची में जोड़ें\n2: संगरोध में जोड़ें\nकोड दर्ज करें:", + "msg_click_target": "5 सेकंड के भीतर लक्ष्य विंडो पर क्लिक करें...", + "msg_confirm_block": "ब्लॉक की पुष्टि करें", + "msg_repaired": "चयनित आइटम मरम्मत किए गए", + "btn_repair": "मरम्मत", + "title_prompt": "सुझाव", + "title_error": "त्रुटि", + "path_unknown": "अज्ञात पथ", + "repair_mbr": "सिस्टम MBR की मरम्मत", + "repair_limit": "सिस्टम प्रतिबंधों की मरम्मत", + "repair_assoc": "फ़ाइल संघों की मरम्मत", + "repair_icon": "फ़ाइल आइकन की मरम्मत", + "repair_hijack": "छवि अपहरण की मरम्मत", + "repair_wallpaper": "डेस्कटॉप वॉलपेपर की मरम्मत", + "status_scanning": "स्कैन कर रहा है...", + "status_deleting": "हटा रहा है...", + "act_del": "आइटम हटाएं", + "act_ignore": "आइटम अनदेखा करें", + "act_quarantine": "संगरोध में जोड़ें", + "act_white": "श्वेतसूची में जोड़ें", + "col_date": "तिथि", + "col_type": "प्रकार", + "col_func": "कार्य", + "col_path": "पथ", + "col_name": "नाम", + "col_pid": "PID", + "col_size": "आकार", + "col_prog": "प्रोग्राम", + "col_class": "वर्ग", + "col_title": "शीर्षक", + "col_repair": "मरम्मत आइटम", + "btn_select_all": "सभी चुनें", + "ctx_open_loc": "फ़ाइल स्थान खोलें", + "msg_too_many": "(बहुत अधिक डेटा, प्रदर्शन सुनिश्चित करने के लिए केवल शीर्ष {0} रिकॉर्ड दिखा रहा है)", + "res_scan_comp": "स्कैन पूरा हुआ", + "res_virus_det": "वायरस का पता चला", + "res_proc_block": "प्रक्रिया अवरुद्ध", + "res_file_block": "फ़ाइल अवरुद्ध", + "res_net_block": "नेटवर्क अवरुद्ध", + "res_drv_block": "ड्राइवर अवरुद्ध", + "res_sys_repair": "सिस्टम मरम्मत", + "res_cfg_update": "कॉन्फ़िगरेशन अपडेट" }, "arabic_switch": { - "PYAS Security": "PYAS Security", - "此裝置已受到防護": "هذا الجهاز محمي", - "智能掃描": "فحص ذكي", - "此選項可以快速掃描裝置安全性": "فحص أمان الجهاز بسرعة", - "日誌導出": "تصدير السجلات", - "此選項可以篩選日誌並匯出存檔": "تصفية السجلات وتصديرها إلى الأرشيف", - "病毒掃描": "فحص الفيروسات", - "此選項可以選擇進階掃描方式": "حدد طريقة فحص متقدمة", - "刪除": "حذف", - "選擇": "تحديد", - "檔案掃描": "فحص الملفات", - "路徑掃描": "فحص المسار", - "全盤掃描": "فحص شامل", - "停止": "إيقاف", - "進程防護": "حماية العمليات", - "此選項可以終止惡意進程運行": "إنهاء تنفيذ العمليات الخبيثة", - "檔案防護": "حماية الملفات", - "此選項可以隔離惡意檔案建立": "عزل إنشاء الملفات الخبيثة", - "系統防護": "حماية النظام", - "此選項可以實時修復系統異常": "إصلاح في الوقت الفعلي لأعطال النظام", - "驅動防護": "حماية برامج التشغيل", - "此選項可以實時攔截惡意行為": "اعتراض السلوك الخبيث في الوقت الفعلي", - "網路防護": "حماية الشبكة", - "此選項可以攔截惡意網路連接": "حظر اتصالات الشبكة الخبيثة", - "自訂防護": "حماية مخصصة", - "此選項可以導入自訂防護規則": "استيراد قواعد حماية مخصصة", - "進程管理": "مدير العمليات", - "此選項可以實時查看系統進程": "مراقبة عمليات النظام في الوقت الفعلي", - "垃圾清理": "تنظيف المخلفات", - "此選項可以清理暫存垃圾檔案": "تنظيف الملفات المؤقتة والمخلفات", - "系統修復": "إصلاح النظام", - "此選項可以修復系統註冊項目": "إصلاح عناصر سجل النظام", - "彈窗攔截": "حظر النوافذ المنبثقة", - "此選項可以選擇指定窗口攔截": "حظر نوافذ منبثقة معينة", - "白名單": "القائمة البيضاء", - "此選項可以查看並管理白名單": "عرض وإدارة القائمة البيضاء", - "隔離區": "الحجر الصحي", - "此選項可以查看並管理隔離區": "عرض وإدارة منطقة الحجر الصحي", - "增強模式": "وضع محسن", - "此選項可以增強靜態掃描引擎": "تحسين محرك الفحص الثابت", - "擴展引擎": "محرك الإضافات", - "此選項可以使用擴展規則引擎": "تمكين محركات قواعد الإضافة", - "雲端服務": "خدمة السحابة", - "此選項可以自動上報可疑檔案": "الإبلاغ تلقائيًا عن الملفات المشبوهة", - "顯色主題": "سمة اللون", - "此選項可以選擇主題顏色": "تحديد سمة ألوان التطبيق", - "白色主題": "الوضع الفاتح", - "紅色主題": "سمة حمراء", - "黃色主題": "سمة صفراء", - "綠色主題": "سمة خضراء", - "藍色主題": "سمة زرقاء", - "黑色主題": "الوضع الداكن", - "顯示語言": "لغة العرض", - "此選項可以選擇顯示語言": "تحديد لغة عرض التطبيق", - "重置選項": "إعادة تعيين الخيارات", - "此選項可以重置所有設定": "استعادة جميع الإعدادات الافتراضية", - "執行": "تنفيذ", - "產品金鑰": "مفتاح المنتج", - "此選項可以啟用產品金鑰": "تنشيط مفتاح المنتج", - "官方網站": "الموقع الرسمي", - "此選項可以前往官方網站": "قم بزيارة موقعنا الرسمي", - "檢查更新": "التحقق من التحديثات", - "此選項可以檢查可用更新": "التحقق من أحدث التحديثات", - "搜尋進程...": "البحث في العمليات...", - "查看": "عرض", - "結束": "إنهاء المهمة", - "白名單管理": "مدير القائمة البيضاء", - "搜尋檔案...": "البحث عن الملفات...", - "加入": "إضافة", - "移除": "إزالة", - "隔離區管理": "مدير الحجر الصحي", - "掃描": "فحص", - "搜尋窗口...": "البحث عن النوافذ...", - "搜尋規則...": "البحث في القواعد...", - "搜尋日誌...": "البحث في السجلات...", - "導出": "تصدير", - "正在初始化中": "جاري التهيئة...", - "檢查更新失敗": "فشل التحقق من التحديثات", - "發現新版本": "تم العثور على إصدار جديد", - "當前已是最新版本": "أنت تستخدم أحدث إصدار حاليًا", - "請選擇要導出的日誌": "يرجى تحديد السجلات لتصديرها", - "確定刪除選取的日誌記錄嗎?": "هل أنت متأكد من حذف السجلات المحددة؟", - "選取的日誌已刪除。": "تم حذف السجلات المحددة.", - "結束進程?": "إنهاء العملية؟", - "確定要結束選取的進程嗎?": "هل أنت متأكد من إنهاء العمليات المحددة؟", - "已清理 ": "تم التنظيف ", - "設定已重置,請重新啟動程式以套用預設值。": "تم إعادة تعيين الإعدادات. يرجى إعادة تشغيل التطبيق لتطبيق الافتراضيات.", - "導出成功": "تم التصدير بنجاح", - "選取進程路徑:\n": "مسارات العمليات المحددة:\n", - "對 ": "إجراء لـ ", - " 執行動作:\n1: 加入白名單\n2: 加入隔離區\n請輸入代碼:": ":\n1: إضافة للقائمة البيضاء\n2: إضافة للحجر الصحي\nأدخل الرمز:", - "請在5秒內點擊目標視窗...": "انقر على النافذة المستهدفة خلال 5 ثوانٍ...", - "確認攔截": "تأكيد الحظر", - "已修復選取項目": "تم إصلاح العناصر المحددة", - "修復": "إصلاح", - "提示": "تلميح", - "錯誤": "خطأ", - "未知路徑": "مسار غير معروف", - "修復系統 MBR": "إصلاح MBR للنظام", - "修復系統限制": "إصلاح قيود النظام", - "修復檔案關聯": "إصلاح اقترانات الملفات", - "修復檔案圖標": "إصلاح رموز الملفات", - "修復映像劫持": "إصلاح اختطاف الصور", - "修復桌面壁紙": "إصلاح خلفية سطح المكتب", - "正在掃描": "جاري الفحص...", - "正在刪除": "جاري الحذف...", - "選單掃描": "فحص قائمة السياق", - "此選項可以啟用右鍵掃描功能": "تمكين ميزة الفحص بزر الماوس الأيمن", - "刪除項目": "حذف العناصر", - "忽略項目": "تجاهل العناصر", - "加入隔離區": "إضافة إلى الحجر الصحي", - "加入白名單": "إضافة إلى القائمة البيضاء", - "日期": "التاريخ", - "類型": "النوع", - "功能": "الوظيفة", - "路徑": "المسار", - "名稱": "الاسم", - "PID": "PID", - "大小": "الحجم", - "程式": "البرنامج", - "類別": "الفئة", - "標題": "العنوان", - "修復項目": "عناصر الإصلاح", - "全選": "تحديد الكل", - "打開檔案所在位置": "فتح موقع الملف" + "app_name": "PYAS Security", + "status_protected": "هذا الجهاز محمي", + "scan_smart": "فحص ذكي", + "scan_smart_desc": "فحص أمان الجهاز بسرعة", + "log_export": "تصدير السجلات", + "log_export_desc": "تصفية السجلات وتصديرها إلى الأرشيف", + "scan_virus": "فحص الفيروسات", + "scan_virus_desc": "حدد طريقة فحص متقدمة", + "btn_delete": "حذف", + "btn_select": "تحديد", + "scan_file": "فحص الملفات", + "scan_path": "فحص المسار", + "scan_full": "فحص شامل", + "btn_stop": "إيقاف", + "protect_proc": "حماية العمليات", + "protect_proc_desc": "إنهاء تنفيذ العمليات الخبيثة", + "protect_file": "حماية الملفات", + "protect_file_desc": "عزل إنشاء الملفات الخبيثة", + "protect_sys": "حماية النظام", + "protect_sys_desc": "إصلاح في الوقت الفعلي لأعطال النظام", + "protect_drv": "حماية برامج التشغيل", + "protect_drv_desc": "اعتراض السلوك الخبيث في الوقت الفعلي", + "protect_net": "حماية الشبكة", + "protect_net_desc": "حظر اتصالات الشبكة الخبيثة", + "protect_custom": "حماية مخصصة", + "protect_custom_desc": "استيراد قواعد حماية مخصصة", + "manage_proc": "مدير العمليات", + "manage_proc_desc": "مراقبة عمليات النظام في الوقت الفعلي", + "clean_junk": "تنظيف المخلفات", + "clean_junk_desc": "تنظيف الملفات المؤقتة والمخلفات", + "repair_sys": "إصلاح النظام", + "repair_sys_desc": "إصلاح عناصر سجل النظام", + "block_popup": "حظر النوافذ المنبثقة", + "block_popup_desc": "حظر نوافذ منبثقة معينة", + "list_white": "القائمة البيضاء", + "list_white_desc": "عرض وإدارة القائمة البيضاء", + "list_quarantine": "الحجر الصحي", + "list_quarantine_desc": "عرض وإدارة منطقة الحجر الصحي", + "mode_enhance": "وضع محسن", + "mode_enhance_desc": "تحسين محرك الفحص الثابت", + "engine_ext": "محرك الإضافات", + "engine_ext_desc": "تمكين محركات قواعد الإضافة", + "service_cloud": "خدمة السحابة", + "service_cloud_desc": "الإبلاغ تلقائيًا عن الملفات المشبوهة", + "scan_context": "فحص قائمة السياق", + "scan_context_desc": "تمكين ميزة الفحص بزر الماوس الأيمن", + "theme_color": "سمة اللون", + "theme_color_desc": "تحديد سمة ألوان التطبيق", + "theme_white": "الوضع الفاتح", + "theme_red": "سمة حمراء", + "theme_yellow": "سمة صفراء", + "theme_green": "سمة خضراء", + "theme_blue": "سمة زرقاء", + "theme_black": "الوضع الداكن", + "lang_display": "لغة العرض", + "lang_display_desc": "تحديد لغة عرض التطبيق", + "opt_reset": "إعادة تعيين الخيارات", + "opt_reset_desc": "استعادة جميع الإعدادات الافتراضية", + "btn_execute": "تنفيذ", + "key_product": "مفتاح المنتج", + "key_product_desc": "تنشيط مفتاح المنتج", + "web_official": "الموقع الرسمي", + "web_official_desc": "قم بزيارة موقعنا الرسمي", + "update_check": "التحقق من التحديثات", + "update_check_desc": "التحقق من أحدث التحديثات", + "search_proc": "البحث في العمليات...", + "btn_view": "عرض", + "btn_end": "إنهاء المهمة", + "manage_white": "مدير القائمة البيضاء", + "search_file": "البحث عن الملفات...", + "btn_add": "إضافة", + "btn_remove": "إزالة", + "manage_quarantine": "مدير الحجر الصحي", + "btn_scan": "فحص", + "search_window": "البحث عن النوافذ...", + "search_rule": "البحث في القواعد...", + "search_log": "البحث في السجلات...", + "btn_export": "تصدير", + "msg_init": "جاري التهيئة...", + "msg_update_fail": "فشل التحقق من التحديثات", + "msg_new_version": "تم العثور على إصدار جديد", + "msg_latest_version": "أنت تستخدم أحدث إصدار حاليًا", + "msg_sel_log_export": "يرجى تحديد السجلات لتصديرها", + "msg_del_log_confirm": "هل أنت متأكد من حذف السجلات المحددة؟", + "msg_log_deleted": "تم حذف السجلات المحددة.", + "msg_end_proc_title": "إنهاء العملية؟", + "msg_end_proc_confirm": "هل أنت متأكد من إنهاء العمليات المحددة؟", + "msg_cleaned": "تم التنظيف ", + "msg_reset_success": "تم إعادة تعيين الإعدادات. يرجى إعادة تشغيل التطبيق لتطبيق الافتراضيات.", + "msg_export_success": "تم التصدير بنجاح", + "msg_sel_proc_path": "مسارات العمليات المحددة:\n", + "msg_action_for": "إجراء لـ ", + "msg_action_opts": ":\n1: إضافة للقائمة البيضاء\n2: إضافة للحجر الصحي\nأدخل الرمز:", + "msg_click_target": "انقر على النافذة المستهدفة خلال 5 ثوانٍ...", + "msg_confirm_block": "تأكيد الحظر", + "msg_repaired": "تم إصلاح العناصر المحددة", + "btn_repair": "إصلاح", + "title_prompt": "تلميح", + "title_error": "خطأ", + "path_unknown": "مسار غير معروف", + "repair_mbr": "إصلاح MBR للنظام", + "repair_limit": "إصلاح قيود النظام", + "repair_assoc": "إصلاح اقترانات الملفات", + "repair_icon": "إصلاح رموز الملفات", + "repair_hijack": "إصلاح اختطاف الصور", + "repair_wallpaper": "إصلاح خلفية سطح المكتب", + "status_scanning": "جاري الفحص...", + "status_deleting": "جاري الحذف...", + "act_del": "حذف العناصر", + "act_ignore": "تجاهل العناصر", + "act_quarantine": "إضافة إلى الحجر الصحي", + "act_white": "إضافة إلى القائمة البيضاء", + "col_date": "التاريخ", + "col_type": "النوع", + "col_func": "الوظيفة", + "col_path": "المسار", + "col_name": "الاسم", + "col_pid": "PID", + "col_size": "الحجم", + "col_prog": "البرنامج", + "col_class": "الفئة", + "col_title": "العنوان", + "col_repair": "عناصر الإصلاح", + "btn_select_all": "تحديد الكل", + "ctx_open_loc": "فتح موقع الملف", + "msg_too_many": "(بيانات كثيرة جدًا، يتم عرض أول {0} سجل فقط لضمان الأداء)", + "res_scan_comp": "اكتمل الفحص", + "res_virus_det": "تم اكتشاف فيروس", + "res_proc_block": "حظر العملية", + "res_file_block": "حظر الملف", + "res_net_block": "حظر الشبكة", + "res_drv_block": "حظر برنامج التشغيل", + "res_sys_repair": "إصلاح النظام", + "res_cfg_update": "تحديث التكوين" }, "russian_switch": { - "PYAS Security": "PYAS Security", - "此裝置已受到防護": "Это устройство защищено", - "智能掃描": "Умное сканирование", - "此選項可以快速掃描裝置安全性": "Быстрое сканирование безопасности устройства", - "日誌導出": "Экспорт журналов", - "此選項可以篩選日誌並匯出存檔": "Фильтрация журналов и экспорт в архив", - "病毒掃描": "Сканирование на вирусы", - "此選項可以選擇進階掃描方式": "Выберите расширенный метод сканирования", - "刪除": "Удалить", - "選擇": "Выбрать", - "檔案掃描": "Сканирование файлов", - "路徑掃描": "Сканирование пути", - "全盤掃描": "Полное сканирование", - "停止": "Остановить", - "進程防護": "Защита процессов", - "此選項可以終止惡意進程運行": "Завершение выполнения вредоносных процессов", - "檔案防護": "Защита файлов", - "此選項可以隔離惡意檔案建立": "Карантин создания вредоносных файлов", - "系統防護": "Защита системы", - "此選項可以實時修復系統異常": "Восстановление системных аномалий в реальном времени", - "驅動防護": "Защита драйверов", - "此選項可以實時攔截惡意行為": "Блокировка вредоносного поведения в реальном времени", - "網路防護": "Сетевая защита", - "此選項可以攔截惡意網路連接": "Блокировка вредоносных сетевых подключений", - "自訂防護": "Пользовательская защита", - "此選項可以導入自訂防護規則": "Импорт пользовательских правил защиты", - "進程管理": "Диспетчер процессов", - "此選項可以實時查看系統進程": "Мониторинг системных процессов в реальном времени", - "垃圾清理": "Очистка мусора", - "此選項可以清理暫存垃圾檔案": "Очистка временных и ненужных файлов", - "系統修復": "Восстановление системы", - "此選項可以修復系統註冊項目": "Восстановление элементов системного реестра", - "彈窗攔截": "Блокировщик всплывающих окон", - "此選項可以選擇指定窗口攔截": "Блокировка определенных всплывающих окон", - "白名單": "Белый список", - "此選項可以查看並管理白名單": "Просмотр и управление белым списком", - "隔離區": "Карантин", - "此選項可以查看並管理隔離區": "Просмотр и управление карантинной зоной", - "增強模式": "Расширенный режим", - "此選項可以增強靜態掃描引擎": "Улучшение статического механизма сканирования", - "擴展引擎": "Модули расширения", - "此選項可以使用擴展規則引擎": "Включить механизмы правил расширения", - "雲端服務": "Облачный сервис", - "此選項可以自動上報可疑檔案": "Автоматически сообщать о подозрительных файлах", - "顯色主題": "Цветовая тема", - "此選項可以選擇主題顏色": "Выберите цветовую тему приложения", - "白色主題": "Светлый режим", - "紅色主題": "Красная тема", - "黃色主題": "Желтая тема", - "綠色主題": "Зеленая тема", - "藍色主題": "Синяя тема", - "黑色主題": "Темный режим", - "顯示語言": "Язык интерфейса", - "此選項可以選擇顯示語言": "Выберите язык приложения", - "重置選項": "Сброс настроек", - "此選項可以重置所有設定": "Восстановить все настройки по умолчанию", - "執行": "Выполнить", - "產品金鑰": "Ключ продукта", - "此選項可以啟用產品金鑰": "Активировать ключ продукта", - "官方網站": "Официальный сайт", - "此選項可以前往官方網站": "Посетите наш официальный сайт", - "檢查更新": "Проверить обновления", - "此選項可以檢查可用更新": "Проверить наличие последних обновлений", - "搜尋進程...": "Поиск процессов...", - "查看": "Просмотр", - "結束": "Завершить", - "白名單管理": "Управление белым списком", - "搜尋檔案...": "Поиск файлов...", - "加入": "Добавить", - "移除": "Удалить", - "隔離區管理": "Управление карантином", - "掃描": "Сканировать", - "搜尋窗口...": "Поиск окон...", - "搜尋規則...": "Поиск правил...", - "搜尋日誌...": "Поиск журналов...", - "導出": "Экспорт", - "正在初始化中": "Инициализация...", - "檢查更新失敗": "Ошибка проверки обновлений", - "發現新版本": "Найдена новая версия", - "當前已是最新版本": "Установлена последняя версия", - "請選擇要導出的日誌": "Пожалуйста, выберите журналы для экспорта", - "確定刪除選取的日誌記錄嗎?": "Вы уверены, что хотите удалить выбранные журналы?", - "選取的日誌已刪除。": "Выбранные журналы удалены.", - "結束進程?": "Завершить процесс?", - "確定要結束選取的進程嗎?": "Вы уверены, что хотите завершить выбранные процессы?", - "已清理 ": "Очищено ", - "設定已重置,請重新啟動程式以套用預設值。": "Настройки сброшены. Перезапустите программу.", - "導出成功": "Успешный экспорт", - "選取進程路徑:\n": "Пути выбранных процессов:\n", - "對 ": "Действие для ", - " 執行動作:\n1: 加入白名單\n2: 加入隔離區\n請輸入代碼:": ":\n1: Добавить в белый список\n2: Добавить в карантин\nВведите код:", - "請在5秒內點擊目標視窗...": "Нажмите на целевое окно в течение 5 сек...", - "確認攔截": "Подтвердить блокировку", - "已修復選取項目": "Выбранные элементы восстановлены", - "修復": "Восстановить", - "提示": "Подсказка", - "錯誤": "Ошибка", - "未知路徑": "Неизвестный путь", - "修復系統 MBR": "Восстановление MBR системы", - "修復系統限制": "Снятие системных ограничений", - "修復檔案關聯": "Восстановление ассоциаций файлов", - "修復檔案圖標": "Восстановление значков файлов", - "修復映像劫持": "Восстановление Image Hijacking", - "修復桌面壁紙": "Восстановление обоев рабочего стола", - "正在掃描": "Сканирование...", - "正在刪除": "Удаление...", - "選單掃描": "Сканирование из контекстного меню", - "此選項可以啟用右鍵掃描功能": "Включить функцию сканирования по правому клику", - "刪除項目": "Удалить элементы", - "忽略項目": "Игнорировать элементы", - "加入隔離區": "Добавить в карантин", - "加入白名單": "Добавить в белый список", - "日期": "Дата", - "類型": "Тип", - "功能": "Функция", - "路徑": "Путь", - "名稱": "Имя", - "PID": "PID", - "大小": "Размер", - "程式": "Программа", - "類別": "Класс", - "標題": "Заголовок", - "修復項目": "Элементы восстановления", - "全選": "Выбрать все", - "打開檔案所在位置": "Открыть расположение файла" + "app_name": "PYAS Security", + "status_protected": "Это устройство защищено", + "scan_smart": "Умное сканирование", + "scan_smart_desc": "Быстрое сканирование безопасности устройства", + "log_export": "Экспорт журналов", + "log_export_desc": "Фильтрация журналов и экспорт в архив", + "scan_virus": "Сканирование на вирусы", + "scan_virus_desc": "Выберите расширенный метод сканирования", + "btn_delete": "Удалить", + "btn_select": "Выбрать", + "scan_file": "Сканирование файлов", + "scan_path": "Сканирование пути", + "scan_full": "Полное сканирование", + "btn_stop": "Остановить", + "protect_proc": "Защита процессов", + "protect_proc_desc": "Завершение выполнения вредоносных процессов", + "protect_file": "Защита файлов", + "protect_file_desc": "Карантин создания вредоносных файлов", + "protect_sys": "Защита системы", + "protect_sys_desc": "Восстановление системных аномалий в реальном времени", + "protect_drv": "Защита драйверов", + "protect_drv_desc": "Блокировка вредоносного поведения в реальном времени", + "protect_net": "Сетевая защита", + "protect_net_desc": "Блокировка вредоносных сетевых подключений", + "protect_custom": "Пользовательская защита", + "protect_custom_desc": "Импорт пользовательских правил защиты", + "manage_proc": "Диспетчер процессов", + "manage_proc_desc": "Мониторинг системных процессов в реальном времени", + "clean_junk": "Очистка мусора", + "clean_junk_desc": "Очистка временных и ненужных файлов", + "repair_sys": "Восстановление системы", + "repair_sys_desc": "Восстановление элементов системного реестра", + "block_popup": "Блокировщик всплывающих окон", + "block_popup_desc": "Блокировка определенных всплывающих окон", + "list_white": "Белый список", + "list_white_desc": "Просмотр и управление белым списком", + "list_quarantine": "Карантин", + "list_quarantine_desc": "Просмотр и управление карантинной зоной", + "mode_enhance": "Расширенный режим", + "mode_enhance_desc": "Улучшение статического механизма сканирования", + "engine_ext": "Модули расширения", + "engine_ext_desc": "Включить механизмы правил расширения", + "service_cloud": "Облачный сервис", + "service_cloud_desc": "Автоматически сообщать о подозрительных файлах", + "scan_context": "Сканирование из контекстного меню", + "scan_context_desc": "Включить функцию сканирования по правому клику", + "theme_color": "Цветовая тема", + "theme_color_desc": "Выберите цветовую тему приложения", + "theme_white": "Светлый режим", + "theme_red": "Красная тема", + "theme_yellow": "Желтая тема", + "theme_green": "Зеленая тема", + "theme_blue": "Синяя тема", + "theme_black": "Темный режим", + "lang_display": "Язык интерфейса", + "lang_display_desc": "Выберите язык приложения", + "opt_reset": "Сброс настроек", + "opt_reset_desc": "Восстановить все настройки по умолчанию", + "btn_execute": "Выполнить", + "key_product": "Ключ продукта", + "key_product_desc": "Активировать ключ продукта", + "web_official": "Официальный сайт", + "web_official_desc": "Посетите наш официальный сайт", + "update_check": "Проверить обновления", + "update_check_desc": "Проверить наличие последних обновлений", + "search_proc": "Поиск процессов...", + "btn_view": "Просмотр", + "btn_end": "Завершить", + "manage_white": "Управление белым списком", + "search_file": "Поиск файлов...", + "btn_add": "Добавить", + "btn_remove": "Удалить", + "manage_quarantine": "Управление карантином", + "btn_scan": "Сканировать", + "search_window": "Поиск окон...", + "search_rule": "Поиск правил...", + "search_log": "Поиск журналов...", + "btn_export": "Экспорт", + "msg_init": "Инициализация...", + "msg_update_fail": "Ошибка проверки обновлений", + "msg_new_version": "Найдена новая версия", + "msg_latest_version": "Установлена последняя версия", + "msg_sel_log_export": "Пожалуйста, выберите журналы для экспорта", + "msg_del_log_confirm": "Вы уверены, что хотите удалить выбранные журналы?", + "msg_log_deleted": "Выбранные журналы удалены.", + "msg_end_proc_title": "Завершить процесс?", + "msg_end_proc_confirm": "Вы уверены, что хотите завершить выбранные процессы?", + "msg_cleaned": "Очищено ", + "msg_reset_success": "Настройки сброшены. Перезапустите программу.", + "msg_export_success": "Успешный экспорт", + "msg_sel_proc_path": "Пути выбранных процессов:\n", + "msg_action_for": "Действие для ", + "msg_action_opts": ":\n1: Добавить в белый список\n2: Добавить в карантин\nВведите код:", + "msg_click_target": "Нажмите на целевое окно в течение 5 сек...", + "msg_confirm_block": "Подтвердить блокировку", + "msg_repaired": "Выбранные элементы восстановлены", + "btn_repair": "Восстановить", + "title_prompt": "Подсказка", + "title_error": "Ошибка", + "path_unknown": "Неизвестный путь", + "repair_mbr": "Восстановление MBR системы", + "repair_limit": "Снятие системных ограничений", + "repair_assoc": "Восстановление ассоциаций файлов", + "repair_icon": "Восстановление значков файлов", + "repair_hijack": "Восстановление Image Hijacking", + "repair_wallpaper": "Восстановление обоев рабочего стола", + "status_scanning": "Сканирование...", + "status_deleting": "Удаление...", + "act_del": "Удалить элементы", + "act_ignore": "Игнорировать элементы", + "act_quarantine": "Добавить в карантин", + "act_white": "Добавить в белый список", + "col_date": "Дата", + "col_type": "Тип", + "col_func": "Функция", + "col_path": "Путь", + "col_name": "Имя", + "col_pid": "PID", + "col_size": "Размер", + "col_prog": "Программа", + "col_class": "Класс", + "col_title": "Заголовок", + "col_repair": "Элементы восстановления", + "btn_select_all": "Выбрать все", + "ctx_open_loc": "Открыть расположение файла", + "msg_too_many": "(Слишком много данных, показаны только первые {0} записей для обеспечения производительности)", + "res_scan_comp": "Сканирование завершено", + "res_virus_det": "Обнаружен вирус", + "res_proc_block": "Процесс заблокирован", + "res_file_block": "Файл заблокирован", + "res_net_block": "Сеть заблокирована", + "res_drv_block": "Драйвер заблокирован", + "res_sys_repair": "Восстановление системы", + "res_cfg_update": "Обновление конфигурации" }, "slovenian_switch": { - "PYAS Security": "PYAS Security", - "此裝置已受到防護": "Ta naprava je zaščitena", - "智能掃描": "Pametno skeniranje", - "此選項可以快速掃描裝置安全性": "Hitro skeniranje varnosti naprave", - "日誌導出": "Izvoz dnevnikov", - "此選項可以篩選日誌並匯出存檔": "Filtriranje dnevnikov in izvoz v arhiv", - "病毒掃描": "Skeniranje virusov", - "此選項可以選擇進階掃描方式": "Izberite napredno metodo skeniranja", - "刪除": "Izbriši", - "選擇": "Izberi", - "檔案掃描": "Skeniranje datotek", - "路徑掃描": "Skeniranje poti", - "全盤掃描": "Celotno skeniranje", - "停止": "Ustavi", - "進程防護": "Zaščita procesov", - "此選項可以終止惡意進程運行": "Končajte izvajanje zlonamernih procesov", - "檔案防護": "Zaščita datotek", - "此選項可以隔離惡意檔案建立": "Karantena za ustvarjanje zlonamernih datotek", - "系統防護": "Sistemska zaščita", - "此選項可以實時修復系統異常": "Popravilo sistemskih anomalij v realnem času", - "驅動防護": "Zaščita gonilnikov", - "此選項可以實時攔截惡意行為": "Prestreganje zlonamernega vedenja v realnem času", - "網路防護": "Omrežna zaščita", - "此選項可以攔截惡意網路連接": "Blokiraj zlonamerne omrežne povezave", - "自訂防護": "Zaščita po meri", - "此選項可以導入自訂防護規則": "Uvozi pravila zaščite po meri", - "進程管理": "Upravitelj procesov", - "此選項可以實時查看系統進程": "Spremlja sistemske procese v realnem času", - "垃圾清理": "Čiščenje nesnage", - "此選項可以清理暫存垃圾檔案": "Čisti začasne in nepotrebne datotek", - "系統修復": "Popravilo sistema", - "此選項可以修復系統註冊項目": "Popravlja elemente sistemskega registra", - "彈窗攔截": "Blokator pojavnih oken", - "此選項可以選擇指定窗口攔截": "Blokira določena pojavna okna", - "白名單": "Seznam dovoljenih", - "此選項可以查看並管理白名單": "Ogled in upravljanje seznama dovoljenih", - "隔離區": "Karantena", - "此選項可以查看並管理隔離區": "Ogled in upravljanje karantene", - "增強模式": "Izboljšan način", - "此選項可以增強靜態掃描引擎": "Izboljša statični mehanizem skeniranja", - "擴展引擎": "Razširitveni mehanizem", - "此選項可以使用擴展規則引擎": "Omogoči razširitvene mehanizme pravil", - "雲端服務": "Storitev v oblaku", - "此選項可以自動上報可疑檔案": "Samodejno prijavi sumljive datoteke", - "顯色主題": "Barvna tema", - "此選項可以選擇主題顏色": "Izberite barvno temo aplikacije", - "白色主題": "Svetel način", - "紅色主題": "Rdeča tema", - "黃色主題": "Rumena tema", - "綠色主題": "Zelena tema", - "藍色主題": "Modra tema", - "黑色主題": "Temen način", - "顯示語言": "Jezik prikaza", - "此選項可以選擇顯示語言": "Izberite jezik prikaza aplikacije", - "重置選項": "Ponastavitev", - "此選項可以重置所有設定": "Obnovi vse privzete nastavitve", - "執行": "Izvedi", - "產品金鑰": "Ključ izdelka", - "此選項可以啟用產品金鑰": "Aktivira ključ izdelka", - "官方網站": "Uradna stran", - "此選項可以前往官方網站": "Obiščite našo uradno spletno stran", - "檢查更新": "Preveri posodobitve", - "此選項可以檢查可用更新": "Preveri zadnje posodobitve", - "搜尋進程...": "Išči procese...", - "查看": "Poglej", - "結束": "Končaj opravilo", - "白名單管理": "Upravitelj seznama dovoljenih", - "搜尋檔案...": "Išči datoteke...", - "加入": "Dodaj", - "移除": "Odstrani", - "隔離區管理": "Upravitelj karantene", - "掃描": "Skeniraj", - "搜尋窗口...": "Išči okna...", - "搜尋規則...": "Išči pravila...", - "搜尋日誌...": "Išči dnevnike...", - "導出": "Izvozi", - "正在初始化中": "Inicializacija...", - "檢查更新失敗": "Preverjanje posodobitev ni uspelo", - "發現新版本": "Najdena nova različica", - "當前已是最新版本": "Trenutno imate najnovejšo različico", - "請選擇要導出的日誌": "Prosimo, izberite dnevnike za izvoz", - "確定刪除選取的日誌記錄嗎?": "Ali ste prepričani, da želite izbrisati izbrane dnevnike?", - "選取的日誌已刪除。": "Izbrani dnevniki so bili izbrisani.", - "結束進程?": "Končam proces?", - "確定要結束選取的進程嗎?": "Ali ste prepričani, da želite končati izbrane procese?", - "已清理 ": "Počiščeno ", - "設定已重置,請重新啟動程式以套用預設值。": "Nastavitve so ponastavljene. Znova zaženite program.", - "導出成功": "Izvoz uspešen", - "選取進程路徑:\n": "Poti izbranih procesov:\n", - "對 ": "Dejanje za ", - " 執行動作:\n1: 加入白名單\n2: 加入隔離區\n請輸入代碼:": ":\n1: Dodaj na seznam dovoljenih\n2: Dodaj v karanteno\nVnesite kodo:", - "請在5秒內點擊目標視窗...": "Kliknite na ciljno okno v 5s...", - "確認攔截": "Potrdi blokado", - "已修復選取項目": "Izbrani predmeti popravljeni", - "修復": "Popravi", - "提示": "Namig", - "錯誤": "Napaka", - "未知路徑": "Neznana pot", - "修復系統 MBR": "Popravilo sistemskega MBR", - "修復系統限制": "Popravilo sistemskih omejitev", - "修復檔案關聯": "Popravilo asociacij datotek", - "修復檔案圖標": "Popravilo ikon datotek", - "修復映像劫持": "Popravilo ugrabitve slike", - "修復桌面壁紙": "Popravilo ozadja namizja", - "正在掃描": "Skeniranje...", - "正在刪除": "Brisanje...", - "選單掃描": "Skeniranje iz kontekstnega menija", - "此選項可以啟用右鍵掃描功能": "Omogoči funkcijo skeniranja z desnim klikom", - "刪除項目": "Izbriši elemente", - "忽略項目": "Prezri elemente", - "加入隔離區": "Dodaj v karanteno", - "加入白名單": "Dodaj na seznam dovoljenih", - "日期": "Datum", - "類型": "Vrsta", - "功能": "Funkcija", - "路徑": "Pot", - "名稱": "Ime", - "PID": "PID", - "大小": "Velikost", - "程式": "Program", - "類別": "Razred", - "標題": "Naslov", - "修復項目": "Predmeti za popravilo", - "全選": "Izberi vse", - "打開檔案所在位置": "Odpri mesto datoteke" + "app_name": "PYAS Security", + "status_protected": "Ta naprava je zaščitena", + "scan_smart": "Pametno skeniranje", + "scan_smart_desc": "Hitro skeniranje varnosti naprave", + "log_export": "Izvoz dnevnikov", + "log_export_desc": "Filtriranje dnevnikov in izvoz v arhiv", + "scan_virus": "Skeniranje virusov", + "scan_virus_desc": "Izberite napredno metodo skeniranja", + "btn_delete": "Izbriši", + "btn_select": "Izberi", + "scan_file": "Skeniranje datotek", + "scan_path": "Skeniranje poti", + "scan_full": "Celotno skeniranje", + "btn_stop": "Ustavi", + "protect_proc": "Zaščita procesov", + "protect_proc_desc": "Končajte izvajanje zlonamernih procesov", + "protect_file": "Zaščita datotek", + "protect_file_desc": "Karantena za ustvarjanje zlonamernih datotek", + "protect_sys": "Sistemska zaščita", + "protect_sys_desc": "Popravilo sistemskih anomalij v realnem času", + "protect_drv": "Zaščita gonilnikov", + "protect_drv_desc": "Prestreganje zlonamernega vedenja v realnem času", + "protect_net": "Omrežna zaščita", + "protect_net_desc": "Blokiraj zlonamerne omrežne povezave", + "protect_custom": "Zaščita po meri", + "protect_custom_desc": "Uvozi pravila zaščite po meri", + "manage_proc": "Upravitelj procesov", + "manage_proc_desc": "Spremlja sistemske procese v realnem času", + "clean_junk": "Čiščenje nesnage", + "clean_junk_desc": "Čisti začasne in nepotrebne datotek", + "repair_sys": "Popravilo sistema", + "repair_sys_desc": "Popravlja elemente sistemskega registra", + "block_popup": "Blokator pojavnih oken", + "block_popup_desc": "Blokira določena pojavna okna", + "list_white": "Seznam dovoljenih", + "list_white_desc": "Ogled in upravljanje seznama dovoljenih", + "list_quarantine": "Karantena", + "list_quarantine_desc": "Ogled in upravljanje karantene", + "mode_enhance": "Izboljšan način", + "mode_enhance_desc": "Izboljša statični mehanizem skeniranja", + "engine_ext": "Razširitveni mehanizem", + "engine_ext_desc": "Omogoči razširitvene mehanizme pravil", + "service_cloud": "Storitev v oblaku", + "service_cloud_desc": "Samodejno prijavi sumljive datoteke", + "scan_context": "Skeniranje iz kontekstnega menija", + "scan_context_desc": "Omogoči funkcijo skeniranja z desnim klikom", + "theme_color": "Barvna tema", + "theme_color_desc": "Izberite barvno temo aplikacije", + "theme_white": "Svetel način", + "theme_red": "Rdeča tema", + "theme_yellow": "Rumena tema", + "theme_green": "Zelena tema", + "theme_blue": "Modra tema", + "theme_black": "Temen način", + "lang_display": "Jezik prikaza", + "lang_display_desc": "Izberite jezik prikaza aplikacije", + "opt_reset": "Ponastavitev", + "opt_reset_desc": "Obnovi vse privzete nastavitve", + "btn_execute": "Izvedi", + "key_product": "Ključ izdelka", + "key_product_desc": "Aktivira ključ izdelka", + "web_official": "Uradna stran", + "web_official_desc": "Obiščite našo uradno spletno stran", + "update_check": "Preveri posodobitve", + "update_check_desc": "Preveri zadnje posodobitve", + "search_proc": "Išči procese...", + "btn_view": "Poglej", + "btn_end": "Končaj opravilo", + "manage_white": "Upravitelj seznama dovoljenih", + "search_file": "Išči datoteke...", + "btn_add": "Dodaj", + "btn_remove": "Odstrani", + "manage_quarantine": "Upravitelj karantene", + "btn_scan": "Skeniraj", + "search_window": "Išči okna...", + "search_rule": "Išči pravila...", + "search_log": "Išči dnevnike...", + "btn_export": "Izvozi", + "msg_init": "Inicializacija...", + "msg_update_fail": "Preverjanje posodobitev ni uspelo", + "msg_new_version": "Najdena nova različica", + "msg_latest_version": "Trenutno imate najnovejšo različico", + "msg_sel_log_export": "Prosimo, izberite dnevnike za izvoz", + "msg_del_log_confirm": "Ali ste prepričani, da želite izbrisati izbrane dnevnike?", + "msg_log_deleted": "Izbrani dnevniki so bili izbrisani.", + "msg_end_proc_title": "Končam proces?", + "msg_end_proc_confirm": "Ali ste prepričani, da želite končati izbrane procese?", + "msg_cleaned": "Počiščeno ", + "msg_reset_success": "Nastavitve so ponastavljene. Znova zaženite program.", + "msg_export_success": "Izvoz uspešen", + "msg_sel_proc_path": "Poti izbranih procesov:\n", + "msg_action_for": "Dejanje za ", + "msg_action_opts": ":\n1: Dodaj na seznam dovoljenih\n2: Dodaj v karanteno\nVnesite kodo:", + "msg_click_target": "Kliknite na ciljno okno v 5s...", + "msg_confirm_block": "Potrdi blokado", + "msg_repaired": "Izbrani predmeti popravljeni", + "btn_repair": "Popravi", + "title_prompt": "Namig", + "title_error": "Napaka", + "path_unknown": "Neznana pot", + "repair_mbr": "Popravilo sistemskega MBR", + "repair_limit": "Popravilo sistemskih omejitev", + "repair_assoc": "Popravilo asociacij datotek", + "repair_icon": "Popravilo ikon datotek", + "repair_hijack": "Popravilo ugrabitve slike", + "repair_wallpaper": "Popravilo ozadja namizja", + "status_scanning": "Skeniranje...", + "status_deleting": "Brisanje...", + "act_del": "Izbriši elemente", + "act_ignore": "Prezri elemente", + "act_quarantine": "Dodaj v karanteno", + "act_white": "Dodaj na seznam dovoljenih", + "col_date": "Datum", + "col_type": "Vrsta", + "col_func": "Funkcija", + "col_path": "Pot", + "col_name": "Ime", + "col_pid": "PID", + "col_size": "Velikost", + "col_prog": "Program", + "col_class": "Razred", + "col_title": "Naslov", + "col_repair": "Predmeti za popravilo", + "btn_select_all": "Izberi vse", + "ctx_open_loc": "Odpri mesto datoteke", + "msg_too_many": "(Preveč podatkov, prikazanih je samo prvih {0} zapisov za zagotavljanje zmogljivosti)", + "res_scan_comp": "Skeniranje končano", + "res_virus_det": "Zaznan virus", + "res_proc_block": "Proces blokiran", + "res_file_block": "Datoteka blokirana", + "res_net_block": "Omrežje blokirano", + "res_drv_block": "Gonilnik blokiran", + "res_sys_repair": "Popravilo sistema", + "res_cfg_update": "Posodobitev konfiguracije" } }, langMap: { diff --git a/Interface/static/js/main.js b/Interface/static/js/main.js index 16e402f..86b5a99 100644 --- a/Interface/static/js/main.js +++ b/Interface/static/js/main.js @@ -1,10 +1,66 @@ document.addEventListener('DOMContentLoaded', () => { - let currentLang = "english_switch"; - let isScanning = false; - let isFirstLaunch = false; - const { dict, langMap } = window.AppI18n; + const appState = { + lang: "english_switch", + scanning: false, + firstLaunch: false, + taskmgrTimer: null, + taskmgrActive: false, + virusMap: new Map(), + virusResults: [], + junkList: [] + }; + + const reverseI18nMap = Object.entries(dict["traditional_switch"]).reduce((acc, [key, val]) => { + acc[val] = key; + return acc; + }, {}); + + const initI18nKeys = () => { + document.querySelectorAll("[data-i18n]").forEach(el => { + let key = el.getAttribute('data-i18n'); + if (!key) { + const text = el.textContent.trim(); + key = reverseI18nMap[text] || text; + el.setAttribute('data-i18n', key); + } + el.dataset.originText = el.textContent.trim(); + }); + document.querySelectorAll("[data-i18n-placeholder]").forEach(el => { + let key = el.getAttribute('data-i18n-placeholder'); + if (reverseI18nMap[key]) { + el.setAttribute('data-i18n-placeholder', reverseI18nMap[key]); + } + el.dataset.originPlaceholder = el.getAttribute('placeholder'); + }); + document.querySelectorAll("option[data-i18n]").forEach(el => { + let key = el.getAttribute('data-i18n'); + if (!key) { + const text = el.textContent.trim(); + key = reverseI18nMap[text] || text; + el.setAttribute('data-i18n', key); + } + }); + }; + + document.addEventListener('click', () => { + document.querySelectorAll('.custom-select-wrapper').forEach(w => w.classList.remove('open')); + }); + + const getMsg = (key) => (dict[appState.lang] || dict["english_switch"])[key] || key; + + const formatMsg = (key, ...args) => { + let msg = getMsg(key); + args.forEach((arg, i) => msg = msg.split(`{${i}}`).join(arg)); + return msg; + }; + + const escapeHtml = (unsafe) => { + if (typeof unsafe !== 'string') return unsafe; + return unsafe.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); + }; + const themes = { "white_switch": { "--bg-window": "245, 245, 247", "--bg-nav": "255, 255, 255", "--bg-panel": "255, 255, 255", "--bg-hover": "rgba(0,0,0,0.05)", "--text-primary": "29, 29, 31", "--text-secondary": "134, 134, 139", "--border-color":"210, 210, 215", "--accent-color":"0, 122, 255", "--accent-alpha":"rgba(0, 122, 255, 0.1)", "--accent-shadow":"rgba(0, 122, 255, 0.2)", "--accent-hover":"rgba(0, 122, 255, 0.3)" }, "black_switch": { "--bg-window": "0, 0, 0", "--bg-nav": "28, 28, 30", "--bg-panel": "28, 28, 30", "--bg-hover": "rgba(255,255,255,0.1)", "--text-primary": "245, 245, 247", "--text-secondary": "134, 134, 139", "--border-color":"44, 44, 46", "--accent-color":"10, 132, 255", "--accent-alpha":"rgba(10, 132, 255, 0.1)", "--accent-shadow":"rgba(10, 132, 255, 0.2)", "--accent-hover":"rgba(10, 132, 255, 0.3)" }, @@ -15,63 +71,30 @@ document.addEventListener('DOMContentLoaded', () => { }; const cols = { - log: [ - {key: 'time_str', label: '日期', flex: 1.5}, - {key: 'level', label: '類型', flex: 0.8}, - {key: 'action', label: '功能', flex: 1.2}, - {key: 'source', label: '路徑', flex: 3} - ], - process: [ - {key: 'name', label: '名稱', flex: 1.5}, - {key: 'pid', label: 'PID', flex: 0.5}, - {key: 'path', label: '路徑', flex: 3} - ], - virus: [ - {key: 'label', label: '類型', flex: 1}, - {key: 'path', label: '路徑', flex: 3} - ], - pathOnly: [ - {key: 'path', label: '路徑', flex: 1} - ], - junk: [ - {key: 'path', label: '路徑', flex: 3}, - {key: 'sizeStr', label: '大小', flex: 1} - ], - popup: [ - {key: 'exe', label: '程式', flex: 1}, - {key: 'class', label: '類別', flex: 1}, - {key: 'title', label: '標題', flex: 2} - ], - repair: [ - {key: 'display', label: '修復項目', flex: 1} - ] + log: [{key: 'time_str', label: 'col_date', flex: 1.5}, {key: 'level', label: 'col_type', flex: 0.8}, {key: 'action', label: 'col_func', flex: 1.2, isI18n: true}, {key: 'source', label: 'col_path', flex: 3}], + process: [{key: 'name', label: 'col_name', flex: 1.5}, {key: 'pid', label: 'col_pid', flex: 0.5}, {key: 'path', label: 'col_path', flex: 3}], + virus: [{key: 'label', label: 'col_type', flex: 1, isI18n: true}, {key: 'path', label: 'col_path', flex: 3}], + pathOnly: [{key: 'path', label: 'col_path', flex: 1}], + junk: [{key: 'path', label: 'col_path', flex: 3}, {key: 'sizeStr', label: 'col_size', flex: 1}], + popup: [{key: 'exe', label: 'col_prog', flex: 1}, {key: 'class', label: 'col_class', flex: 1}, {key: 'title', label: 'col_title', flex: 2}], + repair: [{key: 'display', label: 'col_repair', flex: 1, isI18n: true}] }; - const getMsg = (key) => (dict[currentLang] || dict["english_switch"])[key] || key; - - function buildCustomSelectElement(select) { + const buildCustomSelectElement = (select) => { select.style.display = 'none'; const wrapper = document.createElement('div'); wrapper.className = 'custom-select-wrapper'; - const trigger = document.createElement('div'); - trigger.className = 'custom-select-trigger'; - const triggerText = document.createElement('span'); - triggerText.className = 'custom-select-text'; - const selectedOpt = select.options[select.selectedIndex]; - if (selectedOpt) { - triggerText.textContent = selectedOpt.textContent; - if (selectedOpt.hasAttribute('data-i18n')) triggerText.setAttribute('data-i18n', ''); - if (selectedOpt.hasAttribute('data-origin-text')) triggerText.dataset.originText = selectedOpt.dataset.originText; - } - - const icon = document.createElement('div'); - icon.className = 'custom-select-icon'; - icon.innerHTML = ``; - - trigger.appendChild(triggerText); - trigger.appendChild(icon); + const triggerKey = selectedOpt ? selectedOpt.getAttribute('data-i18n') : ''; + const triggerTextContent = selectedOpt ? getMsg(triggerKey || selectedOpt.textContent) : ''; + + const triggerHTML = ` +
+ ${triggerTextContent} +
+
`; + wrapper.innerHTML = triggerHTML; const optionsContainer = document.createElement('ul'); optionsContainer.className = 'custom-select-options'; @@ -82,22 +105,22 @@ document.addEventListener('DOMContentLoaded', () => { Array.from(select.options).forEach(option => { if (option.disabled) return; + const optKey = option.getAttribute('data-i18n'); + const optText = optKey ? getMsg(optKey) : option.textContent; const li = document.createElement('li'); - li.className = 'custom-select-option'; - li.textContent = option.textContent; + li.className = `custom-select-option ${option.selected ? 'selected' : ''}`; + li.textContent = optText; li.dataset.value = option.value; - if (option.hasAttribute('data-i18n')) li.setAttribute('data-i18n', ''); - if (option.hasAttribute('data-origin-text')) li.dataset.originText = option.dataset.originText; - if (option.selected) li.classList.add('selected'); + if (optKey) li.setAttribute('data-i18n', optKey); li.addEventListener('click', (e) => { e.stopPropagation(); select.value = option.value; + const triggerText = wrapper.querySelector('.custom-select-text'); triggerText.textContent = li.textContent; - if (li.hasAttribute('data-origin-text')) { - triggerText.dataset.originText = li.dataset.originText; - } + if (optKey) triggerText.setAttribute('data-i18n', optKey); + wrapper.classList.remove('open'); optionsContainer.querySelectorAll('.custom-select-option').forEach(el => el.classList.remove('selected')); li.classList.add('selected'); @@ -106,64 +129,64 @@ document.addEventListener('DOMContentLoaded', () => { optionsContainer.appendChild(li); const phantomSpan = document.createElement('span'); - phantomSpan.textContent = option.textContent; - if (option.hasAttribute('data-i18n')) phantomSpan.setAttribute('data-i18n', ''); - if (option.hasAttribute('data-origin-text')) phantomSpan.dataset.originText = option.dataset.originText; + phantomSpan.textContent = optText; + if (optKey) phantomSpan.setAttribute('data-i18n', optKey); phantom.appendChild(phantomSpan); }); wrapper.appendChild(phantom); - wrapper.appendChild(trigger); wrapper.appendChild(optionsContainer); select.parentNode.insertBefore(wrapper, select.nextSibling); + const trigger = wrapper.querySelector('.custom-select-trigger'); trigger.addEventListener('click', (e) => { e.stopPropagation(); const isOpen = wrapper.classList.contains('open'); document.querySelectorAll('.custom-select-wrapper').forEach(w => w.classList.remove('open')); if (!isOpen) wrapper.classList.add('open'); }); - } + }; - function initCustomSelects() { - document.querySelectorAll('select.modern-select').forEach(select => { - buildCustomSelectElement(select); - }); - - document.addEventListener('click', () => { - document.querySelectorAll('.custom-select-wrapper').forEach(w => w.classList.remove('open')); - }); - } - - initCustomSelects(); - - document.querySelectorAll("[data-i18n]").forEach(el => { el.dataset.originText = el.textContent.trim(); }); - document.querySelectorAll("[data-i18n-placeholder]").forEach(el => { el.dataset.originPlaceholder = el.getAttribute('placeholder'); }); - document.querySelectorAll("option[data-i18n]").forEach(el => { el.dataset.originText = el.textContent.trim(); }); + const updateCustomSelectUI = (selectId, val) => { + const select = document.getElementById(selectId); + if (!select) return; + select.value = val; + const wrapper = select.nextElementSibling; + if (wrapper && wrapper.classList.contains('custom-select-wrapper')) { + const triggerText = wrapper.querySelector('.custom-select-text'); + const selectedOpt = select.options[select.selectedIndex]; + if (selectedOpt) { + const optKey = selectedOpt.getAttribute('data-i18n'); + triggerText.textContent = optKey ? getMsg(optKey) : selectedOpt.textContent; + if (optKey) triggerText.setAttribute('data-i18n', optKey); + } + wrapper.querySelectorAll('.custom-select-option').forEach(el => { + el.classList.toggle('selected', el.dataset.value === val); + }); + } + }; const translateText = (lang) => { - currentLang = lang; - const currentDict = dict[lang] || dict["english_switch"]; + appState.lang = lang; document.querySelectorAll("[data-i18n]").forEach(el => { - const originText = el.dataset.originText; - el.textContent = currentDict[originText] || originText; + const key = el.getAttribute('data-i18n'); + if (key) el.textContent = getMsg(key); }); document.querySelectorAll("[data-i18n-placeholder]").forEach(el => { - const originText = el.dataset.originPlaceholder; - el.setAttribute('placeholder', currentDict[originText] || originText); + const key = el.getAttribute('data-i18n-placeholder'); + if (key) el.setAttribute('placeholder', getMsg(key)); }); document.querySelectorAll('.manage-widget, .virus-widget').forEach(widget => { + if (widget.buildHeader) widget.buildHeader(); if (widget.renderData) widget.renderData(); }); - document.documentElement.lang = langMap[currentLang] || "en"; + document.documentElement.lang = langMap[lang] || "en"; const progressText = document.getElementById('progress_text'); if (progressText && progressText.dataset.dynamicMsg) { try { const msgs = JSON.parse(progressText.dataset.dynamicMsg); - if (msgs[lang]) { - progressText.textContent = msgs[lang]; - } + if (msgs[lang]) progressText.textContent = msgs[lang]; } catch (e) {} } }; @@ -177,88 +200,44 @@ document.addEventListener('DOMContentLoaded', () => { } }; - function updateCustomSelectUI(selectId, val) { - const select = document.getElementById(selectId); - if (!select) return; - select.value = val; - let wrapper = select.nextElementSibling; - if (wrapper && wrapper.classList.contains('custom-select-wrapper')) { - const triggerText = wrapper.querySelector('.custom-select-text'); - const selectedOpt = select.options[select.selectedIndex]; - if (selectedOpt) { - triggerText.textContent = selectedOpt.textContent; - if (selectedOpt.hasAttribute('data-origin-text')) { - triggerText.dataset.originText = selectedOpt.dataset.originText; - } - } - wrapper.querySelectorAll('.custom-select-option').forEach(el => { - el.classList.toggle('selected', el.dataset.value === val); - }); - } - } - - function renderDataGrid(containerSelector, dataList, columns, valKey, defaultChecked = false) { + const renderDataGrid = (containerSelector, dataList, columns, valKey, defaultChecked = false) => { const widget = document.querySelector(`${containerSelector} .manage-widget`) || document.querySelector(`${containerSelector} .virus-widget`); const listUl = document.querySelector(`${containerSelector} .manage-list`) || document.querySelector(`${containerSelector} .virus-list`); const searchInput = document.querySelector(`${containerSelector} .search-box input`); if (!widget || !listUl) return; - const escapeHtml = (unsafe) => { - if (typeof unsafe !== 'string') return unsafe; - return unsafe - .replace(/&/g, "&") - .replace(//g, ">") - .replace(/"/g, """) - .replace(/'/g, "'"); - }; - const isInit = !widget.gridState; - if (isInit) { - let containerWidth = widget.clientWidth || 800; - let availableWidth = Math.max(containerWidth - 60 - (columns.length * 16), 400); - let totalFlex = columns.reduce((sum, c) => sum + (c.flex || 1), 0); + const containerWidth = widget.clientWidth || 800; + const availableWidth = Math.max(containerWidth - 60 - (columns.length * 16), 400); + const totalFlex = columns.reduce((sum, c) => sum + (c.flex || 1), 0); widget.gridState = { - sortKey: columns[0]?.key || '', - sortAsc: true, - filterText: "", + sortKey: columns[0]?.key || '', sortAsc: true, filterText: "", colWidths: columns.map(c => Math.max(((c.flex || 1) / totalFlex) * availableWidth, 60)), checkedSet: new Set() }; - widget.gridState.colWidths.forEach((w, idx) => { - widget.style.setProperty(`--col-${idx}`, `${w}px`); - }); - + widget.gridState.colWidths.forEach((w, idx) => widget.style.setProperty(`--col-${idx}`, `${w}px`)); const header = document.createElement('div'); header.className = 'manage-list-header'; widget.insertBefore(header, widget.firstChild); widget.buildHeader = () => { - const headerColsHtml = columns.map((col, idx) => - `
- ${getMsg(col.label)} + const headerColsHtml = columns.map((col, idx) => ` +
+ ${getMsg(col.label)} ${widget.gridState.sortKey === col.key ? (widget.gridState.sortAsc ? '▲' : '▼') : ''}
-
` - ).join(''); +
`).join(''); - header.innerHTML = ` - -
${headerColsHtml}
- `; + header.innerHTML = `
${headerColsHtml}
`; header.querySelectorAll('.col-header').forEach(el => { el.addEventListener('click', () => { const key = el.dataset.key; - if (widget.gridState.sortKey === key) { - widget.gridState.sortAsc = !widget.gridState.sortAsc; - } else { - widget.gridState.sortKey = key; - widget.gridState.sortAsc = true; - } + widget.gridState.sortAsc = widget.gridState.sortKey === key ? !widget.gridState.sortAsc : true; + widget.gridState.sortKey = key; widget.buildHeader(); widget.renderData(widget.gridState.filterText, false); }); @@ -267,23 +246,20 @@ document.addEventListener('DOMContentLoaded', () => { header.querySelectorAll('.col-resizer').forEach(resizer => { resizer.addEventListener('mousedown', (e) => { e.stopPropagation(); - const headerCell = resizer.parentElement; - const idx = parseInt(headerCell.dataset.idx); + const idx = parseInt(resizer.parentElement.dataset.idx); const startX = e.clientX; const startWidth = widget.gridState.colWidths[idx]; - const onMouseMove = (moveEvent) => { - const newWidth = Math.max(startWidth + (moveEvent.clientX - startX), 40); + const onMouseMove = (me) => { + const newWidth = Math.max(startWidth + (me.clientX - startX), 40); widget.gridState.colWidths[idx] = newWidth; widget.style.setProperty(`--col-${idx}`, `${newWidth}px`); }; - const onMouseUp = () => { document.body.classList.remove('resizing-active'); document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); }; - document.body.classList.add('resizing-active'); document.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp); @@ -295,77 +271,46 @@ document.addEventListener('DOMContentLoaded', () => { if (selectAllCb) { selectAllCb.addEventListener('change', (e) => { const isChecked = e.target.checked; - listUl.querySelectorAll('.manage-list-item input[type="checkbox"]').forEach(cb => { - cb.checked = isChecked; - if (isChecked) { - widget.gridState.checkedSet.add(cb.value); - } else { - widget.gridState.checkedSet.delete(cb.value); - } - if (containerSelector === '#scan_window') { - virusState.set(cb.value, isChecked); - } + listUl.querySelectorAll('.manage-list-item input[type="checkbox"]').forEach(cb => cb.checked = isChecked); + (widget.gridState.lastDisplayData || []).forEach(item => { + const valStr = String(item[valKey]); + isChecked ? widget.gridState.checkedSet.add(valStr) : widget.gridState.checkedSet.delete(valStr); + if (containerSelector === '#scan_window') appState.virusMap.set(valStr, isChecked); }); - if (containerSelector === '#scan_window' && typeof checkVirusListEmpty === 'function') { - checkVirusListEmpty(); - } + if (containerSelector === '#scan_window') checkVirusListEmpty(); }); } }; - widget.buildHeader(); listUl.addEventListener('click', (e) => { const li = e.target.closest('.manage-list-item'); if (!li) return; - const cb = li.querySelector('input[type="checkbox"]'); - if (e.target.tagName !== 'INPUT') { - cb.checked = !cb.checked; - } - - if (cb.checked) { - widget.gridState.checkedSet.add(cb.value); - } else { - widget.gridState.checkedSet.delete(cb.value); - } + if (e.target.tagName !== 'INPUT') cb.checked = !cb.checked; + cb.checked ? widget.gridState.checkedSet.add(cb.value) : widget.gridState.checkedSet.delete(cb.value); if (containerSelector === '#scan_window') { - virusState.set(cb.value, cb.checked); - if (typeof checkVirusListEmpty === 'function') checkVirusListEmpty(); - } - - if (typeof widget.updateSelectAllState === 'function') { - widget.updateSelectAllState(); + appState.virusMap.set(cb.value, cb.checked); + checkVirusListEmpty(); } + if (widget.updateSelectAllState) widget.updateSelectAllState(); }); - if (searchInput) { - searchInput.addEventListener('input', (e) => widget.renderData(e.target.value, false)); - } + if (searchInput) searchInput.addEventListener('input', (e) => widget.renderData(e.target.value, false)); } const state = widget.gridState; - widget.renderData = (filterText = state.filterText, resetDataCheck = false) => { state.filterText = filterText; - if (resetDataCheck) { state.checkedSet.clear(); - dataList.forEach(item => { - if (defaultChecked) state.checkedSet.add(String(item[valKey])); - }); + if (defaultChecked) dataList.forEach(item => state.checkedSet.add(String(item[valKey]))); } else { const validKeys = new Set(dataList.map(item => String(item[valKey]))); - for (const val of state.checkedSet) { - if (!validKeys.has(val)) { - state.checkedSet.delete(val); - } - } - + for (const val of state.checkedSet) if (!validKeys.has(val)) state.checkedSet.delete(val); if (state.checkedSet.size === 0 && defaultChecked && dataList.length > 0) { - const hasAnyCheckedInDOM = listUl.querySelector('input[type="checkbox"]:checked'); - if (!hasAnyCheckedInDOM) { + if (!listUl.querySelector('input[type="checkbox"]:checked')) { dataList.forEach(item => state.checkedSet.add(String(item[valKey]))); } } @@ -375,440 +320,344 @@ document.addEventListener('DOMContentLoaded', () => { const selectAllCb = header ? header.querySelector('.select-all-cb') : null; if (selectAllCb) selectAllCb.disabled = dataList.length === 0; - let displayData = dataList.filter(item => { - if (!filterText) return true; - const ft = filterText.toLowerCase(); - return columns.some(col => String(item[col.key] || '').toLowerCase().includes(ft)); - }); + const ft = filterText.toLowerCase(); + let displayData = dataList.filter(item => !filterText || columns.some(col => String(item[col.key] || '').toLowerCase().includes(ft))); displayData.sort((a, b) => { - let valA = a[state.sortKey] ?? ''; - let valB = b[state.sortKey] ?? ''; - - if (state.sortKey === 'sizeStr' && 'size' in a && 'size' in b) { - return state.sortAsc ? a.size - b.size : b.size - a.size; - } - - let numA = parseFloat(valA); - let numB = parseFloat(valB); - if (!isNaN(numA) && !isNaN(numB) && String(valA).trim() !== '' && String(valB).trim() !== '') { - return state.sortAsc ? numA - numB : numB - numA; - } + const valA = a[state.sortKey] ?? '', valB = b[state.sortKey] ?? ''; + if (state.sortKey === 'sizeStr' && 'size' in a && 'size' in b) return state.sortAsc ? a.size - b.size : b.size - a.size; + const numA = parseFloat(valA), numB = parseFloat(valB); + if (!isNaN(numA) && !isNaN(numB) && String(valA).trim() !== '' && String(valB).trim() !== '') return state.sortAsc ? numA - numB : numB - numA; return state.sortAsc ? String(valA).localeCompare(String(valB)) : String(valB).localeCompare(String(valA)); }); + widget.gridState.lastDisplayData = displayData; widget.updateSelectAllState = () => { if (!selectAllCb) return; - const total = listUl.querySelectorAll('input[type="checkbox"]').length; - const checked = listUl.querySelectorAll('input[type="checkbox"]:checked').length; - selectAllCb.checked = (total > 0 && total === checked); - selectAllCb.indeterminate = (checked > 0 && checked < total); + const cData = widget.gridState.lastDisplayData || []; + if (cData.length === 0) { selectAllCb.checked = false; selectAllCb.indeterminate = false; return; } + const checkedCount = cData.filter(item => containerSelector === '#scan_window' ? appState.virusMap.get(String(item[valKey])) : widget.gridState.checkedSet.has(String(item[valKey]))).length; + selectAllCb.checked = (checkedCount > 0 && checkedCount === cData.length); + selectAllCb.indeterminate = (checkedCount > 0 && checkedCount < cData.length); }; - let htmlContent = ''; - const MAX_RENDER_ITEMS = 2000; - const limitData = displayData.slice(0, MAX_RENDER_ITEMS); - - limitData.forEach(item => { + const MAX_ITEMS = 2000; + const limitData = displayData.slice(0, MAX_ITEMS); + + let htmlContent = limitData.map(item => { const itemValStr = String(item[valKey]); - let isChecked = false; + let isChecked = containerSelector === '#scan_window' ? (appState.virusMap.get(itemValStr) ?? true) : state.checkedSet.has(itemValStr); + if (containerSelector === '#scan_window') appState.virusMap.set(itemValStr, isChecked); - if (containerSelector === '#scan_window') { - isChecked = virusState.get(itemValStr) ?? true; - virusState.set(itemValStr, isChecked); - } else { - isChecked = state.checkedSet.has(itemValStr); - } - - const checkedAttr = isChecked ? 'checked' : ''; - - let rowColsHtml = columns.map((col, idx) => { - let valStr = String(item[col.key] || ''); + const rowColsHtml = columns.map((col, idx) => { + const rawVal = String(item[col.key] || ''); + let valStr = col.isI18n ? getMsg(rawVal) : rawVal; + if (rawVal === '未知路徑' || rawVal === 'path_unknown') valStr = getMsg('path_unknown'); return `
${escapeHtml(valStr)}
`; }).join(''); - let escapedPath = escapeHtml(item.path || ''); - htmlContent += ` -
  • - -
    ${rowColsHtml}
    -
  • - `; - }); + return `
  • ${rowColsHtml}
  • `; + }).join(''); - if (displayData.length > MAX_RENDER_ITEMS) { - htmlContent += ` -
  • -
    (資料過多,僅顯示前 ${MAX_RENDER_ITEMS} 筆以確保效能流暢)
    -
  • - `; + if (displayData.length > MAX_ITEMS) { + htmlContent += `
  • ${escapeHtml(formatMsg("msg_too_many", MAX_ITEMS))}
  • `; } const scrollContainer = listUl.parentElement; const scrollTop = scrollContainer ? scrollContainer.scrollTop : 0; listUl.innerHTML = htmlContent; if (scrollContainer) scrollContainer.scrollTop = scrollTop; - widget.updateSelectAllState(); }; - widget.renderData(state.filterText, isInit); - } - - function getCheckedValues(containerSelector) { - const checkboxes = document.querySelectorAll(`${containerSelector} .manage-list-item input[type="checkbox"]:checked`); - return Array.from(checkboxes).map(cb => cb.value); - } - - let taskmgrTimer = null; - let isTaskmgrActive = false; - let currentJunkList = []; - window.virusResults = []; - - renderDataGrid('#scan_window', window.virusResults, cols.virus, 'path', true); - renderDataGrid('#taskmgr_window', [], cols.process, 'pid', false); - renderDataGrid('#junk_window', [], cols.junk, 'path', true); - renderDataGrid('#repair_window', [], cols.repair, 'value', true); - renderDataGrid('#whitelist_window', [], cols.pathOnly, 'path', false); - renderDataGrid('#quarantine_window', [], cols.pathOnly, 'path', false); - renderDataGrid('#custom_protect_window', [], cols.pathOnly, 'path', false); - renderDataGrid('#popup_window', [], cols.popup, 'value', false); - renderDataGrid('#log_export_window', [], cols.log, 'id', true); - - const switchPage = (targetId) => { - const oldActive = document.querySelector('.page.active'); - if (oldActive && oldActive.id !== targetId) { - if (oldActive.id === 'junk_window') { - currentJunkList = []; - renderDataGrid('#junk_window', [], cols.junk, 'path', true); - const searchInput = document.querySelector('#junk_window .search-box input'); - if (searchInput) searchInput.value = ''; - } else if (oldActive.id === 'repair_window') { - renderDataGrid('#repair_window', [], cols.repair, 'value', true); - } - } - - document.querySelectorAll('.page').forEach(page => page.classList.remove('active')); - document.querySelectorAll('.nav-btn').forEach(btn => btn.classList.remove('active')); - const targetPage = document.getElementById(targetId); - if (targetPage) targetPage.classList.add('active'); - const activeNav = document.querySelector(`aside .nav-btn[data-target="${targetId}"]`); - if (activeNav) activeNav.classList.add('active'); - - if (targetId === 'taskmgr_window') { - isTaskmgrActive = true; - const widget = document.querySelector('#taskmgr_window .manage-widget'); - const fetchProcs = () => { - if (!isTaskmgrActive || !window.pywebview) return; - const hasChecked = widget && widget.gridState && widget.gridState.checkedSet.size > 0; - const isHovering = widget && widget.matches(':hover'); - const isMenuOpen = document.querySelector('.custom-context-menu.show') !== null; - const isResizing = document.body.classList.contains('resizing-active'); - - if (!hasChecked && !isHovering && !isMenuOpen && !isResizing) { - window.pywebview.api.get_process_list().then(procs => { - updateProcessList(procs); - if (isTaskmgrActive) taskmgrTimer = setTimeout(fetchProcs, 2000); - }).catch(() => { - if (isTaskmgrActive) taskmgrTimer = setTimeout(fetchProcs, 2000); - }); - } else { - if (isTaskmgrActive) taskmgrTimer = setTimeout(fetchProcs, 2000); - } - }; - fetchProcs(); - } else { - isTaskmgrActive = false; - if (taskmgrTimer) { - clearTimeout(taskmgrTimer); - taskmgrTimer = null; - } - } - - if (['whitelist_window', 'quarantine_window', 'popup_window', 'custom_protect_window'].includes(targetId)) { - refreshConfigLists(); - } - - if (targetId === 'log_export_window' && window.pywebview) { - window.pywebview.api.get_logs().then(logs => { - const logList = logs.reverse().map(log => ({ - time_str: `[${log.time_str}]`, - level: log.level, - action: log.action, - source: log.source ? log.source : '-', - id: log.id - })); - renderDataGrid('#log_export_window', logList, cols.log, 'id', true); - }); - } }; - document.querySelectorAll('[data-target]').forEach(btn => { - btn.addEventListener('click', (e) => { - const targetId = e.currentTarget.getAttribute('data-target'); - if (targetId) switchPage(targetId); - }); - }); + const getCheckedValues = (selector) => Array.from(document.querySelectorAll(`${selector} .manage-list-item input[type="checkbox"]:checked`)).map(cb => cb.value); + const formatSize = (bytes) => { + if (bytes === 0) return '0 B'; + const k = 1024, sizes = ['B', 'KB', 'MB', 'GB'], i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; + }; - document.getElementById('quick_scan_btn')?.addEventListener('click', () => { - if (isScanning) return; - switchPage('scan_window'); - if (window.pywebview) triggerScan('smart'); - }); - - const scanMethodSelect = document.getElementById('scan_method_select'); - const stopBtn = document.getElementById('stop_btn'); - const progressText = document.getElementById('progress_text'); - const progressTitle = document.querySelector('#scan_window .section-title'); - const virusState = new Map(); - - function rebuildCustomSelect(selectId) { + const rebuildCustomSelect = (selectId) => { const select = document.getElementById(selectId); if (!select) return; - let sibling = select.nextElementSibling; while (sibling && sibling.classList.contains('custom-select-wrapper')) { const toRemove = sibling; sibling = sibling.nextElementSibling; toRemove.remove(); } - buildCustomSelectElement(select); - } + }; - function changeScanSelectMode(mode) { - if (!scanMethodSelect) return; - scanMethodSelect.innerHTML = ''; + const changeScanSelectMode = (mode) => { + const select = document.getElementById('scan_method_select'); + if (!select) return; + select.innerHTML = ``; if (mode === 'scan') { - scanMethodSelect.innerHTML = ` - - - - - - `; + select.innerHTML += ` + + + + `; } else if (mode === 'action') { - scanMethodSelect.innerHTML = ` - - - - - - `; + select.innerHTML += ` + + + + `; } - - scanMethodSelect.querySelectorAll('option[data-i18n]').forEach(el => { - el.dataset.originText = el.textContent.trim(); - el.textContent = getMsg(el.dataset.originText); - }); rebuildCustomSelect('scan_method_select'); - } + }; - function getScanSelectWrapper() { - if (!scanMethodSelect) return null; - const w = scanMethodSelect.nextElementSibling; - return (w && w.classList.contains('custom-select-wrapper')) ? w : null; - } - - function handleVirusActions(action) { - if (!window.pywebview) return; - const paths = Array.from(virusState.entries()).filter(([_, isChecked]) => isChecked).map(([path, _]) => path); - - if (paths.length === 0) { - updateCustomSelectUI('scan_method_select', 'none'); - return; + const checkVirusListEmpty = () => { + updateCustomSelectUI('scan_method_select', 'none'); + if (appState.virusMap.size === 0) { + changeScanSelectMode('scan'); + const title = document.querySelector('#scan_window .section-title'); + const text = document.getElementById('progress_text'); + if (title) { title.setAttribute('data-i18n', 'scan_virus'); title.textContent = getMsg('scan_virus'); } + if (text) { + text.setAttribute('data-i18n', 'scan_virus_desc'); + text.removeAttribute('data-dynamic-msg'); + text.textContent = getMsg('scan_virus_desc'); + } } + }; - const wrapper = getScanSelectWrapper(); + const triggerScan = (method) => { + if (!window.pywebview) return; + appState.scanning = true; + appState.virusMap.clear(); + appState.virusResults = []; + renderDataGrid('#scan_window', appState.virusResults, cols.virus, 'path', true); + changeScanSelectMode('scan'); + document.getElementById('scan_method_select').classList.add('hidden'); + const stopBtn = document.getElementById('stop_btn'); + stopBtn.classList.remove('hidden'); + stopBtn.disabled = false; + + const title = document.querySelector('#scan_window .section-title'); + const text = document.getElementById('progress_text'); + if (title) { title.setAttribute('data-i18n', 'status_scanning'); title.textContent = getMsg('status_scanning'); } + if (text) { text.setAttribute('data-i18n', 'msg_init'); text.removeAttribute('data-dynamic-msg'); text.textContent = getMsg('msg_init'); } + window.pywebview.api.trigger_scan(method); + }; + + const handleVirusActions = (action) => { + if (!window.pywebview) return; + const paths = Array.from(appState.virusMap.entries()).filter(([_, checked]) => checked).map(([p]) => p); + if (paths.length === 0) return updateCustomSelectUI('scan_method_select', 'none'); + + const wrapper = document.getElementById('scan_method_select').nextElementSibling; if (wrapper) wrapper.style.pointerEvents = 'none'; - const finalizeAction = () => { - const curWrapper = getScanSelectWrapper(); - if (curWrapper) curWrapper.style.pointerEvents = ''; + const finalize = () => { + if (wrapper) wrapper.style.pointerEvents = ''; checkVirusListEmpty(); }; - const removeListItems = (removedPaths) => { + const removeItems = (removedPaths) => { const removedSet = new Set(removedPaths); - removedPaths.forEach(p => virusState.delete(p)); - - for (let i = window.virusResults.length - 1; i >= 0; i--) { - if (removedSet.has(window.virusResults[i].path)) { - window.virusResults.splice(i, 1); - } - } - + removedPaths.forEach(p => appState.virusMap.delete(p)); + appState.virusResults = appState.virusResults.filter(r => !removedSet.has(r.path)); const widget = document.querySelector('#scan_window .virus-widget'); - if (widget && typeof widget.renderData === 'function') { - widget.renderData(widget.gridState.filterText, false); - } + if (widget && widget.renderData) widget.renderData(widget.gridState.filterText, false); }; if (action === 'delete') { - window.pywebview.api.solve_scan(paths).then((deletedPaths) => { - removeListItems(deletedPaths); - finalizeAction(); - }); + window.pywebview.api.solve_scan(paths).then((deleted) => { removeItems(deleted); finalize(); }); } else if (action === 'ignore') { - window.pywebview.api.remove_virus_result(paths).then(() => { - removeListItems(paths); - finalizeAction(); - }); + window.pywebview.api.remove_virus_result(paths).then(() => { removeItems(paths); finalize(); }); } else if (action === 'quarantine' || action === 'whitelist') { const listKey = action === 'quarantine' ? 'quarantine' : 'white_list'; window.pywebview.api.manage_named_list(listKey, paths, 'add').then(() => { - window.pywebview.api.remove_virus_result(paths).then(() => { - removeListItems(paths); - finalizeAction(); - }); + window.pywebview.api.remove_virus_result(paths).then(() => { removeItems(paths); finalize(); }); }); } - } + }; - function checkVirusListEmpty() { - updateCustomSelectUI('scan_method_select', 'none'); - if (virusState.size === 0) { - changeScanSelectMode('scan'); - if (progressTitle) { - progressTitle.setAttribute('data-i18n', ''); - progressTitle.dataset.originText = "病毒掃描"; - progressTitle.textContent = getMsg("病毒掃描"); - } - if (progressText) { - progressText.setAttribute('data-i18n', ''); - progressText.removeAttribute('data-dynamic-msg'); - progressText.dataset.originText = "此選項可以選擇進階掃描方式"; - progressText.textContent = getMsg("此選項可以選擇進階掃描方式"); + const fetchProcs = () => { + if (!appState.taskmgrActive || !window.pywebview) return; + const widget = document.querySelector('#taskmgr_window .manage-widget'); + const blockFetch = widget && (widget.gridState?.checkedSet.size > 0 || widget.matches(':hover')) || document.querySelector('.custom-context-menu.show') || document.body.classList.contains('resizing-active'); + + if (!blockFetch) { + window.pywebview.api.get_process_list().then(procs => { + const mapped = procs.map(p => ({ name: p.name, pid: p.pid, path: (p.path && p.path !== "None" && p.path !== "Unknown") ? p.path : "path_unknown" })); + renderDataGrid('#taskmgr_window', mapped, cols.process, 'pid', false); + if (appState.taskmgrActive) appState.taskmgrTimer = setTimeout(fetchProcs, 2000); + }).catch(() => { if (appState.taskmgrActive) appState.taskmgrTimer = setTimeout(fetchProcs, 2000); }); + } else { + if (appState.taskmgrActive) appState.taskmgrTimer = setTimeout(fetchProcs, 2000); + } + }; + + const refreshConfigLists = () => { + if (!window.pywebview) return; + window.pywebview.api.get_config().then(cfg => { + renderDataGrid('#whitelist_window', (cfg.white_list || []).map(i => ({path: i.file || i})), cols.pathOnly, 'path'); + renderDataGrid('#quarantine_window', (cfg.quarantine || []).map(i => ({path: i.file || i})), cols.pathOnly, 'path'); + renderDataGrid('#custom_protect_window', (cfg.custom_rule || []).map(i => ({path: i.file || i})), cols.pathOnly, 'path'); + const popupRules = (cfg.block_list || []).map(item => ({ exe: item.exe || '*', class: item.class || '*', title: item.title || '*', value: item.exe || item.title })); + renderDataGrid('#popup_window', popupRules, cols.popup, 'value'); + }); + }; + + const switchPage = (targetId) => { + const oldActive = document.querySelector('.page.active'); + if (oldActive && oldActive.id !== targetId) { + if (oldActive.id === 'junk_window') { + appState.junkList = []; + renderDataGrid('#junk_window', [], cols.junk, 'path', true); + const input = document.querySelector('#junk_window .search-box input'); + if (input) input.value = ''; + } else if (oldActive.id === 'repair_window') { + renderDataGrid('#repair_window', [], cols.repair, 'value', true); } } - } - let virusRenderTimeout = null; + document.querySelectorAll('.page, .nav-btn').forEach(el => el.classList.remove('active')); + document.getElementById(targetId)?.classList.add('active'); + document.querySelector(`aside .nav-btn[data-target="${targetId}"]`)?.classList.add('active'); + + appState.taskmgrActive = targetId === 'taskmgr_window'; + if (appState.taskmgrActive) fetchProcs(); + else if (appState.taskmgrTimer) { clearTimeout(appState.taskmgrTimer); appState.taskmgrTimer = null; } + + if (['whitelist_window', 'quarantine_window', 'popup_window', 'custom_protect_window'].includes(targetId)) refreshConfigLists(); + + if (targetId === 'log_export_window' && window.pywebview) { + window.pywebview.api.get_logs().then(logs => { + const logList = logs.reverse().map(log => ({ time_str: `[${log.time_str}]`, level: log.level, action: log.action, source: log.source || '-', id: log.id })); + renderDataGrid('#log_export_window', logList, cols.log, 'id', true); + }); + } + }; + window.addVirusResult = (label, path) => { - if (!virusState.has(path)) { - window.virusResults.push({ label: label, path: path }); - virusState.set(path, true); - + if (!appState.virusMap.has(path)) { + appState.virusResults.push({ label, path }); + appState.virusMap.set(path, true); const widget = document.querySelector('#scan_window .virus-widget'); - if (widget && typeof widget.renderData === 'function') { - if (virusRenderTimeout) clearTimeout(virusRenderTimeout); - virusRenderTimeout = setTimeout(() => { - widget.renderData(widget.gridState.filterText, false); - }, 50); + if (widget && widget.renderData) { + if (window.virusRenderTimeout) clearTimeout(window.virusRenderTimeout); + window.virusRenderTimeout = setTimeout(() => widget.renderData(widget.gridState.filterText, false), 50); } } }; window.updateScanProgress = (path) => { - if (progressTitle) { - progressTitle.setAttribute('data-i18n', ''); - progressTitle.dataset.originText = "正在掃描"; - progressTitle.textContent = getMsg("正在掃描"); - } - if (progressText) { - progressText.removeAttribute('data-i18n'); - progressText.removeAttribute('data-dynamic-msg'); - progressText.textContent = path; - } + const title = document.querySelector('#scan_window .section-title'); + const text = document.getElementById('progress_text'); + if (title) { title.setAttribute('data-i18n', 'status_scanning'); title.textContent = getMsg('status_scanning'); } + if (text) { text.removeAttribute('data-i18n'); text.removeAttribute('data-dynamic-msg'); text.textContent = path; } }; window.updateDeleteProgress = (path) => { - if (progressTitle) { - progressTitle.setAttribute('data-i18n', ''); - progressTitle.dataset.originText = "正在刪除"; - progressTitle.textContent = getMsg("正在刪除"); - } - if (progressText) { - progressText.removeAttribute('data-i18n'); - progressText.removeAttribute('data-dynamic-msg'); - progressText.textContent = path; - } + const title = document.querySelector('#scan_window .section-title'); + const text = document.getElementById('progress_text'); + if (title) { title.setAttribute('data-i18n', 'status_deleting'); title.textContent = getMsg('status_deleting'); } + if (text) { text.removeAttribute('data-i18n'); text.removeAttribute('data-dynamic-msg'); text.textContent = path; } }; window.finishScan = (msgData, count) => { - isScanning = false; - if (progressTitle) { - progressTitle.setAttribute('data-i18n', ''); - progressTitle.dataset.originText = "病毒掃描"; - progressTitle.textContent = getMsg("病毒掃描"); - } - if (progressText) { - progressText.removeAttribute('data-i18n'); + appState.scanning = false; + const title = document.querySelector('#scan_window .section-title'); + const text = document.getElementById('progress_text'); + if (title) { title.setAttribute('data-i18n', 'scan_virus'); title.textContent = getMsg('scan_virus'); } + if (text) { if (typeof msgData === 'object' && msgData !== null) { - progressText.dataset.dynamicMsg = JSON.stringify(msgData); - progressText.textContent = msgData[currentLang] || msgData["english_switch"]; + text.removeAttribute('data-i18n'); + text.dataset.dynamicMsg = JSON.stringify(msgData); + text.textContent = msgData[appState.lang] || msgData["english_switch"]; } else { - progressText.removeAttribute('data-dynamic-msg'); - progressText.textContent = msgData; + text.removeAttribute('data-dynamic-msg'); + text.setAttribute('data-i18n', msgData); + text.textContent = getMsg(msgData); } } - stopBtn.classList.add('hidden'); - scanMethodSelect.classList.remove('hidden'); - - if (count > 0) { - changeScanSelectMode('action'); - } else { - changeScanSelectMode('scan'); - } + document.getElementById('stop_btn')?.classList.add('hidden'); + document.getElementById('scan_method_select')?.classList.remove('hidden'); + changeScanSelectMode(count > 0 ? 'action' : 'scan'); updateCustomSelectUI('scan_method_select', 'none'); }; - function triggerScan(method) { - if (!window.pywebview) return; - isScanning = true; - virusState.clear(); - window.virusResults = []; - renderDataGrid('#scan_window', window.virusResults, cols.virus, 'path', true); - changeScanSelectMode('scan'); - scanMethodSelect.classList.add('hidden'); - stopBtn.classList.remove('hidden'); - stopBtn.disabled = false; - if (progressTitle) { - progressTitle.setAttribute('data-i18n', ''); - progressTitle.dataset.originText = "正在掃描"; - progressTitle.textContent = getMsg("正在掃描"); + window.updateLogs = (entry) => { + const logWidget = document.querySelector('.log-text'); + if (logWidget) { + let parts = [`[${entry.time_str}]`, entry.level, getMsg(entry.action || '')]; + if (entry.source) parts.push(`Src: ${entry.source}`); + if (entry.target) parts.push(`Tgt: ${entry.target}`); + if (entry.code) parts.push(`Code: ${entry.code}`); + if (entry.pid) parts.push(`PID: ${entry.pid}`); + if (entry.hash) parts.push(`Hash: ${entry.hash}`); + if (entry.detail) parts.push(`Detail: ${entry.detail}`); + if (entry.operate !== null) parts.push(`Op: ${entry.operate}`); + parts.push(`Success: ${entry.success}`); + let val = logWidget.value + parts.join(' | ') + '\n'; + if (val.length > 20000) val = val.substring(val.indexOf('\n', val.length - 15000) + 1); + logWidget.value = val; + logWidget.scrollTop = logWidget.scrollHeight; } - if (progressText) { - progressText.setAttribute('data-i18n', ''); - progressText.removeAttribute('data-dynamic-msg'); - progressText.dataset.originText = "正在初始化中"; - progressText.textContent = getMsg("正在初始化中"); + + if (document.getElementById('log_export_window')?.classList.contains('active') && window.pywebview) { + window.pywebview.api.get_logs().then(logs => { + const logList = logs.reverse().map(log => ({ time_str: `[${log.time_str}]`, level: log.level, action: log.action, source: log.source || '-', id: log.id })); + renderDataGrid('#log_export_window', logList, cols.log, 'id', true); + }); } - window.pywebview.api.trigger_scan(method); - } - scanMethodSelect?.addEventListener('change', () => { - const val = scanMethodSelect.value; - if (val === 'none') return; - - if (!isScanning) { - if (['smart', 'file', 'path', 'full'].includes(val)) { - triggerScan(val); - } else if (['delete', 'ignore', 'quarantine', 'whitelist'].includes(val)) { - handleVirusActions(val); + if ((entry.action === 'System' && entry.detail === 'Engine Initialization Complete') || (entry.level === 'WARN' && entry.action === 'init_engine_thread')) { + const overlay = document.getElementById('loading_overlay'); + if (overlay && !overlay.classList.contains('fade-out')) { + overlay.classList.add('fade-out'); + setTimeout(() => { + document.querySelector('.app-container')?.classList.add('fade-in'); + if (window.onEngineReady) window.onEngineReady(); + }, 400); } } - }); - - stopBtn?.addEventListener('click', () => { - if (window.pywebview) window.pywebview.api.stop_scan(); - stopBtn.disabled = true; - }); - - document.getElementById('theme_select')?.addEventListener('change', (e) => { - applyTheme(e.target.value); - if (window.pywebview) window.pywebview.api.update_config('theme', e.target.value); - }); - - document.getElementById('lang_select')?.addEventListener('change', (e) => { - translateText(e.target.value); - if (window.pywebview) window.pywebview.api.update_config('language', e.target.value); - }); - - window.revertSwitch = (switchKey) => { - // No-op: Async handler in toggle switch automatically reverts based on backend response. }; + window.triggerContextScan = (path) => { + if (appState.scanning) return; + switchPage('scan_window'); + if (window.pywebview) { + appState.scanning = true; + appState.virusMap.clear(); + appState.virusResults = []; + renderDataGrid('#scan_window', appState.virusResults, cols.virus, 'path', true); + document.getElementById('scan_method_select')?.classList.add('hidden'); + const stopBtn = document.getElementById('stop_btn'); + if (stopBtn) { stopBtn.classList.remove('hidden'); stopBtn.disabled = false; } + changeScanSelectMode('scan'); + + const title = document.querySelector('#scan_window .section-title'); + const text = document.getElementById('progress_text'); + if (title) { title.setAttribute('data-i18n', 'status_scanning'); title.textContent = getMsg('status_scanning'); } + if (text) { text.setAttribute('data-i18n', 'msg_init'); text.removeAttribute('data-dynamic-msg'); text.textContent = getMsg('msg_init'); } + + window.pywebview.api.start_scan([path]); + } + }; + + window.revertSwitch = () => {}; + + document.querySelectorAll('[data-target]').forEach(btn => btn.addEventListener('click', (e) => switchPage(e.currentTarget.getAttribute('data-target')))); + document.getElementById('quick_scan_btn')?.addEventListener('click', () => { if (!appState.scanning) { switchPage('scan_window'); triggerScan('smart'); }}); + document.getElementById('stop_btn')?.addEventListener('click', (e) => { if (window.pywebview) window.pywebview.api.stop_scan(); e.target.disabled = true; }); + document.getElementById('theme_select')?.addEventListener('change', (e) => { applyTheme(e.target.value); window.pywebview?.api.update_config('theme', e.target.value); }); + document.getElementById('lang_select')?.addEventListener('change', (e) => { translateText(e.target.value); window.pywebview?.api.update_config('language', e.target.value); }); + + document.getElementById('scan_method_select')?.addEventListener('change', (e) => { + const val = e.target.value; + if (val === 'none' || appState.scanning) return; + if (['smart', 'file', 'path', 'full'].includes(val)) triggerScan(val); + else if (['delete', 'ignore', 'quarantine', 'whitelist'].includes(val)) handleVirusActions(val); + }); + document.querySelectorAll('.toggle-switch input').forEach((toggle, index) => { toggle.addEventListener('change', async (e) => { const switchMap = ["process_switch", "document_switch", "system_switch", "driver_switch", "network_switch", "sensitive_switch", "extension_switch", "cloud_switch", "context_switch"]; @@ -817,508 +666,241 @@ document.addEventListener('DOMContentLoaded', () => { toggle.disabled = true; try { const result = await window.pywebview.api.update_config(key, e.target.checked); - if (result !== undefined && result !== null) { - toggle.checked = result; - } - } catch (err) { - toggle.checked = !e.target.checked; - } finally { - toggle.disabled = false; - } + if (result !== undefined && result !== null) toggle.checked = result; + } catch { toggle.checked = !e.target.checked; } + finally { toggle.disabled = false; } } }); }); - window.triggerContextScan = (path) => { - if (isScanning) return; - switchPage('scan_window'); - if (window.pywebview) { - isScanning = true; - virusState.clear(); - window.virusResults = []; - renderDataGrid('#scan_window', window.virusResults, cols.virus, 'path', true); - scanMethodSelect.classList.add('hidden'); - stopBtn.classList.remove('hidden'); - stopBtn.disabled = false; - changeScanSelectMode('scan'); - if (progressTitle) { - progressTitle.setAttribute('data-i18n', ''); - progressTitle.dataset.originText = "正在掃描"; - progressTitle.textContent = getMsg("正在掃描"); + document.querySelector('#junk_window .primary-btn')?.addEventListener('click', (e) => { + if (!window.pywebview) return; + e.target.setAttribute('data-i18n', 'msg_init'); e.target.textContent = getMsg('msg_init'); + const widget = document.querySelector('#junk_window .manage-widget'); + if (widget?.gridState) widget.gridState.checkedSet.clear(); + + window.pywebview.api.scan_system_junk().then(list => { + appState.junkList = list.map(item => ({ path: item.path, sizeStr: formatSize(item.size), size: item.size })); + renderDataGrid('#junk_window', appState.junkList, cols.junk, 'path', true); + e.target.setAttribute('data-i18n', 'btn_scan'); e.target.textContent = getMsg('btn_scan'); + }); + }); + + document.querySelector('#junk_window .danger-btn')?.addEventListener('click', () => { + const checked = getCheckedValues('#junk_window'); + if (checked.length === 0 || !window.pywebview) return; + window.pywebview.api.clean_system_junk(checked).then(size => { + window.pywebview.api.show_alert(getMsg("title_prompt"), `${getMsg("msg_cleaned")}${formatSize(size)}`, "info"); + appState.junkList = appState.junkList.filter(item => !checked.includes(item.path)); + renderDataGrid('#junk_window', appState.junkList, cols.junk, 'path', true); + }); + }); + + document.querySelector('#repair_window .primary-btn')?.addEventListener('click', () => { + if (!window.pywebview) return; + window.pywebview.api.scan_system_repair().then(list => renderDataGrid('#repair_window', list, cols.repair, 'value', true)); + }); + + document.querySelector('#repair_window .danger-btn')?.addEventListener('click', () => { + const checked = getCheckedValues('#repair_window'); + if (checked.length === 0 || !window.pywebview) return; + window.pywebview.api.execute_system_repair(checked).then(() => { + window.pywebview.api.show_alert(getMsg("title_prompt"), getMsg("msg_repaired"), "info"); + renderDataGrid('#repair_window', [], cols.repair, 'value'); + }); + }); + + ['whitelist_window', 'quarantine_window', 'popup_window', 'custom_protect_window'].forEach(id => { + const listKey = id === 'popup_window' ? 'block_list' : (id === 'custom_protect_window' ? 'custom_rule' : id.replace('_window', '')); + document.querySelector(`#${id} .modern-btn:not(.primary-btn)`)?.addEventListener('click', () => { + const checked = getCheckedValues(`#${id}`); + if (checked.length > 0 && window.pywebview) window.pywebview.api.remove_list_items(listKey, checked).then(refreshConfigLists); + }); + + if (id !== 'popup_window') { + document.querySelector(`#${id} .primary-btn`)?.addEventListener('click', () => { + window.pywebview?.api.select_files().then(files => { + if (files?.length > 0) window.pywebview.api.manage_named_list(listKey, files, 'add').then(refreshConfigLists); + }); + }); + } + }); + + document.querySelector('#popup_window .primary-btn')?.addEventListener('click', (e) => { + if (!window.pywebview) return; + e.target.setAttribute('data-i18n', 'msg_click_target'); e.target.textContent = getMsg('msg_click_target'); e.target.disabled = true; + window.pywebview.api.capture_popup_window().then(rule => { + e.target.setAttribute('data-i18n', 'btn_add'); e.target.textContent = getMsg('btn_add'); e.target.disabled = false; + if (rule) window.pywebview.api.add_popup_rule(rule).then(ok => ok && refreshConfigLists()); + }); + }); + + document.querySelector('#taskmgr_window .primary-btn')?.addEventListener('click', () => { + if (!window.pywebview) return; + document.querySelectorAll('#taskmgr_window .manage-list-item input[type="checkbox"]:checked').forEach(cb => { + if (cb.dataset.path && cb.dataset.path !== "path_unknown") window.pywebview.api.open_file_location(cb.dataset.path); + }); + }); + + document.querySelector('#taskmgr_window .danger-btn')?.addEventListener('click', () => { + const cbs = document.querySelectorAll('#taskmgr_window .manage-list-item input[type="checkbox"]:checked'); + if (cbs.length > 0 && window.pywebview) { + window.pywebview.api.show_confirm(getMsg("msg_end_proc_title"), getMsg("msg_end_proc_confirm")).then(res => { + if (res) Promise.all(Array.from(cbs).map(cb => window.pywebview.api.kill_process(parseInt(cb.value)))).then(() => { + window.pywebview.api.get_process_list().then(procs => renderDataGrid('#taskmgr_window', procs.map(p => ({ name: p.name, pid: p.pid, path: (p.path && p.path !== "None" && p.path !== "Unknown") ? p.path : "path_unknown" })), cols.process, 'pid', false)); + }); + }); + } + }); + + document.querySelector('#log_export_window .primary-btn')?.addEventListener('click', () => { + const checked = getCheckedValues('#log_export_window'); + if (checked.length === 0) return window.pywebview?.api.show_alert(getMsg("title_prompt"), getMsg("msg_sel_log_export"), "warning"); + window.pywebview?.api.export_logs(checked).then(res => res && window.pywebview.api.show_alert(getMsg("title_prompt"), getMsg("msg_export_success"), "info")); + }); + + document.querySelector('#log_export_window .danger-btn')?.addEventListener('click', () => { + const checked = getCheckedValues('#log_export_window'); + if (checked.length === 0 || !window.pywebview) return; + window.pywebview.api.show_confirm(getMsg("title_prompt"), getMsg("msg_del_log_confirm")).then(res => { + if (res) window.pywebview.api.clear_logs(checked).then(() => { + window.pywebview.api.get_logs().then(logs => renderDataGrid('#log_export_window', logs.reverse().map(log => ({ time_str: `[${log.time_str}]`, level: log.level, action: log.action, source: log.source || '-', id: log.id })), cols.log, 'id', true)); + window.pywebview.api.show_alert(getMsg("title_prompt"), getMsg("msg_log_deleted"), "info"); + }); + }); + }); + + document.getElementById('minimize_button')?.addEventListener('click', () => window.pywebview?.api.minimize()); + document.getElementById('close_button')?.addEventListener('click', () => window.pywebview?.api.hide_window()); + + const contextMenu = document.createElement('div'); + contextMenu.className = 'custom-context-menu'; + contextMenu.innerHTML = `
    `; + document.body.appendChild(contextMenu); + let ctxTarget = null; + + document.addEventListener('contextmenu', (e) => { + const li = e.target.closest('.manage-list-item'); + if (li) { + const cb = li.querySelector('input[type="checkbox"]'); + if (cb && cb.dataset.path && cb.dataset.path !== "path_unknown") { + e.preventDefault(); + ctxTarget = cb.dataset.path; + const span = contextMenu.querySelector('span'); + span.textContent = getMsg('ctx_open_loc'); + contextMenu.style.left = `${e.clientX}px`; + contextMenu.style.top = `${e.clientY}px`; + contextMenu.classList.add('show'); + const rect = contextMenu.getBoundingClientRect(); + if (rect.right > window.innerWidth) contextMenu.style.left = `${window.innerWidth - rect.width - 5}px`; + if (rect.bottom > window.innerHeight) contextMenu.style.top = `${window.innerHeight - rect.height - 5}px`; + return; } - if (progressText) { - progressText.setAttribute('data-i18n', ''); - progressText.removeAttribute('data-dynamic-msg'); - progressText.dataset.originText = "正在初始化中"; - progressText.textContent = getMsg("正在初始化中"); + } + contextMenu.classList.remove('show'); + }); + document.addEventListener('click', (e) => { if (!e.target.closest('.custom-context-menu')) contextMenu.classList.remove('show'); }); + document.addEventListener('scroll', () => contextMenu.classList.remove('show'), true); + document.getElementById('ctx_open_location').addEventListener('click', () => { + if (window.pywebview && ctxTarget) window.pywebview.api.open_file_location(ctxTarget); + contextMenu.classList.remove('show'); + }); + + initI18nKeys(); + + const bindSettingAction = (key, action) => { + const item = Array.from(document.querySelectorAll('#about_window .list-item, #setting_window .list-item')).find(el => { + const h2 = el.querySelector('h2'); + return h2 && h2.getAttribute('data-i18n') === key; + }); + + if (item) { + const btn = item.querySelector('button'); + + if (btn) { + btn.addEventListener('click', action); + } else { + item.style.cursor = 'pointer'; + item.dataset.action = key; + item.addEventListener('click', action); } - window.pywebview.api.start_scan([path]); } }; + bindSettingAction('web_official', () => window.pywebview?.api.open_website()); + bindSettingAction('update_check', () => { + window.pywebview?.api.check_update().then(res => { + if (res.error) window.pywebview.api.show_alert(getMsg("title_error"), getMsg("msg_update_fail"), "error"); + else if (res.has_update) window.pywebview.api.show_confirm(getMsg("title_prompt"), `${getMsg("msg_new_version")} ${res.latest}\n(${res.current} -> ${res.latest})`).then(ok => ok && window.pywebview.api.open_url(res.url)); + else window.pywebview.api.show_alert(getMsg("title_prompt"), `${getMsg("msg_latest_version")} ${res.current}`, "info"); + }); + }); + bindSettingAction('opt_reset', () => { + window.pywebview?.api.show_confirm(getMsg("title_prompt"), getMsg("opt_reset_desc")).then(res => { + if (res) window.pywebview.api.reset_config().then(() => window.pywebview.api.show_alert(getMsg("title_prompt"), getMsg("msg_reset_success"), "info")); + }); + }); + + document.querySelectorAll('select.modern-select').forEach(buildCustomSelectElement); + renderDataGrid('#scan_window', appState.virusResults, cols.virus, 'path', true); + renderDataGrid('#taskmgr_window', [], cols.process, 'pid', false); + renderDataGrid('#junk_window', [], cols.junk, 'path', true); + renderDataGrid('#repair_window', [], cols.repair, 'value', true); + renderDataGrid('#whitelist_window', [], cols.pathOnly, 'path', false); + renderDataGrid('#quarantine_window', [], cols.pathOnly, 'path', false); + renderDataGrid('#custom_protect_window', [], cols.pathOnly, 'path', false); + renderDataGrid('#popup_window', [], cols.popup, 'value', false); + renderDataGrid('#log_export_window', [], cols.log, 'id', true); + window.addEventListener('pywebviewready', () => { - window.pywebview.api.get_config().then(async cfg => { + window.pywebview.api.get_config().then(cfg => { const theme = cfg.theme || "white_switch"; const lang = cfg.language || "english_switch"; + appState.firstLaunch = cfg.first_launch; applyTheme(theme); translateText(lang); updateCustomSelectUI('theme_select', theme); updateCustomSelectUI('lang_select', lang); const switchMap = ["process_switch", "document_switch", "system_switch", "driver_switch", "network_switch", "sensitive_switch", "extension_switch", "cloud_switch", "context_switch"]; + document.querySelectorAll('.toggle-switch input').forEach((toggle, index) => { + if (appState.firstLaunch) { + toggle.checked = false; + toggle.disabled = true; + } else if (switchMap[index]) { + toggle.checked = !!cfg[switchMap[index]]; + } + }); - isFirstLaunch = cfg.first_launch; - - if (isFirstLaunch) { - document.querySelectorAll('.toggle-switch input').forEach(toggle => { - toggle.checked = false; - toggle.disabled = true; - }); - } else { - document.querySelectorAll('.toggle-switch input').forEach((toggle, index) => { - if (switchMap[index]) { - toggle.checked = !!cfg[switchMap[index]]; - } - }); - } + window.pywebview.api.init_ui_ready(); + }).catch(err => { + console.error("Config load failed:", err); + window.pywebview.api.init_ui_ready(); }); - window.pywebview.api.init_ui_ready(); }); window.onEngineReady = async () => { - if (!isFirstLaunch) return; - - const switchMap = ["process_switch", "document_switch", "system_switch", "driver_switch", "network_switch", "sensitive_switch", "extension_switch", "cloud_switch", "context_switch"]; - + if (!appState.firstLaunch) return; await window.pywebview.api.update_config("first_launch", false); - - const sequence = [ - "cloud_switch", - "process_switch", "document_switch", "system_switch", "network_switch", - "driver_switch" - ]; - - for (const key of sequence) { + const switchMap = ["process_switch", "document_switch", "system_switch", "driver_switch", "network_switch", "sensitive_switch", "extension_switch", "cloud_switch", "context_switch"]; + const seq = ["cloud_switch", "process_switch", "document_switch", "system_switch", "network_switch", "driver_switch"]; + + for (const key of seq) { const index = switchMap.indexOf(key); if (index !== -1) { const toggle = document.querySelectorAll('.toggle-switch input')[index]; if (toggle) { toggle.checked = true; try { - const result = await window.pywebview.api.update_config(key, true); - if (result !== undefined && result !== null) { - toggle.checked = result; - } - } catch (e) { - toggle.checked = false; - } finally { - toggle.disabled = false; - } + const res = await window.pywebview.api.update_config(key, true); + if (res !== undefined && res !== null) toggle.checked = res; + } catch { toggle.checked = false; } + finally { toggle.disabled = false; } await new Promise(r => setTimeout(r, 200)); } } } - - document.querySelectorAll('.toggle-switch input').forEach(toggle => { - toggle.disabled = false; - }); - - isFirstLaunch = false; + document.querySelectorAll('.toggle-switch input').forEach(t => t.disabled = false); + appState.firstLaunch = false; }; - - window.updateLogs = (entry) => { - const logWidget = document.querySelector('.log-text'); - if (logWidget) { - let parts = [`[${entry.time_str}]`, entry.level, entry.action]; - if (entry.source) parts.push(`Src: ${entry.source}`); - if (entry.target) parts.push(`Tgt: ${entry.target}`); - if (entry.code) parts.push(`Code: ${entry.code}`); - if (entry.pid) parts.push(`PID: ${entry.pid}`); - if (entry.hash) parts.push(`Hash: ${entry.hash}`); - if (entry.detail) parts.push(`Detail: ${entry.detail}`); - if (entry.operate !== null) parts.push(`Op: ${entry.operate}`); - parts.push(`Success: ${entry.success}`); - - let val = logWidget.value + parts.join(' | ') + '\n'; - if (val.length > 20000) { - val = val.substring(val.length - 15000); - val = val.substring(val.indexOf('\n') + 1); - } - - logWidget.value = val; - logWidget.scrollTop = logWidget.scrollHeight; - } - - const exportWindow = document.getElementById('log_export_window'); - if (exportWindow && exportWindow.classList.contains('active')) { - if (window.pywebview) { - window.pywebview.api.get_logs().then(logs => { - const logList = logs.reverse().map(log => ({ - time_str: `[${log.time_str}]`, - level: log.level, - action: log.action, - source: log.source ? log.source : '-', - id: log.id - })); - renderDataGrid('#log_export_window', logList, cols.log, 'id', true); - }); - } - } - - if ((entry.action === 'System' && entry.detail === 'Engine Initialization Complete') || - (entry.level === 'WARN' && entry.action === 'init_engine_thread')) { - const overlay = document.getElementById('loading_overlay'); - const appContainer = document.querySelector('.app-container'); - if (overlay && !overlay.classList.contains('fade-out')) { - overlay.classList.add('fade-out'); - setTimeout(() => { - if (appContainer) appContainer.classList.add('fade-in'); - if (window.onEngineReady) window.onEngineReady(); - }, 400); - } - } - }; - - function formatSize(bytes) { - if (bytes === 0) return '0 B'; - const k = 1024; - const sizes = ['B', 'KB', 'MB', 'GB']; - const i = Math.floor(Math.log(bytes) / Math.log(k)); - return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; - } - - document.querySelector('#junk_window .primary-btn')?.addEventListener('click', () => { - if (!window.pywebview) return; - const btn = document.querySelector('#junk_window .primary-btn'); - btn.textContent = getMsg("正在初始化中"); - - const widget = document.querySelector('#junk_window .manage-widget'); - if (widget && widget.gridState) widget.gridState.checkedSet.clear(); - - window.pywebview.api.scan_system_junk().then(list => { - currentJunkList = list.map(item => ({ - path: item.path, - sizeStr: formatSize(item.size), - size: item.size - })); - renderDataGrid('#junk_window', currentJunkList, cols.junk, 'path', true); - btn.textContent = getMsg("掃描"); - }); - }); - - document.querySelector('#repair_window .primary-btn')?.addEventListener('click', () => { - if (!window.pywebview) return; - const widget = document.querySelector('#repair_window .manage-widget'); - if (widget && widget.gridState) widget.gridState.checkedSet.clear(); - - window.pywebview.api.scan_system_repair().then(list => { - const repairData = list.map(item => ({ display: getMsg(item.display), value: item.value })); - renderDataGrid('#repair_window', repairData, cols.repair, 'value', true); - }); - }); - - document.querySelector('#junk_window .danger-btn')?.addEventListener('click', () => { - if (!window.pywebview) return; - const checkedPaths = getCheckedValues('#junk_window'); - if (checkedPaths.length === 0) return; - - window.pywebview.api.clean_system_junk(checkedPaths).then(deletedSize => { - const msg = getMsg("已清理 "); - window.pywebview.api.show_alert(getMsg("提示"), `${msg}${formatSize(deletedSize)}`, "info"); - currentJunkList = currentJunkList.filter(item => !checkedPaths.includes(item.path)); - renderDataGrid('#junk_window', currentJunkList, cols.junk, 'path', true); - }); - }); - - function refreshConfigLists() { - if (!window.pywebview) return; - window.pywebview.api.get_config().then(cfg => { - renderDataGrid('#whitelist_window', (cfg.white_list || []).map(i => ({path: i.file || i})), cols.pathOnly, 'path'); - renderDataGrid('#quarantine_window', (cfg.quarantine || []).map(i => ({path: i.file || i})), cols.pathOnly, 'path'); - renderDataGrid('#custom_protect_window', (cfg.custom_rule || []).map(i => ({path: i.file || i})), cols.pathOnly, 'path'); - - const popupRules = (cfg.block_list || []).map(item => ({ - exe: item.exe || '*', - class: item.class || '*', - title: item.title || '*', - value: item.exe || item.title - })); - renderDataGrid('#popup_window', popupRules, cols.popup, 'value'); - }); - } - - document.querySelector('#whitelist_window .modern-btn:not(.primary-btn)')?.addEventListener('click', () => { - if (!window.pywebview) return; - const checked = getCheckedValues('#whitelist_window'); - if (checked.length > 0) window.pywebview.api.remove_list_items('white_list', checked).then(refreshConfigLists); - }); - - document.querySelector('#quarantine_window .modern-btn:not(.primary-btn)')?.addEventListener('click', () => { - if (!window.pywebview) return; - const checked = getCheckedValues('#quarantine_window'); - if (checked.length > 0) window.pywebview.api.remove_list_items('quarantine', checked).then(refreshConfigLists); - }); - - document.querySelector('#popup_window .modern-btn:not(.primary-btn)')?.addEventListener('click', () => { - if (!window.pywebview) return; - const checked = getCheckedValues('#popup_window'); - if (checked.length > 0) window.pywebview.api.remove_list_items('block_list', checked).then(refreshConfigLists); - }); - - document.querySelector('#custom_protect_window .modern-btn:not(.primary-btn)')?.addEventListener('click', () => { - if (!window.pywebview) return; - const checked = getCheckedValues('#custom_protect_window'); - if (checked.length > 0) window.pywebview.api.remove_list_items('custom_rule', checked).then(refreshConfigLists); - }); - - document.querySelector('#whitelist_window .primary-btn')?.addEventListener('click', () => { - window.pywebview?.api.select_files().then(files => { - if (files && files.length > 0) window.pywebview.api.manage_named_list('white_list', files, 'add').then(refreshConfigLists); - }); - }); - - document.querySelector('#quarantine_window .primary-btn')?.addEventListener('click', () => { - window.pywebview?.api.select_files().then(files => { - if (files && files.length > 0) window.pywebview.api.manage_named_list('quarantine', files, 'add').then(refreshConfigLists); - }); - }); - - document.querySelector('#custom_protect_window .primary-btn')?.addEventListener('click', () => { - window.pywebview?.api.select_files().then(files => { - if (files && files.length > 0) window.pywebview.api.manage_named_list('custom_rule', files, 'add').then(refreshConfigLists); - }); - }); - - document.querySelector('#repair_window .primary-btn')?.addEventListener('click', () => { - if (!window.pywebview) return; - window.pywebview.api.scan_system_repair().then(list => { - const repairData = list.map(item => ({ display: getMsg(item.display), value: item.value })); - renderDataGrid('#repair_window', repairData, cols.repair, 'value', true); - }); - }); - - document.querySelector('#repair_window .danger-btn')?.addEventListener('click', () => { - if (!window.pywebview) return; - const checkedPaths = getCheckedValues('#repair_window'); - if (checkedPaths.length === 0) return; - window.pywebview.api.execute_system_repair(checkedPaths).then(() => { - const msg = getMsg("已修復選取項目"); - window.pywebview.api.show_alert(getMsg("提示"), msg, "info"); - renderDataGrid('#repair_window', [], cols.repair, 'value'); - }); - }); - - document.getElementById('minimize_button')?.addEventListener('click', () => window.pywebview?.api.minimize()); - document.getElementById('close_button')?.addEventListener('click', () => window.pywebview?.api.hide_window()); - - const websiteBtn = Array.from(document.querySelectorAll('#about_window .list-item')).find(el => { - const h2 = el.querySelector('h2'); - return h2 && (h2.dataset.originText === '官方網站' || h2.textContent.includes('官方網站')); - }); - if (websiteBtn) { - websiteBtn.querySelector('button').addEventListener('click', () => { - if (window.pywebview) window.pywebview.api.open_website(); - }); - } - - const updateBtn = Array.from(document.querySelectorAll('#about_window .list-item')).find(el => { - const h2 = el.querySelector('h2'); - return h2 && (h2.dataset.originText === '檢查更新' || h2.textContent.includes('檢查更新')); - }); - if (updateBtn) { - updateBtn.querySelector('button').addEventListener('click', () => { - if (window.pywebview) { - window.pywebview.api.check_update().then(res => { - if (res.error) { - window.pywebview.api.show_alert(getMsg("錯誤"), getMsg("檢查更新失敗"), "error"); - } else if (res.has_update) { - const msg = getMsg("發現新版本"); - window.pywebview.api.show_confirm(getMsg("提示"), `${msg} ${res.latest}\n(${res.current} -> ${res.latest})`).then(confirmRes => { - if (confirmRes) window.pywebview.api.open_url(res.url); - }); - } else { - const msg = getMsg("當前已是最新版本"); - window.pywebview.api.show_alert(getMsg("提示"), `${msg} ${res.current}`, "info"); - } - }); - } - }); - } - - const resetBtn = Array.from(document.querySelectorAll('#setting_window .list-item')).find(el => { - const h2 = el.querySelector('h2'); - return h2 && (h2.dataset.originText === '重置選項' || h2.textContent.includes('重置選項')); - }); - if (resetBtn) { - resetBtn.querySelector('button').addEventListener('click', () => { - const confirmMsg = getMsg("此選項可以重置所有設定"); - if (window.pywebview) { - window.pywebview.api.show_confirm(getMsg("提示"), confirmMsg).then(res => { - if (res) { - window.pywebview.api.reset_config().then(() => { - window.pywebview.api.show_alert(getMsg("提示"), getMsg("設定已重置,請重新啟動程式以套用預設值。"), "info"); - }); - } - }); - } - }); - } - - document.querySelector('#log_export_window .primary-btn')?.addEventListener('click', () => { - if (window.pywebview) { - const checkedIds = getCheckedValues('#log_export_window'); - if (checkedIds.length === 0) { - window.pywebview.api.show_alert(getMsg("提示"), getMsg("請選擇要導出的日誌"), "warning"); - return; - } - window.pywebview.api.export_logs(checkedIds).then(res => { - if (res) window.pywebview.api.show_alert(getMsg("提示"), getMsg("導出成功"), "info"); - }); - } - }); - - document.querySelector('#log_export_window .danger-btn')?.addEventListener('click', () => { - const checkedIds = getCheckedValues('#log_export_window'); - if (checkedIds.length === 0) return; - - const confirmMsg = getMsg("確定刪除選取的日誌記錄嗎?"); - if (window.pywebview) { - window.pywebview.api.show_confirm(getMsg("提示"), confirmMsg).then(res => { - if (res) { - window.pywebview.api.clear_logs(checkedIds).then(() => { - window.pywebview.api.get_logs().then(logs => { - const logList = logs.reverse().map(log => ({ - time_str: `[${log.time_str}]`, - level: log.level, - action: log.action, - source: log.source ? log.source : '-', - id: log.id - })); - renderDataGrid('#log_export_window', logList, cols.log, 'id', true); - }); - const successMsg = getMsg("選取的日誌已刪除。"); - window.pywebview.api.show_alert(getMsg("提示"), successMsg, "info"); - }); - } - }); - } - }); - - let currentProcessList = []; - function updateProcessList(procs) { - currentProcessList = procs.map(p => ({ - name: p.name, - pid: p.pid, - path: p.path && p.path !== "None" ? p.path : getMsg("未知路徑") - })); - renderDataGrid('#taskmgr_window', currentProcessList, cols.process, 'pid', false); - } - - document.querySelector('#taskmgr_window .primary-btn')?.addEventListener('click', () => { - const cbs = document.querySelectorAll('#taskmgr_window .manage-list-item input[type="checkbox"]:checked'); - if (cbs.length > 0 && window.pywebview) { - cbs.forEach(cb => { - const path = cb.dataset.path; - if (path && path !== "Unknown" && path !== "None") { - window.pywebview.api.open_file_location(path); - } - }); - } - }); - - document.querySelector('#popup_window .primary-btn')?.addEventListener('click', () => { - if (!window.pywebview) return; - const btn = document.querySelector('#popup_window .primary-btn'); - const originalText = btn.textContent; - const waitText = getMsg("請在5秒內點擊目標視窗..."); - - btn.textContent = waitText; - btn.disabled = true; - - window.pywebview.api.capture_popup_window().then(rule => { - btn.textContent = originalText; - btn.disabled = false; - if (rule) { - window.pywebview.api.add_popup_rule(rule).then(success => { - if (success) refreshConfigLists(); - }); - } - }); - }); - - document.querySelector('#taskmgr_window .danger-btn')?.addEventListener('click', () => { - const cbs = document.querySelectorAll('#taskmgr_window .manage-list-item input[type="checkbox"]:checked'); - const confirmMsg = getMsg("確定要結束選取的進程嗎?"); - if (cbs.length > 0 && window.pywebview) { - window.pywebview.api.show_confirm(getMsg("提示"), confirmMsg).then(res => { - if (res) { - const promises = Array.from(cbs).map(cb => window.pywebview.api.kill_process(parseInt(cb.value))); - Promise.all(promises).then(() => { - window.pywebview.api.get_process_list().then(updateProcessList); - }); - } - }); - } - }); - - const contextMenu = document.createElement('div'); - contextMenu.className = 'custom-context-menu'; - contextMenu.innerHTML = ` -
    - - 打開檔案所在位置 -
    - `; - document.body.appendChild(contextMenu); - - const ctxSpan = contextMenu.querySelector('span[data-i18n]'); - ctxSpan.dataset.originText = ctxSpan.textContent.trim(); - - let contextMenuTarget = null; - - document.addEventListener('contextmenu', (e) => { - const listItem = e.target.closest('.manage-list-item'); - if (listItem) { - const cb = listItem.querySelector('input[type="checkbox"]'); - const path = cb ? cb.dataset.path : null; - - if (path && path !== "Unknown" && path !== "None") { - e.preventDefault(); - contextMenuTarget = path; - - ctxSpan.textContent = getMsg(ctxSpan.dataset.originText); - - contextMenu.style.left = `${e.clientX}px`; - contextMenu.style.top = `${e.clientY}px`; - contextMenu.classList.add('show'); - - const rect = contextMenu.getBoundingClientRect(); - if (rect.right > window.innerWidth) { - contextMenu.style.left = `${window.innerWidth - rect.width - 5}px`; - } - if (rect.bottom > window.innerHeight) { - contextMenu.style.top = `${window.innerHeight - rect.height - 5}px`; - } - return; - } - } - contextMenu.classList.remove('show'); - }); - - document.addEventListener('click', (e) => { - if (!e.target.closest('.custom-context-menu')) { - contextMenu.classList.remove('show'); - } - }); - - document.addEventListener('scroll', () => { - contextMenu.classList.remove('show'); - }, true); - - document.getElementById('ctx_open_location').addEventListener('click', () => { - if (window.pywebview && contextMenuTarget) { - window.pywebview.api.open_file_location(contextMenuTarget); - } - contextMenu.classList.remove('show'); - }); }); \ No newline at end of file diff --git a/Interface/templates/index.html b/Interface/templates/index.html index b5d8454..e56cbb8 100644 --- a/Interface/templates/index.html +++ b/Interface/templates/index.html @@ -158,7 +158,7 @@
    -

    系統修復

    此選項可以修復系統註冊項目

    +

    系統修復

    此選項可以修復系統登錄檔項目

    diff --git a/PYAS.py b/PYAS.py index e01be23..2545af1 100644 --- a/PYAS.py +++ b/PYAS.py @@ -69,6 +69,13 @@ class PROCESS_BASIC_INFORMATION(ctypes.Structure): ("Reserved3", ctypes.wintypes.LPVOID) ] +class SHQUERYRBINFO(ctypes.Structure): + _fields_ = [ + ("cbSize", ctypes.wintypes.DWORD), + ("i64Size", ctypes.c_int64), + ("i64NumItems", ctypes.c_int64) + ] + class UNICODE_STRING(ctypes.Structure): _fields_ = [ ("Length", ctypes.wintypes.USHORT), @@ -244,6 +251,10 @@ class WindowAPI: self.shell32.CommandLineToArgvW.argtypes = [ctypes.wintypes.LPCWSTR, ctypes.POINTER(ctypes.c_int)] self.shell32.CommandLineToArgvW.restype = ctypes.POINTER(ctypes.wintypes.LPWSTR) + self.shell32.SHEmptyRecycleBinW.argtypes = [ctypes.wintypes.HWND, ctypes.c_wchar_p, ctypes.wintypes.DWORD] + self.shell32.SHEmptyRecycleBinW.restype = ctypes.c_long + self.shell32.SHQueryRecycleBinW.argtypes = [ctypes.c_wchar_p, ctypes.POINTER(SHQUERYRBINFO)] + self.shell32.SHQueryRecycleBinW.restype = ctypes.c_long self.fltlib.FilterConnectCommunicationPort.argtypes = [ctypes.wintypes.LPCWSTR, ctypes.wintypes.DWORD, ctypes.c_void_p, ctypes.wintypes.DWORD, ctypes.c_void_p, ctypes.POINTER(ctypes.wintypes.HANDLE)] self.fltlib.FilterConnectCommunicationPort.restype = ctypes.c_long @@ -1235,6 +1246,8 @@ class WindowAPI: except Exception: pass else: + if file.lower().endswith(('.sys', '.dll', '.exe', '.ini', '.dat')): + continue size = os.path.getsize(file) os.remove(file) deleted += size @@ -1245,16 +1258,46 @@ class WindowAPI: def scan_system_junk(self): junk_list = [] try: - for path in [self.path_temp, self.path_systemp]: + safe_dirs = [ + self.path_temp, + self.path_systemp, + os.path.join(self.path_system, "SoftwareDistribution", "Download") + ] + + for path in safe_dirs: if os.path.exists(path): for root, dirs, files in os.walk(path): for file in files: + if file.lower().endswith(('.sys', '.dll', '.exe', '.ini', '.dat')): + continue full_path = os.path.join(root, file) try: size = os.path.getsize(full_path) junk_list.append({"path": full_path, "size": size}) except Exception: pass + + log_dir = os.path.join(self.path_system, "Logs") + if os.path.exists(log_dir): + for root, dirs, files in os.walk(log_dir): + for file in files: + if file.lower().endswith(('.log', '.etl', '.evtx')): + full_path = os.path.join(root, file) + try: + size = os.path.getsize(full_path) + junk_list.append({"path": full_path, "size": size}) + except Exception: + pass + + try: + info = SHQUERYRBINFO() + info.cbSize = ctypes.sizeof(SHQUERYRBINFO) + if self.shell32.SHQueryRecycleBinW(None, ctypes.byref(info)) == 0: + if info.i64Size > 0: + junk_list.append({"path": "Recycle Bin", "size": info.i64Size}) + except Exception: + pass + return junk_list except Exception as e: @@ -1266,6 +1309,11 @@ class WindowAPI: try: if paths_to_delete is not None: for path in paths_to_delete: + if path == "Recycle Bin": + self.shell32.SHEmptyRecycleBinW(None, None, 7) + continue + if path.lower().endswith(('.sys', '.dll', '.exe', '.ini', '.dat')): + continue try: size = os.path.getsize(path) os.remove(path) @@ -1273,9 +1321,39 @@ class WindowAPI: except Exception: pass else: - for path in [self.path_temp, self.path_systemp]: + safe_dirs = [ + self.path_temp, + self.path_systemp, + os.path.join(self.path_system, "SoftwareDistribution", "Download") + ] + + for path in safe_dirs: total_deleted += self._traverse_delete(path) - + + log_dir = os.path.join(self.path_system, "Logs") + if os.path.exists(log_dir): + for root, dirs, files in os.walk(log_dir): + for file in files: + if file.lower().endswith(('.log', '.etl', '.evtx')): + full_path = os.path.join(root, file) + try: + size = os.path.getsize(full_path) + os.remove(full_path) + total_deleted += size + except Exception: + pass + + try: + self.shell32.SHEmptyRecycleBinW(None, None, 7) + except Exception: + pass + + try: + for log_type in ["Application", "Security", "Setup", "System"]: + subprocess.run(["wevtutil", "cl", log_type], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, creationflags=0x08000000) + except Exception: + pass + self.write_log("INFO", "Clean Junk", detail=f"Deleted {total_deleted // 1024} KB", operate=True) return total_deleted