Verify historical claims about World War II with AI-powered fact checking
Size
16.2 KB
Version
1.0.1
Created
Oct 27, 2025
Updated
18 days ago
1// ==UserScript==
2// @name World War II Fact Checker
3// @description Verify historical claims about World War II with AI-powered fact checking
4// @version 1.0.1
5// @match https://*.yandex.com/*
6// @icon https://yandex.com/search/_crpd/Xp7NZu105/03bb5aA9eNXL/_8PkmayKPdo-eDTumjMjmbCL3s0as4-ZC3Bboh1zxLzPSxGANDh5HavNSGbDJwD3S0m4ZU_c2AOYSh7EWCkQv41zpT3c27gqf2nFvvojUynmOR2fGdDtXtoW2FXYEuUcnloFVPQY-q7A
7// ==/UserScript==
8(function() {
9 'use strict';
10
11 console.log('World War II Fact Checker initialized');
12
13 // Debounce function to avoid excessive calls
14 function debounce(func, wait) {
15 let timeout;
16 return function executedFunction(...args) {
17 const later = () => {
18 clearTimeout(timeout);
19 func(...args);
20 };
21 clearTimeout(timeout);
22 timeout = setTimeout(later, wait);
23 };
24 }
25
26 // Create the fact checker UI
27 function createFactCheckerUI() {
28 // Check if UI already exists
29 if (document.getElementById('ww2-fact-checker')) {
30 return;
31 }
32
33 const container = document.createElement('div');
34 container.id = 'ww2-fact-checker';
35 container.innerHTML = `
36 <div id="ww2-checker-header">
37 <span>🔍 WWII Fact Checker</span>
38 <button id="ww2-checker-toggle">−</button>
39 </div>
40 <div id="ww2-checker-content">
41 <textarea id="ww2-claim-input" placeholder="Enter a World War II claim to fact-check..."></textarea>
42 <button id="ww2-check-button">Check Fact</button>
43 <div id="ww2-result-container"></div>
44 </div>
45 `;
46
47 document.body.appendChild(container);
48 console.log('Fact checker UI created');
49
50 // Add event listeners
51 setupEventListeners();
52 }
53
54 // Setup event listeners
55 function setupEventListeners() {
56 const toggleBtn = document.getElementById('ww2-checker-toggle');
57 const content = document.getElementById('ww2-checker-content');
58 const checkBtn = document.getElementById('ww2-check-button');
59 const input = document.getElementById('ww2-claim-input');
60
61 // Toggle panel
62 toggleBtn.addEventListener('click', () => {
63 const isCollapsed = content.style.display === 'none';
64 content.style.display = isCollapsed ? 'block' : 'none';
65 toggleBtn.textContent = isCollapsed ? '−' : '+';
66 });
67
68 // Check fact button
69 checkBtn.addEventListener('click', () => {
70 const claim = input.value.trim();
71 if (claim) {
72 checkFact(claim);
73 }
74 });
75
76 // Also check on Enter key
77 input.addEventListener('keypress', (e) => {
78 if (e.key === 'Enter' && !e.shiftKey) {
79 e.preventDefault();
80 const claim = input.value.trim();
81 if (claim) {
82 checkFact(claim);
83 }
84 }
85 });
86
87 // Add context menu for selected text
88 document.addEventListener('mouseup', debounce(handleTextSelection, 300));
89 }
90
91 // Handle text selection for quick fact checking
92 function handleTextSelection() {
93 const selection = window.getSelection();
94 const selectedText = selection.toString().trim();
95
96 // Remove existing quick check button
97 const existingBtn = document.getElementById('ww2-quick-check-btn');
98 if (existingBtn) {
99 existingBtn.remove();
100 }
101
102 if (selectedText.length > 10 && selectedText.length < 500) {
103 const range = selection.getRangeAt(0);
104 const rect = range.getBoundingClientRect();
105
106 const quickBtn = document.createElement('button');
107 quickBtn.id = 'ww2-quick-check-btn';
108 quickBtn.textContent = '✓ Check WWII Fact';
109 quickBtn.style.cssText = `
110 position: fixed;
111 left: ${rect.left + window.scrollX}px;
112 top: ${rect.bottom + window.scrollY + 5}px;
113 z-index: 10002;
114 background: #1a73e8;
115 color: white;
116 border: none;
117 padding: 8px 12px;
118 border-radius: 4px;
119 cursor: pointer;
120 font-size: 13px;
121 font-weight: 500;
122 box-shadow: 0 2px 8px rgba(0,0,0,0.2);
123 `;
124
125 quickBtn.addEventListener('click', () => {
126 document.getElementById('ww2-claim-input').value = selectedText;
127 checkFact(selectedText);
128 quickBtn.remove();
129 });
130
131 document.body.appendChild(quickBtn);
132
133 // Remove button after 5 seconds
134 setTimeout(() => {
135 if (quickBtn.parentNode) {
136 quickBtn.remove();
137 }
138 }, 5000);
139 }
140 }
141
142 // Check the fact using AI
143 async function checkFact(claim) {
144 const resultContainer = document.getElementById('ww2-result-container');
145 const checkBtn = document.getElementById('ww2-check-button');
146
147 // Show loading state
148 checkBtn.disabled = true;
149 checkBtn.textContent = 'Checking...';
150 resultContainer.innerHTML = '<div class="ww2-loading">🔍 Analyzing claim...</div>';
151
152 try {
153 console.log('Checking WWII claim:', claim);
154
155 const result = await RM.aiCall(
156 `You are a World War II historian and fact checker. Analyze the following claim about World War II and provide a detailed fact check. Consider historical accuracy, context, and common misconceptions.
157
158Claim: "${claim}"
159
160Provide a thorough analysis including the verdict, explanation, historical context, and sources if applicable.`,
161 {
162 type: "json_schema",
163 json_schema: {
164 name: "ww2_fact_check",
165 schema: {
166 type: "object",
167 properties: {
168 verdict: {
169 type: "string",
170 enum: ["TRUE", "MOSTLY_TRUE", "PARTIALLY_TRUE", "MISLEADING", "FALSE", "UNVERIFIABLE"]
171 },
172 confidence: {
173 type: "string",
174 enum: ["HIGH", "MEDIUM", "LOW"]
175 },
176 summary: {
177 type: "string"
178 },
179 explanation: {
180 type: "string"
181 },
182 historicalContext: {
183 type: "string"
184 },
185 corrections: {
186 type: "array",
187 items: { type: "string" }
188 },
189 relatedFacts: {
190 type: "array",
191 items: { type: "string" }
192 }
193 },
194 required: ["verdict", "confidence", "summary", "explanation"]
195 }
196 }
197 }
198 );
199
200 console.log('Fact check result:', result);
201 displayResult(result, claim);
202
203 // Cache the result
204 const cacheKey = 'ww2_fact_' + btoa(claim).slice(0, 30);
205 await GM.setValue(cacheKey, JSON.stringify({
206 claim: claim,
207 result: result,
208 timestamp: Date.now()
209 }));
210
211 } catch (error) {
212 console.error('Fact check failed:', error);
213 resultContainer.innerHTML = `
214 <div class="ww2-error">
215 ❌ Error checking fact. Please try again.
216 <div style="font-size: 12px; margin-top: 5px; opacity: 0.8;">${error.message}</div>
217 </div>
218 `;
219 } finally {
220 checkBtn.disabled = false;
221 checkBtn.textContent = 'Check Fact';
222 }
223 }
224
225 // Display the fact check result
226 function displayResult(result, claim) {
227 const resultContainer = document.getElementById('ww2-result-container');
228
229 const verdictColors = {
230 'TRUE': '#0f9d58',
231 'MOSTLY_TRUE': '#5bb974',
232 'PARTIALLY_TRUE': '#f9ab00',
233 'MISLEADING': '#ff9800',
234 'FALSE': '#db4437',
235 'UNVERIFIABLE': '#9e9e9e'
236 };
237
238 const verdictIcons = {
239 'TRUE': '✓',
240 'MOSTLY_TRUE': '✓',
241 'PARTIALLY_TRUE': '⚠',
242 'MISLEADING': '⚠',
243 'FALSE': '✗',
244 'UNVERIFIABLE': '?'
245 };
246
247 const color = verdictColors[result.verdict] || '#9e9e9e';
248 const icon = verdictIcons[result.verdict] || '?';
249
250 let html = `
251 <div class="ww2-result">
252 <div class="ww2-verdict" style="background-color: ${color};">
253 <span class="ww2-verdict-icon">${icon}</span>
254 <span class="ww2-verdict-text">${result.verdict.replace(/_/g, ' ')}</span>
255 <span class="ww2-confidence">(${result.confidence} confidence)</span>
256 </div>
257
258 <div class="ww2-summary">
259 <strong>Summary:</strong> ${result.summary}
260 </div>
261
262 <div class="ww2-explanation">
263 <strong>Explanation:</strong>
264 <p>${result.explanation}</p>
265 </div>
266 `;
267
268 if (result.historicalContext) {
269 html += `
270 <div class="ww2-context">
271 <strong>Historical Context:</strong>
272 <p>${result.historicalContext}</p>
273 </div>
274 `;
275 }
276
277 if (result.corrections && result.corrections.length > 0) {
278 html += `
279 <div class="ww2-corrections">
280 <strong>Corrections:</strong>
281 <ul>
282 ${result.corrections.map(c => `<li>${c}</li>`).join('')}
283 </ul>
284 </div>
285 `;
286 }
287
288 if (result.relatedFacts && result.relatedFacts.length > 0) {
289 html += `
290 <div class="ww2-related">
291 <strong>Related Facts:</strong>
292 <ul>
293 ${result.relatedFacts.map(f => `<li>${f}</li>`).join('')}
294 </ul>
295 </div>
296 `;
297 }
298
299 html += '</div>';
300 resultContainer.innerHTML = html;
301 }
302
303 // Add styles
304 function addStyles() {
305 TM_addStyle(`
306 #ww2-fact-checker {
307 position: fixed;
308 bottom: 20px;
309 right: 20px;
310 width: 400px;
311 max-width: 90vw;
312 background: white;
313 border: 2px solid #1a73e8;
314 border-radius: 8px;
315 box-shadow: 0 4px 16px rgba(0,0,0,0.2);
316 z-index: 10000;
317 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
318 }
319
320 #ww2-checker-header {
321 background: #1a73e8;
322 color: white;
323 padding: 12px 16px;
324 font-weight: 600;
325 font-size: 15px;
326 display: flex;
327 justify-content: space-between;
328 align-items: center;
329 border-radius: 6px 6px 0 0;
330 cursor: move;
331 }
332
333 #ww2-checker-toggle {
334 background: rgba(255,255,255,0.2);
335 color: white;
336 border: none;
337 width: 24px;
338 height: 24px;
339 border-radius: 4px;
340 cursor: pointer;
341 font-size: 18px;
342 line-height: 1;
343 padding: 0;
344 }
345
346 #ww2-checker-toggle:hover {
347 background: rgba(255,255,255,0.3);
348 }
349
350 #ww2-checker-content {
351 padding: 16px;
352 max-height: 600px;
353 overflow-y: auto;
354 }
355
356 #ww2-claim-input {
357 width: 100%;
358 min-height: 80px;
359 padding: 10px;
360 border: 2px solid #e0e0e0;
361 border-radius: 4px;
362 font-size: 14px;
363 font-family: inherit;
364 resize: vertical;
365 box-sizing: border-box;
366 }
367
368 #ww2-claim-input:focus {
369 outline: none;
370 border-color: #1a73e8;
371 }
372
373 #ww2-check-button {
374 width: 100%;
375 margin-top: 12px;
376 padding: 12px;
377 background: #1a73e8;
378 color: white;
379 border: none;
380 border-radius: 4px;
381 font-size: 14px;
382 font-weight: 600;
383 cursor: pointer;
384 transition: background 0.2s;
385 }
386
387 #ww2-check-button:hover:not(:disabled) {
388 background: #1557b0;
389 }
390
391 #ww2-check-button:disabled {
392 background: #9e9e9e;
393 cursor: not-allowed;
394 }
395
396 #ww2-result-container {
397 margin-top: 16px;
398 }
399
400 .ww2-loading {
401 text-align: center;
402 padding: 20px;
403 color: #666;
404 font-size: 14px;
405 }
406
407 .ww2-error {
408 background: #ffebee;
409 color: #c62828;
410 padding: 12px;
411 border-radius: 4px;
412 font-size: 14px;
413 }
414
415 .ww2-result {
416 background: #f8f9fa;
417 border-radius: 4px;
418 overflow: hidden;
419 }
420
421 .ww2-verdict {
422 color: white;
423 padding: 12px 16px;
424 font-weight: 600;
425 font-size: 16px;
426 display: flex;
427 align-items: center;
428 gap: 8px;
429 }
430
431 .ww2-verdict-icon {
432 font-size: 20px;
433 }
434
435 .ww2-confidence {
436 margin-left: auto;
437 font-size: 12px;
438 opacity: 0.9;
439 }
440
441 .ww2-summary,
442 .ww2-explanation,
443 .ww2-context,
444 .ww2-corrections,
445 .ww2-related {
446 padding: 12px 16px;
447 border-top: 1px solid #e0e0e0;
448 font-size: 14px;
449 line-height: 1.6;
450 }
451
452 .ww2-summary strong,
453 .ww2-explanation strong,
454 .ww2-context strong,
455 .ww2-corrections strong,
456 .ww2-related strong {
457 display: block;
458 margin-bottom: 6px;
459 color: #1a73e8;
460 font-size: 13px;
461 text-transform: uppercase;
462 letter-spacing: 0.5px;
463 }
464
465 .ww2-explanation p,
466 .ww2-context p {
467 margin: 0;
468 color: #333;
469 }
470
471 .ww2-corrections ul,
472 .ww2-related ul {
473 margin: 0;
474 padding-left: 20px;
475 color: #333;
476 }
477
478 .ww2-corrections li,
479 .ww2-related li {
480 margin-bottom: 6px;
481 }
482
483 #ww2-quick-check-btn:hover {
484 background: #1557b0 !important;
485 }
486 `);
487 }
488
489 // Initialize the extension
490 function init() {
491 console.log('Initializing World War II Fact Checker');
492 addStyles();
493
494 // Wait for body to be ready
495 if (document.body) {
496 createFactCheckerUI();
497 } else {
498 TM_runBody(() => {
499 createFactCheckerUI();
500 });
501 }
502 }
503
504 // Start the extension
505 init();
506})();