SIMON Master Console Rebuild
True command center for SIMON + WEB360
This rebuild gives you a cleaner production spine: interactive tree, live viewer, guarded editor, dynamic graphics, architecture map, and note storage. It is designed to sit beside your existing
console.php
and become the stronger replacement path.
Dashboard
Tree
Viewer
System Map
File Registry
Notes
Files
15,338
Folders
408
Scanned Size
3.84 GB
PHP Files
890
Editable Text Files
12,599
File viewer
guarded to /htdocs
/sitelogs/telemetry.php
(() => { // ===== SIMON Telemetry Core (first-party) ===== const SID_KEY = "simon_sid"; const sid = localStorage.getItem(SID_KEY) || (crypto.randomUUID ? crypto.randomUUID() : (String(Date.now()) + "-" + Math.random())); localStorage.setItem(SID_KEY, sid); const startTs = Date.now(); let maxScroll = 0; let scrollBuckets = { "0":0, "25":0, "50":0, "75":0, "90":0, "100":0 }; let lastScrollMark = 0; // Rage-click detection let clickTimes = []; function isRageClick() { const t = Date.now(); clickTimes = clickTimes.filter(x => t - x < 1200); clickTimes.push(t); return clickTimes.length >= 4; } function payloadBase() { return { v: 1, sid, ts: Date.now(), url: location.pathname + location.search, ref: document.referrer || "", title: document.title || "", vp: { w: window.innerWidth || 0, h: window.innerHeight || 0 }, tz: Intl.DateTimeFormat().resolvedOptions().timeZone || "" }; } function send(type, data = {}) { const body = JSON.stringify({ ...payloadBase(), type, data }); try { if (navigator.sendBeacon) { navigator.sendBeacon("/api/track.php", body); return; } } catch (e) {} fetch("/api/track.php", { method: "POST", headers: { "Content-Type": "application/json" }, body, keepalive: true }).catch(() => {}); } // Pageview send("pageview", { lang: navigator.language || "", uaHint: /mobile|iphone|android/i.test(navigator.userAgent) ? "mobile" : "desktop" }); // Scroll depth function computeScrollPct() { const doc = document.documentElement; const scrollTop = window.scrollY || doc.scrollTop || 0; const scrollHeight = (doc.scrollHeight || 0) - (window.innerHeight || 0); const pct = scrollHeight > 0 ? Math.min(100, Math.round((scrollTop / scrollHeight) * 100)) : 100; return pct; } window.addEventListener("scroll", () => { // throttle bucket updates const now = Date.now(); if (now - lastScrollMark < 250) return; lastScrollMark = now; const pct = computeScrollPct(); if (pct > maxScroll) maxScroll = pct; // bucket if (pct >= 100) scrollBuckets["100"]++; else if (pct >= 90) scrollBuckets["90"]++; else if (pct >= 75) scrollBuckets["75"]++; else if (pct >= 50) scrollBuckets["50"]++; else if (pct >= 25) scrollBuckets["25"]++; else scrollBuckets["0"]++; }, { passive: true }); // Clicks + heatmap coords document.addEventListener("click", (e) => { const el = e.target.closest("a,button,input,textarea,select,label,summary,[role='button']"); const tag = el ? el.tagName.toLowerCase() : (e.target && e.target.tagName ? e.target.tagName.toLowerCase() : "unknown"); const rect = document.documentElement.getBoundingClientRect(); const x = Math.max(0, Math.round(((e.clientX || 0) / (window.innerWidth || 1)) * 1000)) / 1000; const y = Math.max(0, Math.round(((e.clientY || 0) / (window.innerHeight || 1)) * 1000)) / 1000; const href = el && el.getAttribute ? el.getAttribute("href") : ""; const text = el ? ((el.innerText || el.value || "").trim().slice(0, 120)) : ""; const rage = isRageClick(); send(rage ? "rage_click" : "click", { tag, id: el && el.id ? el.id : "", cls: el && el.className ? String(el.className).slice(0, 200) : "", text, href: href ? String(href).slice(0, 600) : "", heat: { x, y } }); // outbound clicks if (href && /^https?:\/\//i.test(href) && !href.includes(location.host)) { send("outbound", { href: String(href).slice(0, 800) }); } }, { capture: true }); // Form submits document.addEventListener("submit", (e) => { const form = e.target; if (!form) return; send("form_submit", { id: form.id || "", action: (form.getAttribute("action") || "").slice(0, 500), method: (form.getAttribute("method") || "get").toLowerCase() }); }, { capture: true }); // Page duration on unload window.addEventListener("beforeunload", () => { send("duration", { ms: Date.now() - startTs, scrollMax: maxScroll, scrollBuckets }); }); })();
Save file
Quick jump
open a path
Open