Drag OCR → send to SambaNova API → show answer in floating panel (even if OCR empty)
// ==UserScript== // @name Best School Cheat // @namespace http://tampermonkey.net/ // @version V12 // @description Drag OCR → send to SambaNova API → show answer in floating panel (even if OCR empty) // @match *://*/* // @grant GM_setClipboard // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/html2canvas.min.js // @require https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js // ==/UserScript== /* 🔑 YOUR SAMBANOVA API KEY — paste it here */ const SN_API_KEY = "24ae777f-31a3-43ba-85a0-e10a7469581b"; /* 🌐 SambaNova API endpoint */ const SN_URL = "https://api.sambanova.ai/v1/chat/completions"; (function () { let armed = false; let startX, startY, box; let zoomLevel = 2; let promptType = "solve"; /* ---------- BUTTON ---------- */ function makeBtn(txt){ let b = document.createElement("button"); b.textContent = txt; Object.assign(b.style,{ padding:"6px 8px", background:"#007bff", color:"#fff", border:"none", borderRadius:"6px", cursor:"pointer", fontSize:"12px" }); return b; } /* ---------- COLLAPSE REOPEN BUTTON ---------- */ const reopenBtn = makeBtn("+"); Object.assign(reopenBtn.style,{ position:"fixed", bottom:"20px", right:"20px", zIndex:999999, display:"none" }); document.body.appendChild(reopenBtn); /* ---------- CONTROL BAR ---------- */ const bar = document.createElement("div"); Object.assign(bar.style,{ position:"fixed", bottom:"20px", right:"20px", zIndex:999998, padding:"8px", background:"rgba(20,20,20,0.9)", borderRadius:"8px", display:"flex", gap:"6px", alignItems:"center", color:"#fff", fontFamily:"system-ui, sans-serif", fontSize:"12px" }); /* OCR BUTTON */ const ocrBtn = makeBtn("OCR-Drag"); ocrBtn.onclick = () => { armed = !armed; ocrBtn.style.background = armed ? "#28a745" : "#007bff"; }; bar.appendChild(ocrBtn); /* PROMPT SELECT */ const select = document.createElement("select"); ["solve","explain","summarize"].forEach(v=>{ let o = document.createElement("option"); o.value = v; o.textContent = v; select.appendChild(o); }); select.onchange = () => promptType = select.value; bar.appendChild(select); /* ZOOM CONTROLS */ const zoomMinus = makeBtn("−"); const zoomPlus = makeBtn("+"); const zoomLabel = document.createElement("span"); function updateZoom(){ zoomLabel.textContent = `Zoom:${zoomLevel}x`; } updateZoom(); zoomPlus.onclick = () => { zoomLevel = Math.min(5, zoomLevel + 0.5); updateZoom(); }; /* ---------- FULL COLLAPSE ---------- */ zoomMinus.onclick = () => { bar.style.display = "none"; panel.style.display = "none"; reopenBtn.style.display = "block"; }; reopenBtn.onclick = () => { bar.style.display = "flex"; reopenBtn.style.display = "none"; }; bar.append(zoomMinus, zoomLabel, zoomPlus); document.body.appendChild(bar); /* ---------- ANSWER PANEL ---------- */ const panel = document.createElement("div"); Object.assign(panel.style,{ position:"fixed", bottom:"70px", right:"20px", width:"360px", maxHeight:"60vh", background:"#111", color:"#eee", borderRadius:"10px", padding:"12px", display:"none", zIndex:999997, fontFamily:"system-ui, sans-serif", fontSize:"12px", overflow:"auto", boxShadow:"0 2px 10px rgba(0,0,0,0.5)" }); const body = document.createElement("div"); body.style.whiteSpace = "pre-wrap"; panel.appendChild(body); document.body.appendChild(panel); function showPanel(text){ body.textContent = text; panel.style.display = "block"; } /* ---------- SCREENSHOT (lab() color fix) ---------- */ async function screenshot(rect){ return await html2canvas(document.body,{ x:rect.left, y:rect.top, width:rect.width, height:rect.height, scale:zoomLevel, onclone:(doc)=>{ doc.querySelectorAll("[style*='lab(']").forEach(el=>{ el.style.cssText = el.style.cssText.replace(/lab\([^)]*\)/g,"rgb(0,0,0)"); }); } }); } /* ---------- PROMPT BUILDER ---------- */ function buildPrompt(text){ if(promptType === "explain") return `Explain this clearly:\n\n${text}`; if(promptType === "summarize") return `Summarize this:\n\n${text}`; return `Solve this step-by-step:\n\n${text}`; } /* ---------- SAMBANOVA CALL ---------- */ async function askSambaNova(text){ const prompt = buildPrompt(text); const res = await fetch(SN_URL, { method: "POST", headers: { "Authorization": "Bearer " + SN_API_KEY, "Content-Type": "application/json" }, body: JSON.stringify({ stream: false, model: "ALLaM-7B-Instruct-preview", messages: [ { role: "system", content: "You are a helpful assistant" }, { role: "user", content: prompt } ] }) }); const data = await res.json(); const answer = data?.choices?.[0]?.message?.content || "[No answer returned]"; return { prompt, answer }; } /* ---------- DRAG ---------- */ document.addEventListener("mousedown", e => { if(!armed) return; startX = e.clientX; startY = e.clientY; box = document.createElement("div"); Object.assign(box.style,{ position:"fixed", border:"2px dashed red", background:"rgba(255,0,0,0.15)", left:startX+"px", top:startY+"px", zIndex:999996 }); document.body.appendChild(box); }); document.addEventListener("mousemove", e => { if(!armed || !box) return; let w = e.clientX - startX; let h = e.clientY - startY; box.style.width = Math.abs(w) + "px"; box.style.height = Math.abs(h) + "px"; box.style.left = (w < 0 ? e.clientX : startX) + "px"; box.style.top = (h < 0 ? e.clientY : startY) + "px"; }); document.addEventListener("mouseup", async () => { if(!armed || !box) return; const rect = box.getBoundingClientRect(); box.remove(); box = null; armed = false; ocrBtn.style.background = "#007bff"; try{ /* ---------- OCR ---------- */ const canvas = await screenshot(rect); const img = canvas.toDataURL("image/png"); const result = await Tesseract.recognize(img,"eng",{logger:()=>{}}); let text = (result.data.text || "").trim(); if(!text){ text = "[No OCR text found – sending anyway]"; } showPanel( `⏳ OCR done. Sending to SambaNova... --- OCR TEXT --- ${text}` ); /* ---------- SAMBANOVA ---------- */ const { prompt, answer } = await askSambaNova(text); GM_setClipboard(prompt); showPanel( `✅ OCR Copied ✅ Prompt Copied ✅ SambaNova Answer Received --- OCR TEXT --- ${text} --- PROMPT SENT TO SAMBANOVA --- ${prompt} --- SAMBANOVA ANSWER --- ${answer}` ); } catch(err){ showPanel("[ERROR] " + String(err)); } }); })();