Compare commits

..
18 Commits
Author SHA1 Message Date
87owo f5abaf06de Add files via upload 2026-04-08 17:57:14 +08:00
87owo 88023dd09e Add files via upload 2026-04-08 01:20:52 +08:00
87owo eec2996fab Add files via upload 2026-04-07 23:53:35 +08:00
87owo 97ca200c29 Add files via upload 2026-04-07 23:52:55 +08:00
87owo f0600ea3a3 Add files via upload 2026-04-07 23:52:20 +08:00
87owo 19b3eb51d7 Add files via upload 2026-04-04 16:02:36 +08:00
87owo 871dabf142 Add files via upload 2026-04-02 01:30:02 +08:00
87owo 58795b9349 Add files via upload 2026-04-01 23:42:12 +08:00
87owo 1ef769842b Add files via upload 2026-04-01 22:45:57 +08:00
87owo 6051570414 Add files via upload 2026-04-01 22:45:18 +08:00
87owo da5d5d0dc7 Add files via upload 2026-03-31 19:39:18 +08:00
87owo 782aa22d4d Add files via upload 2026-03-31 19:14:08 +08:00
87owo 0084867f38 Add files via upload 2026-03-29 21:14:20 +08:00
87owo 5a27858f86 Add files via upload 2026-03-27 02:17:54 +08:00
87owo 7905d8375f Add files via upload 2026-03-25 15:59:26 +08:00
87owo ba8aa63d75 Add files via upload 2026-03-16 15:10:16 +08:00
87owo ac82778e26 Add files via upload 2026-03-11 17:55:19 +08:00
87owo 55d2661e38 Add files via upload 2026-03-11 17:37:54 +08:00
4 changed files with 250 additions and 151 deletions

No files matched your search

+112 -29
View File
@@ -151,12 +151,12 @@ class MainWindow_Controller(QMainWindow):
"hindi_switch", "arabic_switch", "russian_switch", "slovenian_switch",
]
self.pyas_default = {
"version": "3.4.2",
"version": "3.4.5",
"api_host": "https://pyas-security.com/",
"api_key": "fBRZxYS1UxykM-qzNOlKOEl63WILzlvgNMn6QfsG6FXCAAIktCrOPTAfY5_hEyuZ",
"suffix": [".exe", ".dll", ".sys", ".ocx", ".scr", ".efi", ".acm", ".ax", ".cpl", ".drv", ".com", ".mui", ".pyd"],
"block": [2001, 3001, 4001, 5001, 6001],
"size": 256 * 1024 * 1024,
"block": [3001, 5001, 6001],
"size": 100 * 1024 * 1024,
"language": "english_switch",
"theme": "white_switch",
"process_switch": True,
@@ -309,9 +309,32 @@ class MainWindow_Controller(QMainWindow):
if k.endswith("_button") and isinstance(v, bool) and k.replace("_button", "_window") in self.widgets:
continue
filter_config[k] = v
path = os.path.dirname(file_path)
if not os.path.exists(path):
os.makedirs(path)
if os.path.exists(file_path):
old_config = self.read_config(file_path, {})
changes = []
for k, v in filter_config.items():
if k not in old_config:
changes.append(f"增加 [{k}]")
elif old_config[k] != v:
if isinstance(v, (list, dict)):
changes.append(f"更新 [{k}]")
else:
changes.append(f"更新 [{k}]: {old_config[k]} -> {v}")
for k in old_config:
if k not in filter_config:
changes.append(f"刪除 [{k}]")
if changes:
self.send_message(f"配置更新 | {', '.join(changes)}", "config", True)
with open(file_path, "w", encoding="utf-8", errors="ignore") as f:
f.write(json.dumps(filter_config, indent=4, ensure_ascii=False))
except Exception as e:
@@ -374,11 +397,15 @@ class MainWindow_Controller(QMainWindow):
"taskmgr_window", "tool_window", "scan_window", "home_window"]]
for w in self.sub_window:
if w: w.hide()
if w:
w.hide()
for w in self.main_window + self.menu_window:
if w: w.raise_()
if w:
w.raise_()
for w in self.menu_window + self.blank_window:
if w: w.setGraphicsEffect(self.create_shadow())
if w:
w.setAttribute(Qt.WA_StyledBackground, True)
w.setGraphicsEffect(self.create_shadow())
self.last_widget = self.widgets.get("home_window")
self.setup_theme_mapping()
@@ -451,33 +478,53 @@ class MainWindow_Controller(QMainWindow):
def save_state(self, name, checked):
self.pyas_config[name] = bool(checked)
if name == "sensitive_switch":
pass
if checked:
if not self.isVisible():
self.save_config(self.file_config, self.pyas_config)
elif self.send_message("增強模式可能會誤報檔案,您確定要啟用嗎?", "quest", True):
self.save_config(self.file_config, self.pyas_config)
else:
self.pyas_config[name] = False
if name in self.widgets:
QTimer.singleShot(0, lambda: self.widgets[name].setChecked(False))
else:
self.save_config(self.file_config, self.pyas_config)
elif name == "extension_switch":
pass
self.save_config(self.file_config, self.pyas_config)
elif name == "cloud_switch":
pass
self.save_config(self.file_config, self.pyas_config)
elif name == "process_switch":
if checked:
self.start_daemon_thread(self.protect_proc_thread)
self.save_config(self.file_config, self.pyas_config)
elif name == "document_switch":
if checked:
self.start_daemon_thread(self.protect_file_thread)
self.save_config(self.file_config, self.pyas_config)
elif name == "system_switch":
if checked:
self.start_daemon_thread(self.protect_system_thread)
elif name == "driver_switch":
if not checked:
self.stop_system_driver()
elif self.install_system_driver():
self.start_daemon_thread(self.pipe_server_thread)
else:
self.send_message("驅動防護啟用失敗,請重啟裝置來修復錯誤", "warn", True)
self.save_config(self.file_config, self.pyas_config)
elif name == "network_switch":
if checked:
self.start_daemon_thread(self.protect_net_thread)
self.save_config(self.file_config, self.pyas_config)
elif name == "driver_switch":
if checked:
if self.install_system_driver():
self.start_daemon_thread(self.pipe_server_thread)
else:
self.pyas_config[name] = False
if name in self.widgets:
QTimer.singleShot(0, lambda: self.widgets[name].setChecked(False))
self.send_message("驅動防護啟用失敗", "warn", True)
else:
self.stop_system_driver()
self.save_config(self.file_config, self.pyas_config)
else:
self.send_message(f"此功能不支持使用", "info", True)
self.save_config(self.file_config, self.pyas_config)
def init_thread(self):
self.start_daemon_thread(self.popup_intercept_thread)
@@ -540,7 +587,20 @@ class MainWindow_Controller(QMainWindow):
style = widget._origin_style
for k, v in theme_map.items():
style = style.replace(str(k), str(v))
widget.setStyleSheet(style)
widget.style().unpolish(widget)
widget.style().polish(widget)
try:
widget.update()
except TypeError:
if hasattr(widget, "viewport"):
widget.viewport().update()
effect = widget.graphicsEffect()
if effect:
effect.update()
mapping = getattr(widget, "_theme_mapping", None)
if isinstance(mapping, dict):
@@ -632,7 +692,7 @@ class MainWindow_Controller(QMainWindow):
if widget in (scan_win, method_win):
if getattr(self, "scan_finished", False):
self.widgets["solve_button"].setVisible(len(self.virus_results) > 0)
self.widgets["solve_button"].setVisible(False)
self.widgets["stop_button"].hide()
self.widgets["method_button"].show()
@@ -697,6 +757,9 @@ class MainWindow_Controller(QMainWindow):
self.init_connect()
self.apply_settings()
current_version = self.pyas_config.get("version", "None")
self.send_message(f"當前版本 | {current_version}", "version", True)
param = self.args_pyas[0].replace("/", "-") if self.args_pyas else ""
if "-h" not in param:
self.show_button()
@@ -861,7 +924,7 @@ class MainWindow_Controller(QMainWindow):
@Slot()
def slot_scan_reset(self):
count = len(self.virus_results)
self.widgets["solve_button"].setVisible(count > 0)
self.widgets["solve_button"].setVisible(False)
self.widgets["virus_list"].clear()
self.widgets["method_window"].hide()
self.widgets["stop_button"].setVisible(self.scan_running)
@@ -974,6 +1037,7 @@ class MainWindow_Controller(QMainWindow):
self.virus_results.append(norm_path)
self.scan_add_virus_signal.emit(f"[{result}] > {norm_path}")
self.start_daemon_thread(self.cloud_check, norm_path)
self.send_message(f"病毒掃描 | scan_worker | None | None | {norm_path}", "scan", True)
lang = self.pyas_config.get("language", "english_switch")
self.progress_title_signal.emit(self.trans(lang, "正在掃描"))
@@ -1035,7 +1099,7 @@ class MainWindow_Controller(QMainWindow):
####################################################################################################
def init_cloud_worker(self):
for _ in range(1):
for _ in range(4):
t = threading.Thread(target=self.cloud_worker, daemon=True)
t.start()
@@ -1068,7 +1132,7 @@ class MainWindow_Controller(QMainWindow):
was_locked = True
size = os.path.getsize(file_path)
if size > self.pyas_config.get("size", 256 * 1024 * 1024):
if size > self.pyas_config.get("size", 100 * 1024 * 1024):
if was_locked:
self.lock_file(file_path, True)
return False
@@ -1101,6 +1165,7 @@ class MainWindow_Controller(QMainWindow):
def solve_button(self):
if self.send_message("您確定要刪除檔案嗎?", "quest"):
self.widgets["solve_button"].setVisible(False)
deleted = 0
virus_list = self.widgets["virus_list"]
start_ts = time.time()
@@ -1208,9 +1273,6 @@ class MainWindow_Controller(QMainWindow):
except Exception as e:
self.send_message(f"show_scan_menu | {e}", "warn", False)
count = len(self.virus_results)
self.widgets["solve_button"].setVisible(count > 0)
####################################################################################################
def list_process(self):
@@ -1829,9 +1891,10 @@ class MainWindow_Controller(QMainWindow):
current = str(self.pyas_config.get("version", "")).strip()
page = "https://github.com/87owo/PYAS/releases"
latest = ""
try:
j = requests.get("https://api.github.com/repos/87owo/PYAS/releases/latest", headers={"Accept": "application/vnd.github+json", "User-Agent": "PYAS"}, timeout=10).json()
latest = (j.get("tag_name") or j.get("name") or "").strip()
latest = str(j.get("tag_name") or j.get("name") or "").strip()
page = j.get("html_url") or page
except Exception:
try:
@@ -1842,10 +1905,15 @@ class MainWindow_Controller(QMainWindow):
except Exception:
pass
rl = re.sub(r"^[vV]\s*", "", str(latest))
cl = re.sub(r"^[vV]\s*", "", str(current))
if not latest:
self.send_message("檢查更新失敗", "error", True)
return False
rl = re.sub(r"^[vV]\s*", "", latest)
cl = re.sub(r"^[vV]\s*", "", current)
tr = tuple(int(x) for x in re.findall(r"\d+", rl))
tl = tuple(int(x) for x in re.findall(r"\d+", cl))
if tr and (not tl or tr > tl):
if self.send_message(f"發現新版本 {latest},您確定要前往更新嗎?", "quest", True):
webbrowser.open(page)
@@ -1855,8 +1923,9 @@ class MainWindow_Controller(QMainWindow):
else:
webbrowser.open(page)
return True
except Exception as e:
self.send_message(f"update_button | {e}", "warn", False)
self.send_message(f"update_button | {e}", "error", False)
return False
####################################################################################################
@@ -2197,7 +2266,7 @@ class MainWindow_Controller(QMainWindow):
winreg.SetValueEx(key, "Flags", 0, winreg.REG_DWORD, 0)
subprocess.run(["sc", "start", service_name], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, shell=True)
return True
return self.check_system_driver()
except Exception as e:
self.send_message(f"install_system_driver | {e}", "warn", False)
return False
@@ -2219,6 +2288,20 @@ class MainWindow_Controller(QMainWindow):
except Exception:
return False
def check_system_driver(self):
try:
service_name = "PYAS_Driver"
result = subprocess.run(
["sc", "query", service_name],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
shell=True
)
return "RUNNING" in result.stdout
except Exception:
return False
####################################################################################################
def pipe_server_thread(self):
+100 -80
View File
@@ -538,10 +538,12 @@ class pe_scanner:
pe = None
try:
fsize = os.path.getsize(file_path)
if fsize == 0 or fsize > 268435456:
if fsize == 0 or fsize > 512 * 1024 * 1024:
return None
with open(file_path, "rb") as f:
file_bytes = f.read()
pe = pefile.PE(data=file_bytes, fast_load=True)
fts['TrustSigned'] = 1 if self.signer.sign_verify(file_path) else 0
fh = pe.FILE_HEADER
@@ -800,7 +802,26 @@ class pe_scanner:
class cloud_scanner:
def __init__(self):
pass
self.session = None
self.api_host = None
self.api_key = None
self.timeout = 30
def _init_session(self, api_host, api_key):
if self.session is None or self.api_host != api_host or self.api_key != api_key:
self.api_host = api_host.rstrip('/')
self.api_key = api_key
self.session = requests.Session()
self.session.headers.update({"X-API-Key": api_key, "User-Agent": "PYAS-Engine/1.2"})
def _request(self, method, endpoint, **kwargs):
try:
r = self.session.request(method, f"{self.api_host}{endpoint}", timeout=self.timeout, **kwargs)
if r.status_code == 200:
return r
except Exception:
pass
return None
def calc_hash(self, file_path, block_size=65536):
try:
@@ -814,107 +835,106 @@ class cloud_scanner:
####################################################################################################
def upload_file(self, file_path, api_host, api_key):
def rescan(self, sha256, api_host, api_key):
self._init_session(api_host, api_key)
r = self._request("POST", f"/api/rescan/{sha256}")
return r is not None and r.json().get('status') == 'success'
def upload_file(self, file_path, api_host, api_key, chunk_size=5242880):
try:
self._init_session(api_host, api_key)
sha256 = self.calc_hash(file_path)
if not sha256:
return False, None
base = api_host.rstrip('/')
base_headers = {"X-API-Key": api_key, "User-Agent": "PYAS-Client/1.0"}
status_req = self._request("GET", f"/api/processing_status/{sha256}")
if status_req and status_req.json().get('status') != 'missing':
self.rescan(sha256, api_host, api_key)
return True, sha256
def _req(m, ep, files=None, req_timeout=5, **k):
try:
return requests.request(m, f"{base}{ep}", headers=base_headers, files=files, timeout=req_timeout, **k)
except:
return None
file_size = os.path.getsize(file_path)
if file_size > 104857600:
return False, sha256
r = _req("GET", f"/api/processing_status/{sha256}", req_timeout=15)
status = 'missing'
if r and r.status_code == 200:
try:
status = r.json().get('status', 'missing')
except Exception:
pass
if status in ['failed', 'error']:
status = 'missing'
if status == 'missing':
if file_size > chunk_size:
total_chunks = (file_size + chunk_size - 1) // chunk_size
upload_id = os.urandom(16).hex()
with open(file_path, 'rb') as f:
r = _req("POST", "/api/upload", files={'file': f}, req_timeout=30)
if not r or r.status_code != 200:
return False, sha256
for i in range(total_chunks):
chunk_data = f.read(chunk_size)
headers = {
"X-Chunk-Index": str(i),
"X-Total-Chunks": str(total_chunks),
"X-Upload-ID": upload_id
}
chunk_success = False
for _ in range(3):
r = self._request("POST", "/api/upload", files={'file': (os.path.basename(file_path), chunk_data)}, headers=headers)
if r:
chunk_success = True
break
time.sleep(1)
if not chunk_success:
return False, sha256
return True, sha256
return True, sha256
with open(file_path, 'rb') as f:
file_data = f.read()
for _ in range(3):
r = self._request("POST", "/api/upload", files={'file': (os.path.basename(file_path), file_data)})
if r:
return True, sha256
time.sleep(1)
return False, sha256
except Exception:
return False, None
####################################################################################################
def get_result(self, sha256, api_host, api_key):
def get_result(self, sha256, api_host, api_key, max_retries=6, interval=10):
try:
if not sha256:
return False
self._init_session(api_host, api_key)
base = api_host.rstrip('/')
headers = {"X-API-Key": api_key, "User-Agent": "PYAS-Client/1.0"}
def _req(m, ep, req_timeout, **k):
try:
return requests.request(m, f"{base}{ep}", headers=headers, timeout=req_timeout, **k)
except requests.exceptions.Timeout:
return "timeout"
except Exception:
return None
timeout_count = 0
for _ in range(30):
r = _req("GET", f"/api/processing_status/{sha256}", req_timeout=15)
if r == "timeout" or r is None:
timeout_count += 1
if timeout_count >= 3:
is_done = False
for _ in range(max_retries):
r = self._request("GET", f"/api/processing_status/{sha256}")
if r:
st = r.json().get('status', 'error')
if st == 'done':
is_done = True
break
if st in ['error', 'failed']:
return False
time.sleep(1)
continue
time.sleep(interval)
st = 'error'
if r.status_code == 200:
try:
st = r.json().get('status', 'error')
except Exception:
pass
if not is_done:
return False
if st == 'done':
break
if st in ['error', 'failed']:
return False
time.sleep(1)
r = self._request("GET", f"/api/report/{sha256}")
if r:
data = r.json().get('data', {})
metadata = data.get('metadata', {})
label = metadata.get('label', 'Unsupport')
score = metadata.get('score', 0)
sims = data.get('similar', [])
r = _req("GET", f"/api/report/{sha256}", req_timeout=30)
if r and r != "timeout" and r.status_code == 200:
try:
data = r.json().get('data', {})
res = data.get('detection', {}).get('results', {}).get('PYAS', {})
label = res.get('label', 'Unsupport')
score = res.get('score', 100)
sims = data.get('similar', [])
is_malicious = 'General' in label
sim_malicious_count = 0
valid_sim_count = 0
for s in sims:
if s.get('similarity', 0) > 80:
valid_sim_count += 1
if "General" in s.get('label', ''):
sim_malicious_count += 1
is_malicious = 'General' in label
sim_malicious_count = 0
valid_sim_count = 0
for s in sims:
if s.get('similarity', 0) > 80:
valid_sim_count += 1
if "General" in s.get('label', ''):
sim_malicious_count += 1
if is_malicious and (valid_sim_count == 0 or sim_malicious_count == valid_sim_count):
return f"General:WinPE/Unknown.{score}!cl"
except Exception:
pass
if is_malicious and (valid_sim_count == 0 or sim_malicious_count == valid_sim_count):
return f"General:WinPE/Unknown.{score}!cl"
except Exception:
pass
return False
+1 -1
View File
@@ -2,7 +2,7 @@ import pyinstaller_versionfile
pyinstaller_versionfile.create_versionfile(
output_file="versionfile.txt",
version='3.4.2',
version='3.4.5',
company_name="PYAS Security",
file_description="Python Antivirus Software",
internal_name="PYAS",
+37 -41
View File
@@ -3,11 +3,7 @@
"\\REGISTRY\\MACHINE\\BCD00000000",
"\\REGISTRY\\MACHINE\\BCD00000000\\*",
"*\\Image File Execution Options\\*",
"\\REGISTRY\\USER\\S-1-*\\SOFTWARE\\NetWire\\*",
"\\REGISTRY\\USER\\S-1-*\\SOFTWARE\\Remcos*\\*",
"\\REGISTRY\\USER\\S-1-*\\SOFTWARE\\DC3_FEXEC\\*",
"*\\Classes\\.exe",
"*\\Classes\\.bat",
"*\\Classes\\.cmd",
@@ -19,7 +15,6 @@
"*\\mouclass",
"*\\kbdclass",
"*\\DefaultIcon",
"*\\DisableAntiSpyware",
"*\\DisableWindowsUpdateAccess",
"*\\EnableLUA",
@@ -79,7 +74,6 @@
"*\\NoInteractiveServices",
"*\\ShutdownWithoutLogon",
"*\\AutoAdminLogon",
"*\\ImagePath",
"*\\BootExecute",
"*\\SubSystems",
"*\\FirmwareBootDevice",
@@ -89,7 +83,6 @@
"*\\DisableAutomaticRestartOnFailure",
"*\\SystemBiosVersion",
"*\\NoTheme",
"*\\PendingFileRenameOperations",
"*\\SystemSetupInProgress",
"*\\CmdLine",
"*\\SetupType",
@@ -108,17 +101,30 @@
"Rule_Registry_TrustedList": [
],
"Rule_Process_TrustedPaths": [
"*\\Windows\\*",
"*\\Windows Defender\\*",
"*\\Windows Defender Advanced Threat Protection\\*",
"*\\Program Files\\*",
"*\\Program Files (x86)\\*",
"\\Device\\HarddiskVolume*\\Windows\\*",
"\\Device\\HarddiskVolume*\\Program Files\\*",
"\\Device\\HarddiskVolume*\\Program Files (x86)\\*",
"\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender\\*",
"\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender Advanced Threat Protection\\*",
"*\\Google\\Chrome\\Application\\chrome.exe",
"*\\Microsoft\\Edge\\Application\\msedge.exe",
"*\\Mozilla Firefox\\firefox.exe",
"*\\Steam\\steam.exe",
"*\\steam\\*\\steam.exe",
"*\\Battle.net\\*\\Battle.net.exe",
"*\\Epic Games\\Launcher\\Portal\\Binaries\\*\\EpicGamesLauncher.exe"
"*\\Epic Games\\Launcher\\Portal\\Binaries\\*\\EpicGamesLauncher.exe",
"*\\ThunderEv.exe",
"*\\ThunderStart.exe",
"*\\resources\\bin\\SDK\\DownloadSDKServer.exe",
"*\\KuGou.exe",
"*\\XLGame.exe",
"*\\XLLiveUD.exe",
"*\\PC4399_WPFLauncher.exe",
"*\\bin\\APlayer.exe",
],
"Rule_Process_ExploitableBlacklist": [
"*\\cmd.exe",
@@ -153,31 +159,24 @@
"*\\taskkill.exe",
"*\\ProcessHacker.exe",
"*\\procmon.exe",
"*\\procexp.exe"
"*\\procexp.exe",
],
"Rule_File_ProtectedPaths": [
"*\\PYAS.exe",
"*\\PYAS_Driver.sys",
"*\\ProgramData\\PYAS\\*.json",
"*\\Plugins\\Rules\\Rules_Driver_P1.json",
"*\\Engine\\Pattern\\*.onnx",
"*\\Engine\\Properties\\*.onnx",
"*\\bootmgr",
"*\\boot.ini",
"*\\BOOTNXT",
"*\\BCD",
"*\\EFI\\*",
"*\\Boot\\*",
"*\\Recovery\\*",
"*\\Windows\\*.exe",
"*\\Windows\\*.dll",
"*\\Windows\\*.sys",
"*\\Windows\\System32\\*.exe",
"*\\Windows\\System32\\*.dll",
"*\\Windows\\System32\\*.sys",
"*\\Windows\\SysWOW64\\*.exe",
"*\\Windows\\SysWOW64\\*.dll",
"*\\Windows\\SysWOW64\\*.sys",
"*\\System Volume Information\\*",
"\\Device\\HarddiskVolume*\\bootmgr",
"\\Device\\HarddiskVolume*\\boot.ini",
"\\Device\\HarddiskVolume*\\BOOTNXT",
"\\Device\\HarddiskVolume*\\EFI\\*",
"\\Device\\HarddiskVolume*\\Boot\\*",
"\\Device\\HarddiskVolume*\\Recovery\\*",
"\\Device\\HarddiskVolume*\\System Volume Information\\*",
"\\Device\\HarddiskVolume*\\Windows\\System32\\config\\*",
"*\\CON",
"*\\CON\\*",
@@ -191,20 +190,19 @@
"*\\COM?\\*",
"*\\LPT?",
"*\\LPT?\\*",
"*\\LPT?",
"*\\LPT?\\*",
"*\\OSDATA",
"*\\OSDATA\\*",
"*\\*<*",
"*\\*>*",
"*\\*:*",
],
"Rule_File_ExceptionPaths": [
"*\\AppData\\*"
"*\\Users\\*\\steam\\*",
"*\\AppData\\*",
"*\\Temp\\*",
"*\\Local\\Temp\\*",
"*\\ventoy\\Boot\\*",
],
"Rule_File_RansomwareExtensions": [
".exe", ".dll", ".sys", ".com", ".scr",
".zip", ".7z", ".rar", ".tar", ".gz",
".js", ".bat", ".cmd", ".ps1", ".vbs",
".ppt", ".pptx", ".wps", ".txt", ".rtf",
@@ -213,7 +211,5 @@
".mp3", ".wav", ".aac", ".ogg", ".flac",
".mp4", ".avi", ".mov", ".wmv", ".mkv",
".aux", ".cur", ".mui", ".ttf", ".efi",
".cpp", ".h", ".c", ".hpp", ".cs", ".java", ".py", ".go", ".rs",
".php", ".html", ".css", ".xml", ".sql", ".db"
]
}