| <!doctype html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8" /> |
| <meta name="viewport" content="width=device-width,initial-scale=1" /> |
| <title>Misinformation Detective β Demo</title> |
|
|
| <style> |
| :root { |
| --primary: #0066cc; |
| --bg: #f9fafc; |
| --card-bg: #fff; |
| --border: #ddd; |
| --text: #222; |
| --muted: #666; |
| } |
| body { |
| margin: 0; |
| font-family: system-ui, sans-serif; |
| background: var(--bg); |
| color: var(--text); |
| line-height: 1.5; |
| } |
| .container { |
| max-width: 800px; |
| margin: 0 auto; |
| padding: 1.5rem; |
| } |
| header { |
| text-align: center; |
| margin-bottom: 1.5rem; |
| } |
| header h1 { |
| margin: 0; |
| font-size: 1.8rem; |
| } |
| header .tagline { |
| color: var(--muted); |
| font-size: 0.95rem; |
| } |
| .card { |
| background: var(--card-bg); |
| border: 1px solid var(--border); |
| border-radius: 6px; |
| padding: 1rem; |
| margin: 1rem 0; |
| box-shadow: 0 2px 4px rgba(0,0,0,0.05); |
| } |
| .card h3 { |
| margin-top: 0; |
| font-size: 1.1rem; |
| border-bottom: 1px solid var(--border); |
| padding-bottom: 0.25rem; |
| } |
| textarea { |
| width: 100%; |
| height: 80px; |
| padding: 0.5rem; |
| font-family: inherit; |
| font-size: 1rem; |
| border-radius: 4px; |
| border: 1px solid var(--border); |
| resize: vertical; |
| } |
| .controls { |
| display: flex; |
| justify-content: space-between; |
| align-items: center; |
| flex-wrap: wrap; |
| margin-top: 0.5rem; |
| } |
| .modes button { |
| margin-right: 0.5rem; |
| } |
| button { |
| cursor: pointer; |
| padding: 0.5rem 0.75rem; |
| border: 1px solid var(--border); |
| border-radius: 4px; |
| background: #f0f0f0; |
| font-size: 0.9rem; |
| } |
| button.primary { |
| background: var(--primary); |
| color: white; |
| border: none; |
| } |
| button.active { |
| background: var(--primary); |
| color: white; |
| } |
| .demo-buttons { |
| margin-top: 0.5rem; |
| } |
| .demo { |
| margin-right: 0.3rem; |
| margin-top: 0.3rem; |
| } |
| footer { |
| margin-top: 2rem; |
| text-align: center; |
| color: var(--muted); |
| font-size: 0.8rem; |
| } |
| pre { |
| white-space: pre-wrap; |
| word-wrap: break-word; |
| font-size: 0.85rem; |
| background: #f7f7f7; |
| padding: 0.5rem; |
| border-radius: 4px; |
| } |
| .loading { |
| text-align: center; |
| padding: 2rem; |
| font-weight: bold; |
| } |
| .error { |
| color: red; |
| font-weight: bold; |
| } |
| ul { |
| padding-left: 1.2rem; |
| } |
| li { |
| margin-bottom: 0.3rem; |
| } |
| </style> |
| </head> |
| <body> |
| <main class="container"> |
| <header> |
| <h1>Misinformation Detective</h1> |
| <p class="tagline">Quick check + deep evidence-based explanation with highlighted comparisons.</p> |
| </header> |
|
|
| <section class="card input-card"> |
| <label for="claim">Paste a claim or headline</label> |
| <textarea id="claim" placeholder="E.g. 'Alien is landed on earth'"></textarea> |
|
|
| <div class="controls"> |
| <div class="modes"> |
| <button id="mode-fast" class="mode active">Fast β‘</button> |
| <button id="mode-deep" class="mode">Deep π</button> |
| <button id="mode-hybrid" class="mode">Hybrid π</button> |
| </div> |
| <div class="actions"> |
| <button id="verify-btn" class="primary">Verify Claim</button> |
| <div class="demo-buttons"> |
| <button class="demo" data-claim="Drinking lemon cures cancer">Health example</button> |
| <button class="demo" data-claim="Scientists confirm coffee extends life by 10 years">Study example</button> |
| <button class="demo" data-claim="Alien is landed on earth">UFO example</button> |
| </div> |
| </div> |
| </div> |
| </section> |
|
|
| <section id="pipeline" class="pipeline"> |
| |
| </section> |
|
|
| <footer> |
| <small>Designed for hackathon demo β resilient, educational, and transparent pipeline.</small> |
| </footer> |
| </main> |
|
|
| <script> |
| const claimInput = document.getElementById("claim"); |
| const verifyBtn = document.getElementById("verify-btn"); |
| const pipeline = document.getElementById("pipeline"); |
| let mode = "fast"; |
| |
| |
| document.querySelectorAll(".mode").forEach(btn => { |
| btn.addEventListener("click", () => { |
| document.querySelectorAll(".mode").forEach(b => b.classList.remove("active")); |
| btn.classList.add("active"); |
| mode = btn.id.replace("mode-",""); |
| }); |
| }); |
| |
| |
| document.querySelectorAll(".demo").forEach(btn => { |
| btn.addEventListener("click", () => { |
| claimInput.value = btn.dataset.claim; |
| }); |
| }); |
| |
| function addCard(title, content) { |
| const card = document.createElement("section"); |
| card.className = "card"; |
| card.innerHTML = `<h3>${title}</h3><div>${content}</div>`; |
| pipeline.appendChild(card); |
| } |
| |
| function renderComparison(list) { |
| if (!list || !list.length) return "<em>No comparisons available</em>"; |
| return "<ul>" + list.map(c => |
| `<li><strong>${c.claim_span}</strong> β <q>${c.evidence_span}</q> <em>[${c.relation}]</em></li>` |
| ).join("") + "</ul>"; |
| } |
| |
| verifyBtn.addEventListener("click", async () => { |
| const text = claimInput.value.trim(); |
| if (!text) return alert("Please enter a claim."); |
| pipeline.innerHTML = "<p class='loading'>Checking claim...</p>"; |
| |
| try { |
| |
| const res = await fetch("/api/predict/", { |
| method: "POST", |
| headers: {"Content-Type":"application/json"}, |
| body: JSON.stringify({data: [text, mode]}) |
| }); |
| const json = await res.json(); |
| const data = json.data[0]; |
| |
| pipeline.innerHTML = ""; |
| |
| addCard("Step 1 β Classification", `<p>Type: <b>${data["Text type"]}</b></p>`); |
| addCard("Step 2 β Summary", `<p>${data["User summary"]}</p>`); |
| addCard("Step 3 β Search Results", `<pre>${data["Evidence summary"]}</pre>`); |
| addCard("Step 4 β Evidence Filtered", `<p>Found ${data["Evidence count filtered"]} credible sources</p>`); |
| addCard("Step 5 β Fast Label", `<p>${data["Fast classification"]}</p>`); |
| addCard("Step 6 β Similarity Score", `<p>${data.similarity || "N/A"}</p>`); |
| |
| if (data["Deep result"] && data["Deep result"] !== "N/A") { |
| const deep = data["Deep result"]; |
| addCard("Step 7 β Deep AI Verdict", |
| `<p><b>Outcome:</b> ${deep.outcome}</p> |
| <p>${deep.explanation}</p> |
| <h4>Comparison</h4>${renderComparison(deep.comparison)} |
| <h4>Takeaways</h4><ul>${deep.takeaways.map(t=>`<li>${t}</li>`).join("")}</ul> |
| <p><i>Tip:</i> ${deep.tip || ""}</p>`); |
| } |
| |
| addCard("Step 8 β Credibility Score", |
| `<p>Score: <b style="color:${data["Credibility"].color}">${data["Credibility"].score}</b>/100</p>`); |
| |
| } catch (err) { |
| console.error(err); |
| pipeline.innerHTML = "<p class='error'>Error verifying claim.</p>"; |
| } |
| }); |
| </script> |
|
|
| </body> |
| </html> |
|
|