| import argv |
| import gleam/io |
| import gleam/http/response |
| import gleam/http/request.{type Request} |
| import mist.{type ResponseData} |
| import flashsync_native |
| import gleam/bytes_tree |
| import gleam/list |
| import gleam/float |
| import gleam/int |
| import gleam/option |
| import gleam/string |
| import sm2_algorithm |
| import ai_tutor |
| import neural_heatmap |
| import ocr_service |
| import multiplayer |
| import biometric_tracker |
| import time_travel |
| import exam_generator |
| import ghost_writing |
|
|
| const app_version = "2.7.0" |
|
|
| pub fn main() { |
| flashsync_native.load() |
| case argv.load().arguments { |
| ["serve"] -> { |
| let port = 8080 |
| io.println("FlashSync Learning Platform Online | http://0.0.0.0:" <> int.to_string(port)) |
| io.println("Features Loaded:") |
| io.println(" - AI Tutor with File Upload") |
| io.println(" - PDF Export & Print Mode") |
| io.println(" - Spaced Repetition (SM-2)") |
| io.println(" - Neural Knowledge Heatmap") |
| io.println(" - Practice Question Generator") |
| io.println(" - Mock Exams with Grading") |
| io.println(" - Biometric Focus Tracking") |
| io.println(" - Time-Travel Learning Timeline") |
| io.println(" - Drawing & Ghost Writing Mode") |
| io.println(" - 8 Language Support") |
| io.println(" - Subscription Plans") |
| io.println(" - File Storage & Preview") |
| io.println(" - Command Center Intelligence") |
| io.println("FlashSync Version: " <> app_version) |
| let assert Ok(_) = mist.new(handle_request) |> mist.bind("0.0.0.0") |> mist.port(port) |> mist.start |
| process.sleep_forever() |
| } |
| _ -> io.println("Usage: flashsync serve") |
| } |
| } |
|
|
| fn handle_request(req: Request(mist.Connection)) -> response.Response(ResponseData) { |
| let path = request.path_segments(req) |
| |
| case path { |
| // Core Card Operations |
| ["api", "save", id, body] -> { |
| let _ = flashsync_native.save_card(id, body) |
| json_response("{\"status\": \"saved\", \"id\": \"" <> id <> "\"}") |
| } |
| ["api", "card", id] -> { |
| let card_data = flashsync_native.get_card(id) |
| json_response(card_data) |
| } |
| ["api", "create_card", id, question, answer] -> { |
| let _ = flashsync_native.save_card(id, question <> "|||" <> answer) |
| json_response("{\"status\": \"created\", \"id\": \"" <> id <> "\"}") |
| } |
| |
| // SM-2 Spaced Repetition |
| ["api", "review", _id, grade] -> { |
| let grade_val = case grade { |
| "0" -> sm2_algorithm.Incorrect |
| "1" -> sm2_algorithm.Difficult |
| "2" -> sm2_algorithm.Complete |
| "3" -> sm2_algorithm.Acceptable |
| "4" -> sm2_algorithm.Easy |
| _ -> sm2_algorithm.Perfect |
| } |
| let initial = sm2_algorithm.initial_state() |
| let updated = sm2_algorithm.calculate_next_review(initial, grade_val) |
| let response_text = "{\"next_review\": \"" <> updated.next_review_date <> "\", \"mastery\": " <> float.to_string(sm2_algorithm.calculate_mastery_percentage(updated)) <> "}" |
| json_response(response_text) |
| } |
| |
| // AI Tutor |
| ["api", "tutor", "ask"] -> { |
| let response_msg = ai_tutor.get_comprehensive_welcome("Student") |
| json_response("{\"response\": \"" <> response_msg <> "\"}") |
| } |
| ["api", "tutor", "analyze_file"] -> { |
| json_response("{\"status\": \"ready\", \"message\": \"Upload a PDF, image, or document for AI analysis\"}") |
| } |
| |
| // Neural Heatmap |
| ["api", "heatmap"] -> { |
| let cards = [ |
| #("card_1", "Quantum Mechanics", 85.0), |
| #("card_2", "Linear Algebra", 72.0), |
| #("card_3", "Thermodynamics", 63.0), |
| #("card_4", "Organic Chemistry", 91.0), |
| #("card_5", "Differential Equations", 45.0), |
| ] |
| let map = neural_heatmap.build_constellation(cards) |
| let svg = neural_heatmap.generate_svg_constellation(map) |
| let analytics = neural_heatmap.calculate_heatmap_analytics(map) |
| json_response("{\"svg\": \"" <> svg <> "\", \"analytics\": \"" <> analytics <> "\"}") |
| } |
| |
| // OCR |
| ["api", "ocr", "process"] -> { |
| let ocr_result = ocr_service.OcrSuccess( |
| text: "Successfully extracted handwritten text from sketch", |
| confidence: 0.92, |
| metadata: ocr_service.OcrMetadata( |
| language: "en", |
| character_count: 45, |
| word_count: 8, |
| confidence_per_line: [0.95, 0.90, 0.89], |
| ), |
| ) |
| let formatted = ocr_service.format_ocr_output(ocr_result) |
| json_response("{\"result\": \"" <> formatted <> "\"}") |
| } |
| |
| // Multiplayer |
| ["api", "multiplayer", "create"] -> { |
| let _session = multiplayer.create_session("room_2026_03", "Advanced Biology Study") |
| json_response("{\"room_id\": \"room_2026_03\", \"name\": \"Advanced Biology Study\"}") |
| } |
| ["api", "multiplayer", "join"] -> { |
| let session = multiplayer.create_session("room_2026_03", "Advanced Biology Study") |
| let with_user = multiplayer.add_participant(session, "usr_001", "Alice") |
| let svg_space = multiplayer.generate_svg_focus_space(with_user) |
| json_response("{\"participants\": 1, \"focus_space\": \"" <> svg_space <> "\"}") |
| } |
| |
| // Biometric |
| ["api", "biometric", "track"] -> { |
| let data = biometric_tracker.BiometricData( |
| timestamp: 1710841800, |
| eye_gaze_x: 400.0, |
| eye_gaze_y: 300.0, |
| head_posture: biometric_tracker.Upright, |
| blink_rate: 18.0, |
| pupil_size: 5.2, |
| attention_score: 0.88, |
| is_user_present: True, |
| ) |
| let metrics = biometric_tracker.monitor_focus_stream(data, option.None) |
| let music = biometric_tracker.get_neural_audio_instruction(metrics) |
| json_response("{\"focus_score\": " <> float.to_string(metrics.current_focus_score) <> ", \"music\": \"" <> music <> "\"}") |
| } |
| |
| // Time-Travel |
| ["api", "timetravel", "snapshots"] -> { |
| let snapshots = [ |
| time_travel.KnowledgeSnapshot( |
| timestamp: "2026-02-15T00:00:00Z", |
| card_id: "card_1", |
| question: "What is quantum superposition?", |
| answer: "A quantum system existing in multiple states...", |
| mastery_level: 45.0, |
| is_mastered: False, |
| ), |
| time_travel.KnowledgeSnapshot( |
| timestamp: "2026-03-19T00:00:00Z", |
| card_id: "card_1", |
| question: "What is quantum superposition?", |
| answer: "A quantum system existing in multiple states...", |
| mastery_level: 85.0, |
| is_mastered: True, |
| ), |
| ] |
| let timelapse = time_travel.build_timelapse(snapshots) |
| let viz = time_travel.generate_growth_visualization(timelapse) |
| json_response("{\"visualization\": \"" <> viz <> "\", \"growth\": " <> float.to_string(timelapse.total_growth) <> "}") |
| } |
| |
| // Exam |
| ["api", "exam", "generate"] -> { |
| let cards = [ |
| #("card_1", "Define photosynthesis", "Process by which plants convert light to chemical energy"), |
| #("card_2", "What is ATP?", "Adenosine triphosphate, cellular energy molecule"), |
| #("card_3", "Explain mitochondria function", "Powerhouse of the cell, produces ATP"), |
| ] |
| let exam = exam_generator.generate_mock_exam("Biology 101", cards, 5, "medium") |
| let _pdf = exam_generator.generate_pdf_exam(exam) |
| json_response("{\"exam_id\": \"" <> exam.exam_id <> "\", \"questions\": " <> int.to_string(list.length(exam.questions)) <> ", \"duration\": " <> int.to_string(exam.duration_minutes) <> "}") |
| } |
| |
| // Ghost Writing |
| ["api", "ghost_writing", "start"] -> { |
| let session = ghost_writing.start_ghost_writing_session("https://example.com/heart_diagram.png") |
| json_response("{\"session_id\": \"" <> session.session_id <> "\", \"canvas\": \"" <> ghost_writing.create_drawing_canvas_html() <> "\"}") |
| } |
| ["api", "ghost_writing", "submit"] -> { |
| let strokes = [] |
| let score = ghost_writing.calculate_similarity(strokes, "reference.png") |
| json_response("{\"score\": " <> float.to_string(score.overall_score) <> ", \"structural\": " <> float.to_string(score.structural_accuracy) <> "}") |
| } |
| |
| // YouTube to Study Materials |
| ["api", "youtube", "convert", video_id] -> { |
| json_response("{\"status\": \"processing\", \"video_id\": \"" <> video_id <> "\", \"message\": \"Extracting transcript and generating flashcards...\"}") |
| } |
| ["api", "pulse", "overview"] -> json_response(build_pulse_overview_json()) |
| ["api", "coach", "mission"] -> json_response(build_coach_mission_json("general", "scholar")) |
| ["api", "coach", "mission", domain, level] -> json_response(build_coach_mission_json(domain, level)) |
| ["api", "exam", "blitz", difficulty] -> json_response(build_exam_blitz_json(difficulty)) |
| ["api", "system", "health"] -> json_response(build_system_health_json()) |
| |
| // UI Pages |
| [] -> render_ui("login", "") |
| ["hub"] -> render_ui("hub", "") |
| ["calendar"] -> render_ui("calendar", "") |
| ["sketch"] -> render_ui("sketch", "") |
| ["library"] -> render_ui("library", "") |
| ["tutor"] -> render_ui("tutor", "") |
| ["analytics"] -> render_ui("analytics", "") |
| ["heatmap"] -> render_ui("heatmap", "") |
| ["multiplayer"] -> render_ui("multiplayer", "") |
| ["biometric"] -> render_ui("biometric", "") |
| ["timetravel"] -> render_ui("timetravel", "") |
| ["exam"] -> render_ui("exam", "") |
| ["ghostwriting"] -> render_ui("ghostwriting", "") |
| ["settings"] -> render_ui("settings", "") |
| ["education"] -> render_ui("education", "") |
| ["ai-solver"] -> render_ui("ai-solver", "") |
| ["study-tools"] -> render_ui("study-tools", "") |
| ["flashcards"] -> render_ui("flashcards", "") |
| ["pdf-export"] -> render_ui("pdf-export", "") |
| ["practice"] -> render_ui("practice", "") |
| ["subscriptions"] -> render_ui("subscriptions", "") |
| ["file-manager"] -> render_ui("file-manager", "") |
| ["blog"] -> render_ui("blog", "") |
| ["youtube"] -> render_ui("youtube", "") |
| ["command-center"] -> render_ui("command-center", "") |
| |
| _ -> render_ui("404", "") |
| } |
| } |
|
|
| fn json_response(json: String) -> response.Response(ResponseData) { |
| response.new(200) |
| |> response.set_header("content-type", "application/json") |
| |> response.set_body(mist.Bytes(bytes_tree.from_string(json))) |
| } |
|
|
| fn sample_mastery_cards() -> List(#(String, String, Float)) { |
| [ |
| #("card_1", "Quantum Mechanics", 85.0), |
| #("card_2", "Linear Algebra", 72.0), |
| #("card_3", "Thermodynamics", 63.0), |
| #("card_4", "Organic Chemistry", 91.0), |
| #("card_5", "Differential Equations", 45.0), |
| ] |
| } |
|
|
| fn sample_focus_metrics() -> biometric_tracker.FocusMetrics { |
| let previous = biometric_tracker.BiometricData( |
| timestamp: 1710841700, |
| eye_gaze_x: 390.0, |
| eye_gaze_y: 320.0, |
| head_posture: biometric_tracker.Upright, |
| blink_rate: 16.0, |
| pupil_size: 5.0, |
| attention_score: 0.83, |
| is_user_present: True, |
| ) |
|
|
| let current = biometric_tracker.BiometricData( |
| timestamp: 1710841800, |
| eye_gaze_x: 400.0, |
| eye_gaze_y: 300.0, |
| head_posture: biometric_tracker.Upright, |
| blink_rate: 18.0, |
| pupil_size: 5.2, |
| attention_score: 0.88, |
| is_user_present: True, |
| ) |
|
|
| biometric_tracker.monitor_focus_stream(current, option.Some(previous)) |
| } |
|
|
| fn first_three_topics(topics: List(String)) -> #(String, String, String) { |
| case topics { |
| [a, b, c, .._] -> #(a, b, c) |
| [a, b] -> #(a, b, "Revision Sprint") |
| [a] -> #(a, "Concept Linking", "Revision Sprint") |
| [] -> #("Differential Equations", "Thermodynamics", "Concept Linking") |
| } |
| } |
|
|
| fn parse_domain(domain: String) -> #(ai_tutor.SubjectDomain, String) { |
| case string.lowercase(domain) { |
| "medicine" -> #(ai_tutor.Medicine, "Medicine") |
| "computer" | "computerscience" | "cs" -> #(ai_tutor.ComputerScience, "Computer Science") |
| "math" | "mathematics" -> #(ai_tutor.Mathematics, "Mathematics") |
| "law" -> #(ai_tutor.Law, "Law") |
| _ -> #(ai_tutor.GeneralStudies, "General Studies") |
| } |
| } |
|
|
| fn parse_level(level: String) -> #(ai_tutor.Difficulty, String) { |
| case string.lowercase(level) { |
| "initiate" | "easy" -> #(ai_tutor.Initiate, "Initiate") |
| "scholar" | "medium" -> #(ai_tutor.Scholar, "Scholar") |
| "master" | "hard" -> #(ai_tutor.Master, "Master") |
| "zenith" | "expert" -> #(ai_tutor.Zenith, "Zenith") |
| _ -> #(ai_tutor.Scholar, "Scholar") |
| } |
| } |
|
|
| fn build_pulse_overview_json() -> String { |
| let map = neural_heatmap.build_constellation(sample_mastery_cards()) |
| let metrics = sample_focus_metrics() |
| let recommendations = neural_heatmap.recommend_next_topics(map) |
| let #(r1, r2, r3) = first_three_topics(recommendations) |
| let efficiency = ai_tutor.calculate_study_efficiency(240, 168, 90) |
| let retention_report = ai_tutor.generate_retention_report(efficiency) |
| let schedule = sm2_algorithm.calculate_next_review(sm2_algorithm.initial_state(), sm2_algorithm.Easy) |
|
|
| "{\"version\": \"" <> app_version <> |
| "\", \"total_mastery\": " <> float.to_string(map.total_mastery) <> |
| ", \"focus_score\": " <> float.to_string(metrics.current_focus_score) <> |
| ", \"focus_trend\": \"" <> metrics.focus_trend <> |
| "\", \"study_efficiency\": " <> float.to_string(efficiency) <> |
| ", \"retention_report\": \"" <> retention_report <> |
| "\", \"next_review_date\": \"" <> schedule.next_review_date <> |
| "\", \"recommended_topic_1\": \"" <> r1 <> |
| "\", \"recommended_topic_2\": \"" <> r2 <> |
| "\", \"recommended_topic_3\": \"" <> r3 <> |
| "\"}" |
| } |
|
|
| fn build_coach_mission_json(domain: String, level: String) -> String { |
| let #(subject, subject_label) = parse_domain(domain) |
| let #(difficulty, difficulty_label) = parse_level(level) |
| let mission_name = subject_label <> " " <> difficulty_label <> " Mission" |
| let intent = ai_tutor.parse_detailed_intent("explain differences and test me with deep mechanisms") |
| let prompt = ai_tutor.generate_subject_optimized_prompt( |
| "Design a 45-minute sprint to improve weak topics and improve retention.", |
| subject, |
| difficulty, |
| ) |
|
|
| "{\"mission_name\": \"" <> mission_name <> |
| "\", \"domain\": \"" <> subject_label <> |
| "\", \"difficulty\": \"" <> difficulty_label <> |
| "\", \"intent\": \"" <> intent <> |
| "\", \"prompt\": \"" <> prompt <> |
| "\", \"micro_goals\": \"25m deep focus + 10m active recall + 10m synthesis\"}" |
| } |
|
|
| fn build_exam_blitz_json(difficulty: String) -> String { |
| let normalized = case string.lowercase(difficulty) { |
| "easy" -> "easy" |
| "hard" | "expert" -> "hard" |
| _ -> "medium" |
| } |
|
|
| let cards = [ |
| #("card_1", "Define photosynthesis", "Process by which plants convert light to chemical energy"), |
| #("card_2", "What is ATP?", "Adenosine triphosphate, cellular energy molecule"), |
| #("card_3", "Explain mitochondria function", "Powerhouse of the cell, produces ATP"), |
| #("card_4", "Describe osmosis", "Movement of water across semipermeable membrane"), |
| #("card_5", "What is cellular respiration?", "Metabolic pathway that generates ATP"), |
| ] |
|
|
| let exam = exam_generator.generate_mock_exam("Integrated Sciences", cards, 5, normalized) |
| let schedule = sm2_algorithm.calculate_next_review(sm2_algorithm.initial_state(), sm2_algorithm.Acceptable) |
|
|
| "{\"exam_id\": \"" <> exam.exam_id <> |
| "\", \"difficulty\": \"" <> normalized <> |
| "\", \"question_count\": " <> int.to_string(list.length(exam.questions)) <> |
| ", \"duration_minutes\": " <> int.to_string(exam.duration_minutes) <> |
| ", \"total_points\": " <> int.to_string(exam.total_points) <> |
| ", \"next_review_date\": \"" <> schedule.next_review_date <> |
| "\"}" |
| } |
|
|
| fn build_system_health_json() -> String { |
| let map = neural_heatmap.build_constellation(sample_mastery_cards()) |
| let metrics = sample_focus_metrics() |
| let capability = {map.total_mastery +. metrics.current_focus_score +. 92.0} /. 3.0 |
|
|
| "{\"status\": \"healthy\", \"platform\": \"FlashSync\", \"version\": \"" <> app_version <> |
| "\", \"capability_index\": " <> float.to_string(capability) <> |
| ", \"modules_online\": 12, \"api_ready\": true}" |
| } |
|
|
| fn render_ui(page: String, _extra_content: String) -> response.Response(ResponseData) { |
| let content = case page { |
| "login" -> " |
| // <h1 class="brand-title">FlashSync</h1> |
| // <input type="text" id="user" placeholder="Enter your name" class="modern-input"> |
| // <button class="primary-button" onclick="login()">Get Started</button> |
| // <button onclick="setLanguage(\"en\")" class="lang-icon active">EN</button> |
| // <button onclick="setLanguage(\"nl\")" class="lang-icon">NL</button> |
| // <button onclick="setLanguage(\"es\")" class="lang-icon">ES</button> |
| // <button onclick="setLanguage(\"fr\")" class="lang-icon">FR</button> |
| // <button onclick="setLanguage(\"de\")" class="lang-icon">DE</button> |
| // <button onclick="setLanguage(\"it\")" class="lang-icon">IT</button> |
| // <button onclick="setLanguage(\"pt\")" class="lang-icon">PT</button> |
| // <button onclick="setLanguage(\"ja\")" class="lang-icon">JP</button> |
| // </div> |
| // </div> |
| // </div>" |
| |
| "hub" -> " |
| // </div> |
| |
| <h3>AI Tutor</h3> |
| // </div> |
| |
| <h3>Flashcards</h3> |
| // </div> |
| |
| <h3>Practice</h3> |
| // </div> |
| |
| <h3>PDF Export</h3> |
| // </div> |
| |
| <h3>Knowledge Map</h3> |
| // </div> |
| |
| <h3>Mock Exams</h3> |
| // </div> |
| |
| <h3>My Files</h3> |
| // </div> |
| |
| <h3>Subscription</h3> |
| // </div> |
| // </div> |
| |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div>" |
| |
| "heatmap" -> " |
| // <h1>Knowledge Map</h1> |
| // </div> |
| |
| // <button class="filter-btn active" onclick="filterMap('all')">All Topics</button> |
| // <button class="filter-btn" onclick="filterMap('strong')">Strong</button> |
| // <button class="filter-btn" onclick="filterMap('weak')">Needs Work</button> |
| // <button class="filter-btn" onclick="filterMap('recent')">Recent</button> |
| // </div> |
| // <button class="view-btn active" onclick="setMapView('constellation')"><i class="fas fa-star"></i> Constellation</button> |
| // <button class="view-btn" onclick="setMapView('grid')"><i class="fas fa-th"></i> Grid</button> |
| // <button class="view-btn" onclick="setMapView('timeline')"><i class="fas fa-stream"></i> Timeline</button> |
| // </div> |
| // </div> |
| |
| <canvas id="knowledgeCanvas" style="width: 100%; height: 450px; cursor: grab;"></canvas> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| |
| <h4 style="margin-bottom: 16px;"><i class="fas fa-brain"></i> Learning Insights</h4> |
| <i class="fas fa-arrow-trend-up" style="color: var(--success); font-size: 20px;"></i> |
| <strong>+23% improvement</strong> |
| // </div> |
| // </div> |
| <i class="fas fa-clock" style="color: var(--primary); font-size: 20px;"></i> |
| <strong>Peak learning time</strong> |
| // </div> |
| // </div> |
| <i class="fas fa-fire" style="color: var(--warning); font-size: 20px;"></i> |
| <strong>5 day streak!</strong> |
| // </div> |
| // </div> |
| // </div> |
| |
| <h4 style="margin-bottom: 16px;"><i class="fas fa-bullseye"></i> Recommended Focus</h4> |
| <strong>Differential Equations</strong> |
| // </div> |
| // <button class="mini-btn" onclick="startStudying('diffeq')">Study</button> |
| // </div> |
| <strong>Thermodynamics</strong> |
| // </div> |
| // <button class="mini-btn" onclick="startStudying('thermo')">Study</button> |
| // </div> |
| <strong>Organic Chemistry</strong> |
| // </div> |
| // <button class="mini-btn" onclick="startStudying('organic')">Review</button> |
| // </div> |
| // </div> |
| // </div> |
| // </div>" |
| |
| "tutor" -> " |
| // <h1>AI Tutor</h1> |
| // </div> |
| |
| <ul> |
| <li>Explaining complex concepts</li> |
| <li>Answering questions</li> |
| <li>Analyzing uploaded PDFs and images</li> |
| <li>Generating practice problems</li> |
| <li>Creating study summaries</li> |
| </ul> |
| // </div> |
| // </div> |
| // </div> |
| |
| // <input type="file" id="fileUpload" multiple accept=".pdf,.png,.jpg,.jpeg,.docx,.pptx" style="display: none;"> |
| // <button class="attach-btn" onclick="document.getElementById(\"fileUpload\").click()"><i class="fas fa-paperclip"></i></button> |
| // </div> |
| // <input type="text" id="tutorInput" class="chat-input" placeholder="Ask anything or upload a file..." onkeydown="if(event.key===\"Enter\") sendTutorMessage()"> |
| // <button class="send-btn" onclick="sendTutorMessage()"><i class="fas fa-paper-plane"></i></button> |
| // </div> |
| // </div> |
| |
| <h4>Quick Actions</h4> |
| // <button class="quick-action" onclick="askTutor(\"Explain photosynthesis\")"><i class="fas fa-leaf"></i> Photosynthesis</button> |
| // <button class="quick-action" onclick="askTutor(\"Solve: x² + 5x + 6 = 0\")"><i class="fas fa-calculator"></i> Math Problem</button> |
| // <button class="quick-action" onclick="askTutor(\"Generate 5 practice questions\")"><i class="fas fa-question"></i> Practice Questions</button> |
| // <button class="quick-action" onclick="askTutor(\"Summarize my last deck\")"><i class="fas fa-compress"></i> Summarize</button> |
| // </div> |
| |
| <h4>Uploaded Files</h4> |
| // </div> |
| // </div> |
| // </div> |
| // </div>" |
| |
| "biometric" -> " |
| // <h1>Focus Tracking</h1> |
| // </div> |
| |
| <h3 style="color: var(--success);">88%</h3> |
| // </div> |
| <h3 style="color: var(--primary);">18.4</h3> |
| // </div> |
| <h3 style="color: var(--secondary);">Good</h3> |
| // </div> |
| <h3 style="color: var(--accent);">140 BPM</h3> |
| // </div> |
| // </div>" |
| |
| "multiplayer" -> " |
| // <h1>Study Rooms</h1> |
| // </div> |
| |
| // </div>" |
| |
| "ghostwriting" -> " |
| // <h1>Drawing Practice</h1> |
| // </div> |
| |
| <h4>Reference Image</h4> |
| <canvas id="ghostCanvas" width="350" height="350" style="background: var(--bg-dark); border-radius: 10px; width: 100%;"></canvas> |
| // </div> |
| <h4>Your Drawing</h4> |
| <canvas id="userCanvas" width="350" height="350" style="background: var(--bg-dark); border-radius: 10px; width: 100%; cursor: crosshair;"></canvas> |
| // </div> |
| // </div> |
| // <button class="secondary-button" onclick="clearCanvas()">Clear</button> |
| // <button class="primary-button" onclick="submitDrawing()" style="flex: 1;">Submit & Score</button> |
| // </div>" |
| |
| "timetravel" -> " |
| // <h1>Learning Timeline</h1> |
| // </div> |
| |
| <h3>Your Progress</h3> |
| // </div> |
| // </div>" |
| |
| "exam" -> " |
| // <h1>Mock Exams</h1> |
| // </div> |
| |
| <h4>Biology 101</h4> |
| // <button class="primary-button" style="width: 100%; margin-top: 16px;">Start Exam</button> |
| // </div> |
| <h4>Chemistry Fundamentals</h4> |
| // <button class="primary-button" style="width: 100%; margin-top: 16px;">Start Exam</button> |
| // </div> |
| // </div>" |
| |
| "analytics" -> " |
| // <h1>Analytics</h1> |
| // </div> |
| |
| <h4 style="color: var(--primary);">85.2%</h4> |
| // </div> |
| <h4 style="color: var(--success);">88 min</h4> |
| // </div> |
| <h4 style="color: var(--secondary);">142</h4> |
| // </div> |
| <h4 style="color: var(--accent);">94.2%</h4> |
| // </div> |
| // </div>" |
|
|
| "command-center" -> " |
| // <h1>Command Center</h1> |
| // </div> |
|
|
| <h3><i class="fas fa-satellite-dish"></i> Live Intelligence Pulse</h3> |
| // <button class="primary-button" onclick="fetch(\"/api/pulse/overview\").then(r => r.json()).then(d => alert(\"Focus: \" + d.focus_score + \"% | Mastery: \" + d.total_mastery + \"% | Next Review: \" + d.next_review_date))">Run Pulse Scan</button> |
| // </div> |
| <h3><i class="fas fa-chess-knight"></i> Adaptive Coach Mission</h3> |
| // <button class="accent-button" onclick="fetch(\"/api/coach/mission/computerscience/master\").then(r => r.json()).then(d => alert(d.mission_name + \"\\n\\n\" + d.intent + \"\\n\\n\" + d.prompt))">Generate Mission</button> |
| // </div> |
| // </div> |
|
|
| <h3><i class="fas fa-bolt"></i> Blitz Exam Generator</h3> |
| // <button class="success-button" onclick="fetch(\"/api/exam/blitz/medium\").then(r => r.json()).then(d => alert(\"Exam ID: \" + d.exam_id + \" | Questions: \" + d.question_count + \" | Duration: \" + d.duration_minutes + \" min\"))">Create Blitz Exam</button> |
| // </div>" |
| |
| "flashcards" -> " |
| // <h1>Flashcard Vault</h1> |
| // </div> |
| |
| // <button class="primary-button" onclick="createDeck()"><i class="fas fa-plus"></i> New Deck</button> |
| // <button class="secondary-button" onclick="importDeck()"><i class="fas fa-file-import"></i> Import</button> |
| // <button class="accent-button" onclick="exportAllPDF()"><i class="fas fa-file-pdf"></i> Export All</button> |
| // <button class="success-button" onclick="printMode()"><i class="fas fa-print"></i> Print & Cut</button> |
| // </div> |
| |
| // <h2>Your Decks</h2> |
| <h3>Biology 101</h3> |
| // </div> |
| // </div> |
| // <button class="mini-btn primary">Study</button> |
| // <button class="mini-btn">Review</button> |
| // </div> |
| // </div> |
| |
| <h3>Chemistry</h3> |
| // </div> |
| // </div> |
| // <button class="mini-btn primary">Study</button> |
| // <button class="mini-btn">Review</button> |
| // </div> |
| // </div> |
| |
| <i class="fas fa-plus-circle"></i> |
| // </div> |
| // </div> |
| // </div>" |
| |
| "practice" -> " |
| // <h1>Practice Questions</h1> |
| // </div> |
| |
| <h3>Select Subject</h3> |
| // <button class="subject-btn active" data-subject="biology" onclick="selectSubject(this)"> |
| <i class="fas fa-dna"></i> Biology |
| </button> |
| // <button class="subject-btn" data-subject="history" onclick="selectSubject(this)"> |
| <i class="fas fa-landmark"></i> History |
| </button> |
| // <button class="subject-btn" data-subject="physics" onclick="selectSubject(this)"> |
| <i class="fas fa-atom"></i> Physics |
| </button> |
| // <button class="subject-btn" data-subject="chemistry" onclick="selectSubject(this)"> |
| <i class="fas fa-flask"></i> Chemistry |
| </button> |
| // <button class="subject-btn" data-subject="mathematics" onclick="selectSubject(this)"> |
| <i class="fas fa-calculator"></i> Mathematics |
| </button> |
| // <button class="subject-btn" data-subject="geography" onclick="selectSubject(this)"> |
| <i class="fas fa-globe"></i> Geography |
| </button> |
| // <button class="subject-btn" data-subject="literature" onclick="selectSubject(this)"> |
| <i class="fas fa-book"></i> Literature |
| </button> |
| // <button class="subject-btn" data-subject="computer" onclick="selectSubject(this)"> |
| <i class="fas fa-laptop-code"></i> Computer Science |
| </button> |
| // </div> |
| // </div> |
| |
| <label>Difficulty</label> |
| <select id="quizDifficulty" class="modern-input"> |
| <option value="easy">Easy</option> |
| <option value="medium" selected>Medium</option> |
| <option value="hard">Hard</option> |
| <option value="expert">Expert</option> |
| </select> |
| // </div> |
| <label>Number of Questions</label> |
| <select id="quizCount" class="modern-input"> |
| <option value="10">10</option> |
| <option value="25">25</option> |
| <option value="50" selected>50</option> |
| <option value="100">100</option> |
| </select> |
| // </div> |
| // </div> |
| |
| // <button class="primary-button full" onclick="startQuiz()"><i class="fas fa-play"></i> Start Quiz</button> |
| // </div> |
| |
| // </div> |
| |
| // </div> |
| |
| // <h2 class="question-text" id="questionText">What is the powerhouse of the cell?</h2> |
| |
| // <button class="quiz-option" data-index="0" onclick="selectAnswer(this)">Nucleus</button> |
| // <button class="quiz-option" data-index="1" onclick="selectAnswer(this)">Mitochondria</button> |
| // <button class="quiz-option" data-index="2" onclick="selectAnswer(this)">Ribosome</button> |
| // <button class="quiz-option" data-index="3" onclick="selectAnswer(this)">Endoplasmic Reticulum</button> |
| // </div> |
| // </div> |
| |
| <h3 id="feedbackTitle">Correct!</h3> |
| // </div> |
| // <button class="primary-button" onclick="nextQuestion()"><i class="fas fa-arrow-right"></i> Next Question</button> |
| // </div> |
| |
| // <h2>Quiz Complete!</h2> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // <button class="primary-button" onclick="restartQuiz()"><i class="fas fa-redo"></i> Try Again</button> |
| // <button class="secondary-button" onclick="backToSetup()"><i class="fas fa-arrow-left"></i> New Quiz</button> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| |
| <canvas id="confettiCanvas" class="confetti-canvas"></canvas> |
| |
| <h3>Subject Statistics</h3> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div>" |
| |
| "pdf-export" -> " |
| // <h1>PDF Export & Download</h1> |
| // </div> |
| |
| <h3>All Flashcards</h3> |
| // <button class="primary-button" onclick="exportAllCards()"><i class="fas fa-download"></i> Download</button> |
| // </div> |
| |
| <h3>Print & Cut Mode</h3> |
| // <button class="accent-button" onclick="exportPrintable()"><i class="fas fa-print"></i> Prepare Print</button> |
| // </div> |
| |
| <h3>Study Guide</h3> |
| // <button class="secondary-button" onclick="exportStudyGuide()"><i class="fas fa-download"></i> Download</button> |
| // </div> |
| |
| <h3>Exam Results</h3> |
| // <button class="secondary-button" onclick="exportExamResults()"><i class="fas fa-download"></i> Download</button> |
| // </div> |
| // </div> |
| |
| <h3>Export Settings</h3> |
| <label class="toggle-label"> |
| // <input type="checkbox" checked> |
| Include card images |
| </label> |
| <label class="toggle-label"> |
| // <input type="checkbox" checked> |
| Include mastery statistics |
| </label> |
| <label class="toggle-label"> |
| // <input type="checkbox"> |
| Include answer keys |
| </label> |
| <label class="toggle-label"> |
| // <input type="checkbox" checked> |
| Math formula rendering |
| </label> |
| // </div> |
| // </div>" |
| |
| "ai-solver" -> " |
| // <h1>AI Problem Solver</h1> |
| // </div> |
| |
| <i class="fas fa-camera"></i> |
| // </div> |
| <i class="fas fa-keyboard"></i> |
| // </div> |
| <i class="fas fa-microphone"></i> |
| // </div> |
| // </div> |
| |
| // <input type="file" id="solverFile" accept="image/*" style="display: none;" onchange="handleSolverUpload()"> |
| <i class="fas fa-cloud-upload-alt"></i> |
| // </div> |
| // </div> |
| |
| <textarea class="solver-textarea" placeholder="Type or paste your math problem, equation, or question here..."></textarea> |
| // <button onclick="insertMath(\"frac\")"><i class="fas fa-divide"></i> Fraction</button> |
| // <button onclick="insertMath(\"sqrt\")"><i class="fas fa-square-root-alt"></i> Root</button> |
| // <button onclick="insertMath(\"pow\")"><i class="fas fa-superscript"></i> Power</button> |
| // <button onclick="insertMath(\"sum\")"><i class="fas fa-sigma"></i> Sum</button> |
| // </div> |
| // </div> |
| |
| // <button class="solve-button" onclick="solveProblem()"><i class="fas fa-bolt"></i> Solve Now</button> |
| // </div> |
| |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div>" |
| |
| "settings" -> " |
| // <h1>Settings</h1> |
| // </div> |
| |
| // <button class="settings-tab active" onclick="showSettingsTab(\"profile\")"><i class="fas fa-user"></i> Profile</button> |
| // <button class="settings-tab" onclick="showSettingsTab(\"appearance\")"><i class="fas fa-palette"></i> Appearance</button> |
| // <button class="settings-tab" onclick="showSettingsTab(\"learning\")"><i class="fas fa-graduation-cap"></i> Learning</button> |
| // <button class="settings-tab" onclick="showSettingsTab(\"notifications\")"><i class="fas fa-bell"></i> Notifications</button> |
| // <button class="settings-tab" onclick="showSettingsTab(\"language\")"><i class="fas fa-globe"></i> Language</button> |
| // <button class="settings-tab" onclick="showSettingsTab(\"billing\")"><i class="fas fa-credit-card"></i> Billing</button> |
| // </div> |
| |
| <h3>Profile Information</h3> |
| <i class="fas fa-user"></i> |
| // </div> |
| // <button class="secondary-button small"><i class="fas fa-camera"></i> Change</button> |
| // </div> |
| <label>Display Name</label> |
| // <input type="text" class="modern-input" value="Student"> |
| // </div> |
| <label>Email</label> |
| // <input type="email" class="modern-input" value="student@example.com"> |
| // </div> |
| // </div> |
| // </div> |
| |
| <h3>Public Profile</h3> |
| <label class="toggle-label"> |
| // <input type="checkbox"> |
| Allow others to see my shared decks |
| </label> |
| <label class="toggle-label"> |
| // <input type="checkbox" checked> |
| Show achievements on profile |
| </label> |
| // </div> |
| |
| <h3>Theme</h3> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| |
| <h3>Animations</h3> |
| <label>Hover Effect Intensity</label> |
| // <input type="range" min="0" max="100" value="80" class="modern-slider" oninput="updateAnimationIntensity(this.value)"> |
| // </div> |
| <label class="toggle-label"> |
| // <input type="checkbox" checked> |
| Enable card flip animations |
| </label> |
| <label class="toggle-label"> |
| // <input type="checkbox" checked> |
| Enable page transitions |
| </label> |
| <label class="toggle-label"> |
| // <input type="checkbox"> |
| Reduce motion (accessibility) |
| </label> |
| // </div> |
| |
| <h3>Daily Goals</h3> |
| <label>Study Time (minutes)</label> |
| // <input type="number" class="modern-input" value="60"> |
| // </div> |
| <label>Cards per Day</label> |
| // <input type="number" class="modern-input" value="20"> |
| // </div> |
| |
| <h3>Algorithm Settings</h3> |
| <label class="toggle-label"> |
| // <input type="checkbox" checked> |
| Use SM-2 spaced repetition |
| </label> |
| <label class="toggle-label"> |
| // <input type="checkbox" checked> |
| Auto-schedule review sessions |
| </label> |
| // </div> |
| |
| <h3>Interface Language</h3> |
| // <button class="lang-btn active" onclick="setLanguage(\"en\")">English</button> |
| // <button class="lang-btn" onclick="setLanguage(\"nl\")">Nederlands (Dutch)</button> |
| // <button class="lang-btn" onclick="setLanguage(\"es\")">Español</button> |
| // <button class="lang-btn" onclick="setLanguage(\"fr\")">Français</button> |
| // <button class="lang-btn" onclick="setLanguage(\"de\")">Deutsch</button> |
| // <button class="lang-btn" onclick="setLanguage(\"it\")">Italiano</button> |
| // <button class="lang-btn" onclick="setLanguage(\"pt\")">Português</button> |
| // <button class="lang-btn" onclick="setLanguage(\"ja\")">日本語</button> |
| // </div> |
| // </div> |
| |
| // <button class="secondary-button" onclick="resetSettings()">Reset to Default</button> |
| // <button class="primary-button" onclick="saveSettings()"><i class="fas fa-save"></i> Save Changes</button> |
| // </div> |
| // </div> |
| // </div>" |
| |
| "subscriptions" -> " |
| // <h1>Choose Your Plan</h1> |
| // </div> |
| |
| <label class="switch"> |
| // <input type="checkbox" onchange="toggleBilling()"> |
| </label> |
| // </div> |
| |
| <h3>Free</h3> |
| // </div> |
| <ul class="features"> |
| <li><i class="fas fa-check"></i> Up to 100 flashcards</li> |
| <li><i class="fas fa-check"></i> Basic AI Tutor</li> |
| <li><i class="fas fa-check"></i> SM-2 algorithm</li> |
| <li><i class="fas fa-check"></i> 3 mock exams</li> |
| <li class="disabled"><i class="fas fa-times"></i> PDF export</li> |
| <li class="disabled"><i class="fas fa-times"></i> File upload</li> |
| <li class="disabled"><i class="fas fa-times"></i> 8 languages</li> |
| </ul> |
| // <button class="secondary-button full" disabled>Current Plan</button> |
| // </div> |
| |
| <h3>Standard</h3> |
| // </div> |
| <ul class="features"> |
| <li><i class="fas fa-check"></i> Unlimited flashcards</li> |
| <li><i class="fas fa-check"></i> Full AI Tutor + File upload</li> |
| <li><i class="fas fa-check"></i> PDF export & Print mode</li> |
| <li><i class="fas fa-check"></i> Unlimited mock exams</li> |
| <li><i class="fas fa-check"></i> 8 language support</li> |
| <li><i class="fas fa-check"></i> Biometric tracking</li> |
| <li class="disabled"><i class="fas fa-times"></i> iDEAL/Bancontact</li> |
| </ul> |
| // <button class="primary-button full" onclick="subscribe(\"standard\")">Upgrade</button> |
| // </div> |
| |
| <h3>Plus</h3> |
| // </div> |
| <ul class="features"> |
| <li><i class="fas fa-check"></i> Everything in Standard</li> |
| <li><i class="fas fa-check"></i> iDEAL & Bancontact payments</li> |
| <li><i class="fas fa-check"></i> 50GB file storage</li> |
| <li><i class="fas fa-check"></i> Word & PowerPoint support</li> |
| <li><i class="fas fa-check"></i> Priority AI processing</li> |
| <li><i class="fas fa-check"></i> Study groups (10 people)</li> |
| <li><i class="fas fa-check"></i> Advanced analytics</li> |
| </ul> |
| // <button class="accent-button full" onclick="subscribe(\"plus\")">Go Plus</button> |
| // </div> |
| // </div> |
| |
| <h3>Supported Payment Methods</h3> |
| // </div> |
| // </div>" |
| |
| "file-manager" -> " |
| // <h1>My Files</h1> |
| // </div> |
| |
| // <button class="primary-button" onclick="document.getElementById(\"fileUpload\").click()"><i class="fas fa-cloud-upload-alt"></i> Upload</button> |
| // <input type="file" id="fileUpload" multiple accept=".pdf,.docx,.pptx,.jpg,.png" style="display: none;" onchange="uploadFiles()"> |
| // <button class="filter-btn active">All</button> |
| // <button class="filter-btn">PDF</button> |
| // <button class="filter-btn">Documents</button> |
| // <button class="filter-btn">Images</button> |
| // </div> |
| // </div> |
| // </div> |
| |
| <h4>Biology_Notes.pdf</h4> |
| // </div> |
| // <button onclick="previewFile(\"biology\")"><i class="fas fa-eye"></i></button> |
| // <button onclick="shareFile(\"biology\")"><i class="fas fa-share"></i></button> |
| // <button onclick="deleteFile(\"biology\")"><i class="fas fa-trash"></i></button> |
| // </div> |
| // </div> |
| |
| <h4>Chemistry_Lab.docx</h4> |
| // </div> |
| // <button onclick="previewFile(\"chemistry\")"><i class="fas fa-eye"></i></button> |
| // <button onclick="shareFile(\"chemistry\")"><i class="fas fa-share"></i></button> |
| // <button onclick="deleteFile(\"chemistry\")"><i class="fas fa-trash"></i></button> |
| // </div> |
| // </div> |
| |
| <h4>Physics_Slides.pptx</h4> |
| // </div> |
| // <button onclick="previewFile(\"physics\")"><i class="fas fa-eye"></i></button> |
| // <button onclick="shareFile(\"physics\")"><i class="fas fa-share"></i></button> |
| // <button onclick="deleteFile(\"physics\")"><i class="fas fa-trash"></i></button> |
| // </div> |
| // </div> |
| |
| <h4>Diagram_01.png</h4> |
| // </div> |
| // <button onclick="previewFile(\"diagram\")"><i class="fas fa-eye"></i></button> |
| // <button onclick="shareFile(\"diagram\")"><i class="fas fa-share"></i></button> |
| // <button onclick="deleteFile(\"diagram\")"><i class="fas fa-trash"></i></button> |
| // </div> |
| // </div> |
| // </div>" |
| |
| "blog" -> " |
| // <h1>Learning Blog</h1> |
| // </div> |
| |
| <article class="blog-card"> |
| <h3>Master Spaced Repetition</h3> |
| // </div> |
| </article> |
| |
| <article class="blog-card"> |
| <h3>Sleep and Memory Consolidation</h3> |
| // </div> |
| </article> |
| |
| <article class="blog-card"> |
| <h3>The Feynman Technique</h3> |
| // </div> |
| </article> |
| |
| <article class="blog-card"> |
| <h3>The Pomodoro Technique</h3> |
| // </div> |
| </article> |
| // </div>" |
| |
| "youtube" -> " |
| // <h1>YouTube to Study Materials</h1> |
| // </div> |
| |
| <i class="fab fa-youtube"></i> |
| // <input type="text" id="youtubeUrl" class="modern-input" placeholder="Paste YouTube URL here (e.g., https://youtube.com/watch?v=...)"> |
| // <button class="primary-button" onclick="convertYoutube()"><i class="fas fa-magic"></i> Convert</button> |
| // </div> |
| // </div> |
| |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| |
| <i class="fas fa-play-circle"></i> |
| // </div> |
| <h3 id="videoTitle">Introduction to Quantum Physics</h3> |
| // </div> |
| // </div> |
| // </div> |
| |
| <h3>Generated Study Materials</h3> |
| <h4>Flashcard Deck</h4> |
| // <button class="secondary-button small">Download</button> |
| // </div> |
| |
| <h4>Summary</h4> |
| // <button class="secondary-button small">Download</button> |
| // </div> |
| |
| <h4>Practice Questions</h4> |
| // <button class="secondary-button small">Download</button> |
| // </div> |
| |
| <h4>Full Transcript</h4> |
| // <button class="secondary-button small">Download</button> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // </div>" |
| |
| _ -> " |
| // <h1>Page Not Found</h1> |
| // <button class="primary-button" onclick="location.href=\"/hub\""><i class="fas fa-home"></i> Back to Dashboard</button> |
| // </div>" |
| } |
| assemble(page, content) |
| } |
|
|
| fn assemble(page: String, content: String) -> response.Response(ResponseData) { |
| let html = build_html_page(page, content) |
| response.new(200) |
| |> response.set_header("content-type", "text/html") |
| |> response.set_header("X-Frame-Options", "SAMEORIGIN") |
| |> response.set_header("Content-Security-Policy", "default-src "self"; script-src "self" "unsafe-inline" https://cdnjs.cloudflare.com; style-src "self" "unsafe-inline" https://cdnjs.cloudflare.com; font-src https://cdnjs.cloudflare.com;") |
| |> response.set_body(mist.Bytes(bytes_tree.from_string(html))) |
| } |
|
|
| fn build_html_page(page: String, content: String) -> String { |
| "<!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| <title>FlashSync - Advanced Learning Platform</title> |
| <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet"> |
| <style>" <> get_all_styles() <> "</style> |
| </head> |
| <body> |
| " <> case page { |
| "login" -> "" |
| _ -> build_navigation(page) |
| } <> " |
| <main class="" <> case page { "login" -> "login-main" _ -> "content-main" } <> ""> |
| " <> content <> " |
| </main> |
| <script>" <> get_all_scripts() <> "</script> |
| </body> |
| </html>" |
| } |
|
|
| fn build_navigation(active_page: String) -> String { |
| "<nav class="sidebar"> |
| <i class="fas fa-brain"></i> |
| // </div> |
| |
| <a href="/hub" class="nav-link " <> case active_page { "hub" -> "active" _ -> "" } <> ""><i class="fas fa-home"></i> Dashboard</a> |
| <a href="/flashcards" class="nav-link " <> case active_page { "flashcards" -> "active" _ -> "" } <> ""><i class="fas fa-layer-group"></i> Flashcards</a> |
| <a href="/practice" class="nav-link " <> case active_page { "practice" -> "active" _ -> "" } <> ""><i class="fas fa-question-circle"></i> Practice</a> |
| <a href="/tutor" class="nav-link " <> case active_page { "tutor" -> "active" _ -> "" } <> ""><i class="fas fa-robot"></i> AI Tutor</a> |
| // </div> |
| |
| <a href="/ai-solver" class="nav-link " <> case active_page { "ai-solver" -> "active" _ -> "" } <> ""><i class="fas fa-wand-magic-sparkles"></i> AI Solver</a> |
| <a href="/youtube" class="nav-link " <> case active_page { "youtube" -> "active" _ -> "" } <> ""><i class="fab fa-youtube"></i> YouTube Convert</a> |
| <a href="/pdf-export" class="nav-link " <> case active_page { "pdf-export" -> "active" _ -> "" } <> ""><i class="fas fa-file-pdf"></i> PDF Export</a> |
| <a href="/file-manager" class="nav-link " <> case active_page { "file-manager" -> "active" _ -> "" } <> ""><i class="fas fa-folder-open"></i> My Files</a> |
| // </div> |
| |
| <a href="/heatmap" class="nav-link " <> case active_page { "heatmap" -> "active" _ -> "" } <> ""><i class="fas fa-brain"></i> Knowledge Map</a> |
| <a href="/exam" class="nav-link " <> case active_page { "exam" -> "active" _ -> "" } <> ""><i class="fas fa-clipboard-check"></i> Exams</a> |
| <a href="/command-center" class="nav-link " <> case active_page { "command-center" -> "active" _ -> "" } <> ""><i class="fas fa-satellite"></i> Command Center</a> |
| // </div> |
| |
| <a href="/blog" class="nav-link " <> case active_page { "blog" -> "active" _ -> "" } <> ""><i class="fas fa-book-open"></i> Blog</a> |
| <a href="/subscriptions" class="nav-link " <> case active_page { "subscriptions" -> "active" _ -> "" } <> ""><i class="fas fa-crown"></i> Subscription</a> |
| <a href="/settings" class="nav-link " <> case active_page { "settings" -> "active" _ -> "" } <> ""><i class="fas fa-cog"></i> Settings</a> |
| // </div> |
| </nav>" |
| } |
|
|
| fn get_all_styles() -> String { |
| " |
| :root { |
| --primary: #00d4ff; |
| --secondary: #a855f7; |
| --accent: #f43f5e; |
| --success: #22c55e; |
| --warning: #f59e0b; |
| --bg-dark: #0a0a0f; |
| --bg-card: #13131f; |
| --bg-hover: #1a1a2e; |
| --text-primary: #ffffff; |
| --text-secondary: #a1a1aa; |
| --border: #27273a; |
| --glass: rgba(255,255,255,0.03); |
| --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); |
| --shadow: 0 4px 20px rgba(0,0,0,0.3); |
| --glow-primary: 0 0 20px rgba(0,212,255,0.3); |
| --glow-secondary: 0 0 20px rgba(168,85,247,0.3); |
| } |
| |
| * { margin: 0; padding: 0; box-sizing: border-box; } |
| |
| body { |
| font-family: "Segoe UI", system-ui, -apple-system, sans-serif; |
| background: var(--bg-dark); |
| color: var(--text-primary); |
| min-height: 100vh; |
| display: flex; |
| } |
| |
| .sidebar { |
| width: 260px; |
| background: var(--bg-card); |
| border-right: 1px solid var(--border); |
| padding: 24px 16px; |
| position: fixed; |
| height: 100vh; |
| overflow-y: auto; |
| z-index: 100; |
| } |
| |
| .nav-brand { |
| display: flex; |
| align-items: center; |
| gap: 12px; |
| padding: 0 12px 24px; |
| margin-bottom: 24px; |
| border-bottom: 1px solid var(--border); |
| } |
| |
| .nav-brand i { |
| font-size: 28px; |
| color: var(--primary); |
| filter: drop-shadow(0 0 10px rgba(0,212,255,0.5)); |
| } |
| |
| .nav-brand span { |
| font-size: 22px; |
| font-weight: 800; |
| background: linear-gradient(135deg, var(--primary), var(--secondary)); |
| -webkit-background-clip: text; |
| -webkit-text-fill-color: transparent; |
| } |
| |
| .nav-section { margin-bottom: 24px; } |
| |
| .nav-label { |
| display: block; |
| font-size: 11px; |
| font-weight: 700; |
| text-transform: uppercase; |
| letter-spacing: 1px; |
| color: var(--text-secondary); |
| padding: 0 12px; |
| margin-bottom: 8px; |
| } |
| |
| .nav-link { |
| display: flex; |
| align-items: center; |
| gap: 12px; |
| padding: 12px 16px; |
| margin: 4px 0; |
| border-radius: 12px; |
| color: var(--text-secondary); |
| text-decoration: none; |
| font-size: 14px; |
| font-weight: 500; |
| transition: var(--transition); |
| position: relative; |
| overflow: hidden; |
| } |
| |
| .nav-link::before { |
| content: ""; |
| position: absolute; |
| left: 0; |
| top: 0; |
| width: 3px; |
| height: 100%; |
| background: var(--primary); |
| transform: scaleY(0); |
| transition: transform 0.3s; |
| } |
| |
| .nav-link:hover { |
| background: var(--bg-hover); |
| color: var(--text-primary); |
| transform: translateX(4px); |
| } |
| |
| .nav-link:hover::before { |
| transform: scaleY(1); |
| } |
| |
| .nav-link.active { |
| background: linear-gradient(90deg, rgba(0,212,255,0.1), transparent); |
| color: var(--primary); |
| } |
| |
| .nav-link.active::before { |
| transform: scaleY(1); |
| } |
| |
| .nav-link i { |
| width: 20px; |
| text-align: center; |
| } |
| |
| .content-main { |
| flex: 1; |
| margin-left: 260px; |
| padding: 32px; |
| max-width: 1400px; |
| } |
| |
| .login-main { |
| flex: 1; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| min-height: 100vh; |
| background: radial-gradient(ellipse at top, #1a1a2e 0%, var(--bg-dark) 50%); |
| } |
| |
| .page-header { |
| margin-bottom: 32px; |
| } |
| |
| .page-header h1 { |
| font-size: 32px; |
| font-weight: 800; |
| margin-bottom: 8px; |
| } |
| |
| .page-header .highlight { |
| background: linear-gradient(135deg, var(--primary), var(--secondary)); |
| -webkit-background-clip: text; |
| -webkit-text-fill-color: transparent; |
| } |
| |
| .subtitle { |
| color: var(--text-secondary); |
| font-size: 16px; |
| } |
| |
| .login-container { |
| width: 100%; |
| max-width: 420px; |
| padding: 20px; |
| } |
| |
| .login-box { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 24px; |
| padding: 48px 40px; |
| text-align: center; |
| box-shadow: var(--shadow); |
| } |
| |
| .brand-title { |
| font-size: 36px; |
| font-weight: 900; |
| background: linear-gradient(135deg, var(--primary), var(--secondary)); |
| -webkit-background-clip: text; |
| -webkit-text-fill-color: transparent; |
| margin-bottom: 8px; |
| } |
| |
| .tagline { |
| color: var(--text-secondary); |
| font-size: 16px; |
| margin-bottom: 8px; |
| } |
| |
| .feature-list { |
| color: var(--text-secondary); |
| font-size: 13px; |
| margin-bottom: 32px; |
| } |
| |
| .modern-input { |
| width: 100%; |
| background: var(--bg-dark); |
| border: 2px solid var(--border); |
| padding: 16px 20px; |
| border-radius: 12px; |
| color: var(--text-primary); |
| font-size: 15px; |
| margin-bottom: 16px; |
| transition: var(--transition); |
| } |
| |
| .modern-input:focus { |
| outline: none; |
| border-color: var(--primary); |
| box-shadow: var(--glow-primary); |
| } |
| |
| .language-bar { |
| display: flex; |
| justify-content: center; |
| gap: 8px; |
| margin-top: 24px; |
| } |
| |
| .lang-icon { |
| width: 40px; |
| height: 40px; |
| border-radius: 10px; |
| border: 1px solid var(--border); |
| background: var(--bg-dark); |
| color: var(--text-secondary); |
| font-size: 12px; |
| font-weight: 600; |
| cursor: pointer; |
| transition: var(--transition); |
| } |
| |
| .lang-icon:hover { |
| border-color: var(--primary); |
| color: var(--primary); |
| transform: translateY(-2px); |
| } |
| |
| .lang-icon.active { |
| background: var(--primary); |
| color: var(--bg-dark); |
| border-color: var(--primary); |
| } |
| |
| .primary-button { |
| background: linear-gradient(135deg, var(--primary), #0099cc); |
| color: var(--bg-dark); |
| border: none; |
| padding: 14px 28px; |
| border-radius: 12px; |
| font-weight: 700; |
| font-size: 15px; |
| cursor: pointer; |
| transition: var(--transition); |
| display: inline-flex; |
| align-items: center; |
| gap: 8px; |
| } |
| |
| .primary-button:hover { |
| transform: translateY(-2px); |
| box-shadow: var(--glow-primary); |
| } |
| |
| .secondary-button { |
| background: var(--bg-hover); |
| color: var(--text-primary); |
| border: 1px solid var(--border); |
| padding: 14px 28px; |
| border-radius: 12px; |
| font-weight: 600; |
| font-size: 15px; |
| cursor: pointer; |
| transition: var(--transition); |
| display: inline-flex; |
| align-items: center; |
| gap: 8px; |
| } |
| |
| .secondary-button:hover { |
| background: var(--border); |
| transform: translateY(-2px); |
| } |
| |
| .accent-button { |
| background: linear-gradient(135deg, var(--accent), #e11d48); |
| color: white; |
| border: none; |
| padding: 14px 28px; |
| border-radius: 12px; |
| font-weight: 700; |
| font-size: 15px; |
| cursor: pointer; |
| transition: var(--transition); |
| display: inline-flex; |
| align-items: center; |
| gap: 8px; |
| } |
| |
| .accent-button:hover { |
| transform: translateY(-2px); |
| box-shadow: 0 0 20px rgba(244,63,94,0.3); |
| } |
| |
| .success-button { |
| background: linear-gradient(135deg, var(--success), #16a34a); |
| color: white; |
| border: none; |
| padding: 14px 28px; |
| border-radius: 12px; |
| font-weight: 700; |
| font-size: 15px; |
| cursor: pointer; |
| transition: var(--transition); |
| display: inline-flex; |
| align-items: center; |
| gap: 8px; |
| } |
| |
| .success-button:hover { |
| transform: translateY(-2px); |
| box-shadow: 0 0 20px rgba(34,197,94,0.3); |
| } |
| |
| .primary-button.full, .secondary-button.full, .accent-button.full, .success-button.full { |
| width: 100%; |
| justify-content: center; |
| } |
| |
| .primary-button.small, .secondary-button.small { |
| padding: 8px 16px; |
| font-size: 13px; |
| } |
| |
| .dashboard-grid { |
| display: grid; |
| grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); |
| gap: 20px; |
| margin-bottom: 32px; |
| } |
| |
| .dash-card { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 16px; |
| padding: 24px; |
| cursor: pointer; |
| transition: var(--transition); |
| position: relative; |
| overflow: hidden; |
| } |
| |
| .dash-card::after { |
| content: ""; |
| position: absolute; |
| top: 0; |
| left: 0; |
| width: 100%; |
| height: 3px; |
| background: linear-gradient(90deg, var(--primary), var(--secondary)); |
| transform: scaleX(0); |
| transition: transform 0.3s; |
| } |
| |
| .dash-card:hover { |
| transform: translateY(-4px); |
| box-shadow: var(--shadow); |
| border-color: var(--border); |
| } |
| |
| .dash-card:hover::after { |
| transform: scaleX(1); |
| } |
| |
| .dash-card.primary::after { background: linear-gradient(90deg, var(--primary), #0099cc); } |
| .dash-card.secondary::after { background: linear-gradient(90deg, var(--secondary), #7c3aed); } |
| .dash-card.accent::after { background: linear-gradient(90deg, var(--accent), #e11d48); } |
| .dash-card.success::after { background: linear-gradient(90deg, var(--success), #16a34a); } |
| |
| .card-icon { |
| width: 48px; |
| height: 48px; |
| border-radius: 12px; |
| background: var(--bg-hover); |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| font-size: 20px; |
| color: var(--primary); |
| margin-bottom: 16px; |
| } |
| |
| .dash-card h3 { |
| font-size: 16px; |
| font-weight: 700; |
| margin-bottom: 4px; |
| } |
| |
| .dash-card p { |
| color: var(--text-secondary); |
| font-size: 13px; |
| } |
| |
| .badge, .stat { |
| position: absolute; |
| top: 16px; |
| right: 16px; |
| padding: 4px 10px; |
| border-radius: 20px; |
| font-size: 11px; |
| font-weight: 700; |
| } |
| |
| .badge { |
| background: var(--primary); |
| color: var(--bg-dark); |
| } |
| |
| .stat { |
| background: var(--bg-hover); |
| color: var(--text-secondary); |
| } |
| |
| .quick-stats { |
| display: grid; |
| grid-template-columns: repeat(4, 1fr); |
| gap: 20px; |
| } |
| |
| .stat-item { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 12px; |
| padding: 20px; |
| text-align: center; |
| transition: var(--transition); |
| } |
| |
| .stat-item:hover { |
| transform: translateY(-2px); |
| border-color: var(--primary); |
| } |
| |
| .stat-value { |
| font-size: 28px; |
| font-weight: 800; |
| background: linear-gradient(135deg, var(--primary), var(--secondary)); |
| -webkit-background-clip: text; |
| -webkit-text-fill-color: transparent; |
| margin-bottom: 4px; |
| } |
| |
| .stat-label { |
| color: var(--text-secondary); |
| font-size: 13px; |
| } |
| |
| .action-bar { |
| display: flex; |
| gap: 12px; |
| margin-bottom: 32px; |
| flex-wrap: wrap; |
| } |
| |
| .deck-grid { |
| display: grid; |
| grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); |
| gap: 20px; |
| margin-bottom: 32px; |
| } |
| |
| .deck-card { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 16px; |
| padding: 24px; |
| cursor: pointer; |
| transition: var(--transition); |
| } |
| |
| .deck-card:hover { |
| transform: translateY(-4px); |
| box-shadow: var(--shadow); |
| border-color: var(--primary); |
| } |
| |
| .deck-card.new { |
| border-style: dashed; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| } |
| |
| .add-deck { |
| text-align: center; |
| color: var(--text-secondary); |
| } |
| |
| .add-deck i { |
| font-size: 40px; |
| margin-bottom: 12px; |
| color: var(--primary); |
| } |
| |
| .deck-header { |
| display: flex; |
| justify-content: space-between; |
| align-items: center; |
| margin-bottom: 12px; |
| } |
| |
| .deck-header h3 { |
| font-size: 18px; |
| font-weight: 700; |
| } |
| |
| .mastery-badge { |
| padding: 4px 12px; |
| border-radius: 20px; |
| font-size: 12px; |
| font-weight: 700; |
| } |
| |
| .mastery-badge.high { background: rgba(34,197,94,0.2); color: var(--success); } |
| .mastery-badge.medium { background: rgba(245,158,11,0.2); color: var(--warning); } |
| .mastery-badge.low { background: rgba(244,63,94,0.2); color: var(--accent); } |
| |
| .deck-meta { |
| color: var(--text-secondary); |
| font-size: 13px; |
| margin-bottom: 16px; |
| } |
| |
| .deck-progress { |
| height: 6px; |
| background: var(--bg-hover); |
| border-radius: 3px; |
| margin-bottom: 16px; |
| overflow: hidden; |
| } |
| |
| .progress-bar { |
| height: 100%; |
| background: linear-gradient(90deg, var(--primary), var(--secondary)); |
| border-radius: 3px; |
| transition: width 0.5s ease; |
| } |
| |
| .deck-actions { |
| display: flex; |
| gap: 8px; |
| } |
| |
| .mini-btn { |
| flex: 1; |
| padding: 10px; |
| border-radius: 8px; |
| border: 1px solid var(--border); |
| background: var(--bg-hover); |
| color: var(--text-secondary); |
| font-size: 13px; |
| font-weight: 600; |
| cursor: pointer; |
| transition: var(--transition); |
| } |
| |
| .mini-btn:hover { |
| background: var(--border); |
| color: var(--text-primary); |
| } |
| |
| .mini-btn.primary { |
| background: var(--primary); |
| color: var(--bg-dark); |
| border-color: var(--primary); |
| } |
| |
| .feature-box { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 16px; |
| padding: 24px; |
| margin-bottom: 24px; |
| } |
| |
| .feature-box h3 { |
| font-size: 16px; |
| font-weight: 700; |
| margin-bottom: 12px; |
| display: flex; |
| align-items: center; |
| gap: 8px; |
| } |
| |
| .feature-box h3 i { |
| color: var(--primary); |
| } |
| |
| .stat-card { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 16px; |
| padding: 24px; |
| transition: var(--transition); |
| } |
| |
| .stat-card:hover { |
| transform: translateY(-4px); |
| border-color: var(--primary); |
| } |
| |
| .grid-2 { |
| display: grid; |
| grid-template-columns: repeat(2, 1fr); |
| gap: 20px; |
| margin-bottom: 24px; |
| } |
| |
| .grid-4 { |
| display: grid; |
| grid-template-columns: repeat(4, 1fr); |
| gap: 20px; |
| margin-bottom: 24px; |
| } |
| |
| .tutor-container { |
| display: grid; |
| grid-template-columns: 1fr 300px; |
| gap: 24px; |
| } |
| |
| .chat-area { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 16px; |
| overflow: hidden; |
| display: flex; |
| flex-direction: column; |
| height: 600px; |
| } |
| |
| .chat-messages { |
| flex: 1; |
| overflow-y: auto; |
| padding: 24px; |
| display: flex; |
| flex-direction: column; |
| gap: 16px; |
| } |
| |
| .message { |
| display: flex; |
| gap: 12px; |
| max-width: 85%; |
| } |
| |
| .ai-message { |
| align-self: flex-start; |
| } |
| |
| .message-avatar { |
| width: 36px; |
| height: 36px; |
| border-radius: 50%; |
| background: linear-gradient(135deg, var(--primary), var(--secondary)); |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| color: white; |
| font-size: 14px; |
| flex-shrink: 0; |
| } |
| |
| .message-content { |
| background: var(--bg-hover); |
| padding: 16px; |
| border-radius: 12px; |
| border-bottom-left-radius: 4px; |
| } |
| |
| .message-content p { |
| margin-bottom: 8px; |
| line-height: 1.6; |
| } |
| |
| .message-content ul { |
| margin: 12px 0; |
| padding-left: 20px; |
| color: var(--text-secondary); |
| } |
| |
| .message-content li { |
| margin: 4px 0; |
| } |
| |
| .chat-input-area { |
| padding: 16px; |
| border-top: 1px solid var(--border); |
| display: flex; |
| gap: 12px; |
| align-items: center; |
| } |
| |
| .attach-btn { |
| width: 44px; |
| height: 44px; |
| border-radius: 12px; |
| border: 1px solid var(--border); |
| background: var(--bg-hover); |
| color: var(--text-secondary); |
| cursor: pointer; |
| transition: var(--transition); |
| } |
| |
| .attach-btn:hover { |
| border-color: var(--primary); |
| color: var(--primary); |
| } |
| |
| .chat-input { |
| flex: 1; |
| background: var(--bg-dark); |
| border: 1px solid var(--border); |
| padding: 12px 16px; |
| border-radius: 12px; |
| color: var(--text-primary); |
| font-size: 14px; |
| } |
| |
| .chat-input:focus { |
| outline: none; |
| border-color: var(--primary); |
| } |
| |
| .send-btn { |
| width: 44px; |
| height: 44px; |
| border-radius: 12px; |
| border: none; |
| background: var(--primary); |
| color: var(--bg-dark); |
| cursor: pointer; |
| transition: var(--transition); |
| } |
| |
| .send-btn:hover { |
| transform: scale(1.05); |
| box-shadow: var(--glow-primary); |
| } |
| |
| .tutor-sidebar { |
| display: flex; |
| flex-direction: column; |
| gap: 20px; |
| } |
| |
| .sidebar-section { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 16px; |
| padding: 20px; |
| } |
| |
| .sidebar-section h4 { |
| font-size: 13px; |
| font-weight: 700; |
| text-transform: uppercase; |
| letter-spacing: 1px; |
| color: var(--text-secondary); |
| margin-bottom: 12px; |
| } |
| |
| .quick-action { |
| width: 100%; |
| padding: 12px; |
| margin: 4px 0; |
| border-radius: 10px; |
| border: 1px solid var(--border); |
| background: var(--bg-hover); |
| color: var(--text-secondary); |
| font-size: 13px; |
| cursor: pointer; |
| transition: var(--transition); |
| display: flex; |
| align-items: center; |
| gap: 10px; |
| } |
| |
| .quick-action:hover { |
| border-color: var(--primary); |
| color: var(--primary); |
| transform: translateX(4px); |
| } |
| |
| .quick-action i { |
| color: var(--primary); |
| } |
| |
| .file-list { |
| font-size: 13px; |
| color: var(--text-secondary); |
| } |
| |
| .empty-state { |
| text-align: center; |
| padding: 20px; |
| color: var(--text-secondary); |
| } |
| |
| .generator-panel { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 16px; |
| padding: 24px; |
| margin-bottom: 24px; |
| } |
| |
| .input-row { |
| display: flex; |
| gap: 16px; |
| align-items: flex-end; |
| flex-wrap: wrap; |
| } |
| |
| .input-group { |
| flex: 1; |
| min-width: 150px; |
| } |
| |
| .input-group label { |
| display: block; |
| font-size: 12px; |
| font-weight: 600; |
| color: var(--text-secondary); |
| margin-bottom: 6px; |
| text-transform: uppercase; |
| letter-spacing: 0.5px; |
| } |
| |
| .question-list { |
| display: flex; |
| flex-direction: column; |
| gap: 16px; |
| } |
| |
| .practice-question { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 16px; |
| padding: 24px; |
| transition: var(--transition); |
| } |
| |
| .practice-question:hover { |
| border-color: var(--border); |
| box-shadow: var(--shadow); |
| } |
| |
| .question-header { |
| display: flex; |
| gap: 12px; |
| align-items: center; |
| margin-bottom: 16px; |
| } |
| |
| .question-number { |
| padding: 4px 12px; |
| background: var(--primary); |
| color: var(--bg-dark); |
| border-radius: 20px; |
| font-size: 12px; |
| font-weight: 700; |
| } |
| |
| .difficulty-badge { |
| padding: 4px 10px; |
| border-radius: 20px; |
| font-size: 11px; |
| font-weight: 600; |
| text-transform: uppercase; |
| } |
| |
| .difficulty-badge.easy { background: rgba(34,197,94,0.2); color: var(--success); } |
| .difficulty-badge.medium { background: rgba(245,158,11,0.2); color: var(--warning); } |
| .difficulty-badge.hard { background: rgba(244,63,94,0.2); color: var(--accent); } |
| |
| .question-text { |
| font-size: 16px; |
| line-height: 1.6; |
| margin-bottom: 20px; |
| } |
| |
| .answer-options { |
| display: grid; |
| grid-template-columns: repeat(2, 1fr); |
| gap: 12px; |
| } |
| |
| .option-btn { |
| padding: 16px; |
| background: var(--bg-hover); |
| border: 2px solid var(--border); |
| border-radius: 12px; |
| color: var(--text-primary); |
| font-size: 14px; |
| cursor: pointer; |
| transition: var(--transition); |
| text-align: left; |
| } |
| |
| .option-btn:hover { |
| border-color: var(--primary); |
| background: rgba(0,212,255,0.1); |
| } |
| |
| .option-btn.selected { |
| border-color: var(--primary); |
| background: rgba(0,212,255,0.15); |
| } |
| |
| .answer-section { |
| margin: 20px 0; |
| } |
| |
| .answer-content { |
| background: var(--bg-hover); |
| padding: 20px; |
| border-radius: 12px; |
| margin-top: 12px; |
| line-height: 1.6; |
| } |
| |
| .answer-content.hidden { |
| display: none; |
| } |
| |
| .answer-content p { |
| margin-bottom: 12px; |
| } |
| |
| .feedback-buttons { |
| display: flex; |
| gap: 12px; |
| } |
| |
| .feedback-btn { |
| flex: 1; |
| padding: 12px; |
| border-radius: 10px; |
| border: 1px solid var(--border); |
| background: var(--bg-hover); |
| color: var(--text-secondary); |
| font-size: 13px; |
| cursor: pointer; |
| transition: var(--transition); |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| gap: 8px; |
| } |
| |
| .feedback-btn:hover { |
| transform: translateY(-2px); |
| } |
| |
| .feedback-btn.correct:hover { |
| background: rgba(34,197,94,0.1); |
| border-color: var(--success); |
| color: var(--success); |
| } |
| |
| .feedback-btn.wrong:hover { |
| background: rgba(244,63,94,0.1); |
| border-color: var(--accent); |
| color: var(--accent); |
| } |
| |
| .export-options { |
| display: grid; |
| grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); |
| gap: 20px; |
| margin-bottom: 32px; |
| } |
| |
| .export-card { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 16px; |
| padding: 24px; |
| text-align: center; |
| transition: var(--transition); |
| position: relative; |
| } |
| |
| .export-card:hover { |
| transform: translateY(-4px); |
| border-color: var(--primary); |
| } |
| |
| .export-card.featured { |
| border-color: var(--warning); |
| background: linear-gradient(135deg, rgba(245,158,11,0.05), transparent); |
| } |
| |
| .export-icon { |
| width: 56px; |
| height: 56px; |
| border-radius: 16px; |
| background: var(--bg-hover); |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| margin: 0 auto 16px; |
| font-size: 24px; |
| color: var(--warning); |
| } |
| |
| .export-card h3 { |
| font-size: 16px; |
| margin-bottom: 8px; |
| } |
| |
| .export-card p { |
| color: var(--text-secondary); |
| font-size: 13px; |
| margin-bottom: 20px; |
| } |
| |
| .plan-badge { |
| position: absolute; |
| top: 12px; |
| right: 12px; |
| padding: 4px 10px; |
| background: var(--warning); |
| color: var(--bg-dark); |
| border-radius: 20px; |
| font-size: 10px; |
| font-weight: 700; |
| text-transform: uppercase; |
| } |
| |
| .export-settings { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 16px; |
| padding: 24px; |
| } |
| |
| .export-settings h3 { |
| margin-bottom: 20px; |
| } |
| |
| .settings-row { |
| display: flex; |
| flex-wrap: wrap; |
| gap: 20px; |
| } |
| |
| .toggle-label { |
| display: flex; |
| align-items: center; |
| gap: 12px; |
| cursor: pointer; |
| font-size: 14px; |
| color: var(--text-secondary); |
| } |
| |
| .toggle-label input { |
| display: none; |
| } |
| |
| .toggle { |
| width: 44px; |
| height: 24px; |
| background: var(--bg-hover); |
| border-radius: 12px; |
| position: relative; |
| transition: var(--transition); |
| flex-shrink: 0; |
| } |
| |
| .toggle::after { |
| content: ""; |
| position: absolute; |
| width: 20px; |
| height: 20px; |
| background: white; |
| border-radius: 50%; |
| top: 2px; |
| left: 2px; |
| transition: var(--transition); |
| } |
| |
| .toggle-label input:checked + .toggle { |
| background: var(--primary); |
| } |
| |
| .toggle-label input:checked + .toggle::after { |
| left: 22px; |
| } |
| |
| .solver-container { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 16px; |
| padding: 24px; |
| } |
| |
| .input-methods { |
| display: flex; |
| gap: 12px; |
| margin-bottom: 24px; |
| border-bottom: 1px solid var(--border); |
| padding-bottom: 20px; |
| } |
| |
| .input-method { |
| flex: 1; |
| padding: 16px; |
| border-radius: 12px; |
| border: 2px solid var(--border); |
| background: var(--bg-hover); |
| color: var(--text-secondary); |
| cursor: pointer; |
| transition: var(--transition); |
| text-align: center; |
| } |
| |
| .input-method:hover { |
| border-color: var(--border); |
| color: var(--text-primary); |
| } |
| |
| .input-method.active { |
| border-color: var(--primary); |
| background: rgba(0,212,255,0.1); |
| color: var(--primary); |
| } |
| |
| .input-method i { |
| display: block; |
| font-size: 24px; |
| margin-bottom: 8px; |
| } |
| |
| .solver-workspace { |
| position: relative; |
| } |
| |
| .solver-panel { |
| display: none; |
| } |
| |
| .solver-panel.active { |
| display: block; |
| } |
| |
| .upload-zone { |
| border: 2px dashed var(--border); |
| border-radius: 16px; |
| padding: 60px 40px; |
| text-align: center; |
| cursor: pointer; |
| transition: var(--transition); |
| } |
| |
| .upload-zone:hover { |
| border-color: var(--primary); |
| background: rgba(0,212,255,0.05); |
| } |
| |
| .upload-zone i { |
| font-size: 48px; |
| color: var(--primary); |
| margin-bottom: 16px; |
| } |
| |
| .upload-zone p { |
| margin-bottom: 8px; |
| } |
| |
| .formats { |
| color: var(--text-secondary); |
| font-size: 13px; |
| } |
| |
| .solver-textarea { |
| width: 100%; |
| min-height: 200px; |
| background: var(--bg-dark); |
| border: 1px solid var(--border); |
| border-radius: 12px; |
| padding: 16px; |
| color: var(--text-primary); |
| font-size: 15px; |
| resize: vertical; |
| } |
| |
| .solver-textarea:focus { |
| outline: none; |
| border-color: var(--primary); |
| } |
| |
| .math-toolbar { |
| display: flex; |
| gap: 8px; |
| margin-top: 12px; |
| flex-wrap: wrap; |
| } |
| |
| .math-toolbar button { |
| padding: 8px 14px; |
| background: var(--bg-hover); |
| border: 1px solid var(--border); |
| border-radius: 8px; |
| color: var(--text-secondary); |
| font-size: 13px; |
| cursor: pointer; |
| transition: var(--transition); |
| } |
| |
| .math-toolbar button:hover { |
| border-color: var(--primary); |
| color: var(--primary); |
| } |
| |
| .solve-button { |
| width: 100%; |
| padding: 16px; |
| margin-top: 20px; |
| background: linear-gradient(135deg, var(--primary), var(--secondary)); |
| border: none; |
| border-radius: 12px; |
| color: var(--bg-dark); |
| font-size: 16px; |
| font-weight: 700; |
| cursor: pointer; |
| transition: var(--transition); |
| } |
| |
| .solve-button:hover { |
| transform: translateY(-2px); |
| box-shadow: var(--glow-primary); |
| } |
| |
| .solution-result { |
| margin-top: 24px; |
| padding: 24px; |
| background: var(--bg-hover); |
| border-radius: 12px; |
| border-left: 4px solid var(--success); |
| } |
| |
| .solution-header { |
| margin-bottom: 16px; |
| } |
| |
| .solution-badge { |
| padding: 6px 12px; |
| background: rgba(34,197,94,0.2); |
| color: var(--success); |
| border-radius: 20px; |
| font-size: 12px; |
| font-weight: 600; |
| } |
| |
| .solution-steps { |
| display: flex; |
| flex-direction: column; |
| gap: 12px; |
| } |
| |
| .step { |
| display: flex; |
| gap: 16px; |
| align-items: flex-start; |
| } |
| |
| .step-num { |
| width: 28px; |
| height: 28px; |
| background: var(--primary); |
| color: var(--bg-dark); |
| border-radius: 50%; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| font-size: 12px; |
| font-weight: 700; |
| flex-shrink: 0; |
| } |
| |
| .step p { |
| flex: 1; |
| line-height: 1.6; |
| } |
| |
| .settings-layout { |
| display: grid; |
| grid-template-columns: 240px 1fr; |
| gap: 24px; |
| } |
| |
| .settings-nav { |
| display: flex; |
| flex-direction: column; |
| gap: 4px; |
| } |
| |
| .settings-tab { |
| padding: 14px 16px; |
| border-radius: 12px; |
| border: none; |
| background: transparent; |
| color: var(--text-secondary); |
| font-size: 14px; |
| cursor: pointer; |
| transition: var(--transition); |
| display: flex; |
| align-items: center; |
| gap: 12px; |
| text-align: left; |
| } |
| |
| .settings-tab:hover { |
| background: var(--bg-hover); |
| color: var(--text-primary); |
| } |
| |
| .settings-tab.active { |
| background: var(--primary); |
| color: var(--bg-dark); |
| font-weight: 600; |
| } |
| |
| .settings-content { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 16px; |
| padding: 32px; |
| } |
| |
| .settings-panel { |
| display: none; |
| } |
| |
| .settings-panel.active { |
| display: block; |
| } |
| |
| .settings-panel h3 { |
| font-size: 18px; |
| margin-bottom: 24px; |
| padding-bottom: 16px; |
| border-bottom: 1px solid var(--border); |
| } |
| |
| .profile-header { |
| display: flex; |
| gap: 24px; |
| margin-bottom: 32px; |
| } |
| |
| .avatar-upload { |
| text-align: center; |
| } |
| |
| .avatar-preview { |
| width: 100px; |
| height: 100px; |
| border-radius: 50%; |
| background: linear-gradient(135deg, var(--primary), var(--secondary)); |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| margin-bottom: 12px; |
| } |
| |
| .avatar-preview i { |
| font-size: 40px; |
| color: white; |
| } |
| |
| .profile-fields { |
| flex: 1; |
| display: flex; |
| flex-direction: column; |
| gap: 16px; |
| } |
| |
| .field label { |
| display: block; |
| font-size: 12px; |
| font-weight: 600; |
| color: var(--text-secondary); |
| margin-bottom: 6px; |
| text-transform: uppercase; |
| letter-spacing: 0.5px; |
| } |
| |
| .theme-options { |
| display: flex; |
| gap: 16px; |
| margin-bottom: 32px; |
| } |
| |
| .theme-option { |
| cursor: pointer; |
| text-align: center; |
| } |
| |
| .theme-preview { |
| width: 80px; |
| height: 60px; |
| border-radius: 12px; |
| border: 2px solid var(--border); |
| margin-bottom: 8px; |
| transition: var(--transition); |
| } |
| |
| .theme-preview.dark { |
| background: linear-gradient(135deg, #1a1a2e, #0a0a0f); |
| } |
| |
| .theme-preview.light { |
| background: linear-gradient(135deg, #f8fafc, #e2e8f0); |
| } |
| |
| .theme-preview.auto { |
| background: linear-gradient(90deg, #1a1a2e 50%, #f8fafc 50%); |
| } |
| |
| .theme-option:hover .theme-preview { |
| border-color: var(--primary); |
| } |
| |
| .theme-option.active .theme-preview { |
| border-color: var(--primary); |
| box-shadow: var(--glow-primary); |
| } |
| |
| .slider-setting { |
| margin-bottom: 24px; |
| } |
| |
| .slider-setting label { |
| display: block; |
| margin-bottom: 12px; |
| font-weight: 500; |
| } |
| |
| .modern-slider { |
| width: 100%; |
| height: 6px; |
| background: var(--bg-hover); |
| border-radius: 3px; |
| outline: none; |
| -webkit-appearance: none; |
| } |
| |
| .modern-slider::-webkit-slider-thumb { |
| -webkit-appearance: none; |
| width: 18px; |
| height: 18px; |
| background: var(--primary); |
| border-radius: 50%; |
| cursor: pointer; |
| } |
| |
| .language-grid { |
| display: grid; |
| grid-template-columns: repeat(4, 1fr); |
| gap: 12px; |
| } |
| |
| .lang-btn { |
| padding: 12px; |
| border-radius: 10px; |
| border: 1px solid var(--border); |
| background: var(--bg-hover); |
| color: var(--text-secondary); |
| font-size: 13px; |
| cursor: pointer; |
| transition: var(--transition); |
| } |
| |
| .lang-btn:hover { |
| border-color: var(--primary); |
| color: var(--primary); |
| } |
| |
| .lang-btn.active { |
| background: var(--primary); |
| color: var(--bg-dark); |
| border-color: var(--primary); |
| font-weight: 600; |
| } |
| |
| .settings-footer { |
| display: flex; |
| justify-content: space-between; |
| margin-top: 32px; |
| padding-top: 24px; |
| border-top: 1px solid var(--border); |
| } |
| |
| .pricing-toggle { |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| gap: 16px; |
| margin-bottom: 40px; |
| } |
| |
| .pricing-toggle span { |
| color: var(--text-secondary); |
| font-weight: 500; |
| } |
| |
| .pricing-toggle span.active { |
| color: var(--text-primary); |
| } |
| |
| .switch { |
| position: relative; |
| width: 56px; |
| height: 28px; |
| } |
| |
| .switch input { |
| opacity: 0; |
| width: 0; |
| height: 0; |
| } |
| |
| .slider { |
| position: absolute; |
| cursor: pointer; |
| inset: 0; |
| background: var(--bg-hover); |
| border-radius: 28px; |
| transition: var(--transition); |
| } |
| |
| .slider::before { |
| content: ""; |
| position: absolute; |
| height: 22px; |
| width: 22px; |
| left: 3px; |
| bottom: 3px; |
| background: white; |
| border-radius: 50%; |
| transition: var(--transition); |
| } |
| |
| input:checked + .slider { |
| background: var(--primary); |
| } |
| |
| input:checked + .slider::before { |
| transform: translateX(28px); |
| } |
| |
| .save-badge { |
| padding: 4px 10px; |
| background: var(--success); |
| color: var(--bg-dark); |
| border-radius: 20px; |
| font-size: 11px; |
| font-weight: 700; |
| margin-left: 8px; |
| } |
| |
| .pricing-grid { |
| display: grid; |
| grid-template-columns: repeat(3, 1fr); |
| gap: 24px; |
| margin-bottom: 40px; |
| } |
| |
| .pricing-card { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 20px; |
| padding: 32px 24px; |
| position: relative; |
| transition: var(--transition); |
| } |
| |
| .pricing-card:hover { |
| transform: translateY(-4px); |
| box-shadow: var(--shadow); |
| } |
| |
| .pricing-card.popular { |
| border-color: var(--primary); |
| box-shadow: var(--glow-primary); |
| } |
| |
| .popular-badge { |
| position: absolute; |
| top: -12px; |
| left: 50%; |
| transform: translateX(-50%); |
| padding: 6px 16px; |
| background: var(--primary); |
| color: var(--bg-dark); |
| border-radius: 20px; |
| font-size: 12px; |
| font-weight: 700; |
| } |
| |
| .plan-header { |
| text-align: center; |
| margin-bottom: 24px; |
| } |
| |
| .plan-header h3 { |
| font-size: 20px; |
| margin-bottom: 8px; |
| } |
| |
| .price { |
| font-size: 36px; |
| font-weight: 800; |
| background: linear-gradient(135deg, var(--primary), var(--secondary)); |
| -webkit-background-clip: text; |
| -webkit-text-fill-color: transparent; |
| } |
| |
| .price span { |
| font-size: 14px; |
| color: var(--text-secondary); |
| font-weight: 400; |
| -webkit-text-fill-color: var(--text-secondary); |
| } |
| |
| .features { |
| list-style: none; |
| margin-bottom: 24px; |
| } |
| |
| .features li { |
| padding: 10px 0; |
| font-size: 14px; |
| display: flex; |
| align-items: center; |
| gap: 10px; |
| } |
| |
| .features li i { |
| color: var(--success); |
| } |
| |
| .features li.disabled { |
| color: var(--text-secondary); |
| opacity: 0.5; |
| } |
| |
| .features li.disabled i { |
| color: var(--text-secondary); |
| } |
| |
| .payment-methods { |
| text-align: center; |
| } |
| |
| .payment-methods h3 { |
| margin-bottom: 20px; |
| font-size: 16px; |
| } |
| |
| .payment-icons { |
| display: flex; |
| justify-content: center; |
| gap: 24px; |
| flex-wrap: wrap; |
| } |
| |
| .payment-icon { |
| display: flex; |
| align-items: center; |
| gap: 8px; |
| color: var(--text-secondary); |
| font-size: 14px; |
| } |
| |
| .payment-icon i { |
| font-size: 24px; |
| } |
| |
| .file-toolbar { |
| display: flex; |
| justify-content: space-between; |
| align-items: center; |
| margin-bottom: 24px; |
| flex-wrap: wrap; |
| gap: 16px; |
| } |
| |
| .file-filters { |
| display: flex; |
| gap: 8px; |
| } |
| |
| .filter-btn { |
| padding: 8px 16px; |
| border-radius: 8px; |
| border: 1px solid var(--border); |
| background: var(--bg-hover); |
| color: var(--text-secondary); |
| font-size: 13px; |
| cursor: pointer; |
| transition: var(--transition); |
| } |
| |
| .filter-btn:hover, .filter-btn.active { |
| background: var(--primary); |
| color: var(--bg-dark); |
| border-color: var(--primary); |
| } |
| |
| .storage-indicator { |
| display: flex; |
| align-items: center; |
| gap: 12px; |
| font-size: 13px; |
| color: var(--text-secondary); |
| } |
| |
| .storage-bar { |
| width: 100px; |
| height: 6px; |
| background: var(--bg-hover); |
| border-radius: 3px; |
| overflow: hidden; |
| } |
| |
| .storage-bar div { |
| height: 100%; |
| background: linear-gradient(90deg, var(--primary), var(--secondary)); |
| border-radius: 3px; |
| transition: width 0.3s; |
| } |
| |
| .file-grid { |
| display: flex; |
| flex-direction: column; |
| gap: 12px; |
| } |
| |
| .file-item { |
| display: flex; |
| align-items: center; |
| gap: 16px; |
| padding: 16px 20px; |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 12px; |
| transition: var(--transition); |
| } |
| |
| .file-item:hover { |
| border-color: var(--primary); |
| transform: translateX(4px); |
| } |
| |
| .file-icon { |
| width: 44px; |
| height: 44px; |
| border-radius: 10px; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| font-size: 18px; |
| } |
| |
| .file-icon.pdf { background: rgba(239,68,68,0.1); color: #ef4444; } |
| .file-icon.docx { background: rgba(59,130,246,0.1); color: #3b82f6; } |
| .file-icon.pptx { background: rgba(249,115,22,0.1); color: #f97316; } |
| .file-icon.image { background: rgba(34,197,94,0.1); color: #22c55e; } |
| |
| .file-info { |
| flex: 1; |
| } |
| |
| .file-info h4 { |
| font-size: 14px; |
| font-weight: 600; |
| margin-bottom: 4px; |
| } |
| |
| .file-meta { |
| font-size: 12px; |
| color: var(--text-secondary); |
| } |
| |
| .file-actions { |
| display: flex; |
| gap: 8px; |
| } |
| |
| .file-actions button { |
| width: 36px; |
| height: 36px; |
| border-radius: 8px; |
| border: 1px solid var(--border); |
| background: var(--bg-hover); |
| color: var(--text-secondary); |
| cursor: pointer; |
| transition: var(--transition); |
| } |
| |
| .file-actions button:hover { |
| border-color: var(--primary); |
| color: var(--primary); |
| transform: translateY(-2px); |
| } |
| |
| .blog-grid { |
| display: grid; |
| grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); |
| gap: 24px; |
| } |
| |
| .blog-card { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 16px; |
| overflow: hidden; |
| transition: var(--transition); |
| cursor: pointer; |
| } |
| |
| .blog-card:hover { |
| transform: translateY(-4px); |
| box-shadow: var(--shadow); |
| border-color: var(--primary); |
| } |
| |
| .blog-image { |
| height: 160px; |
| background: linear-gradient(135deg, var(--primary), var(--secondary)); |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| font-size: 48px; |
| color: white; |
| } |
| |
| .blog-content { |
| padding: 20px; |
| } |
| |
| .blog-tag { |
| display: inline-block; |
| padding: 4px 10px; |
| background: var(--bg-hover); |
| color: var(--primary); |
| border-radius: 20px; |
| font-size: 11px; |
| font-weight: 600; |
| text-transform: uppercase; |
| margin-bottom: 12px; |
| } |
| |
| .blog-content h3 { |
| font-size: 16px; |
| margin-bottom: 8px; |
| } |
| |
| .blog-content p { |
| color: var(--text-secondary); |
| font-size: 14px; |
| line-height: 1.5; |
| margin-bottom: 12px; |
| } |
| |
| .blog-date { |
| font-size: 12px; |
| color: var(--text-secondary); |
| } |
| |
| .error-page { |
| text-align: center; |
| padding: 80px 20px; |
| } |
| |
| .error-page h1 { |
| font-size: 48px; |
| margin-bottom: 16px; |
| } |
| |
| @media (max-width: 1024px) { |
| .sidebar { |
| width: 80px; |
| padding: 20px 12px; |
| } |
| |
| .nav-brand span, .nav-link span, .nav-label { |
| display: none; |
| } |
| |
| .nav-brand { |
| justify-content: center; |
| } |
| |
| .nav-link { |
| justify-content: center; |
| padding: 16px; |
| } |
| |
| .nav-link::before { |
| width: 100%; |
| height: 3px; |
| transform: scaleX(0); |
| } |
| |
| .content-main { |
| margin-left: 80px; |
| } |
| |
| .tutor-container { |
| grid-template-columns: 1fr; |
| } |
| |
| .tutor-sidebar { |
| display: none; |
| } |
| |
| .settings-layout { |
| grid-template-columns: 1fr; |
| } |
| |
| .settings-nav { |
| flex-direction: row; |
| overflow-x: auto; |
| padding-bottom: 8px; |
| } |
| |
| .pricing-grid { |
| grid-template-columns: 1fr; |
| } |
| |
| .quick-stats { |
| grid-template-columns: repeat(2, 1fr); |
| } |
| } |
| |
| @media (max-width: 640px) { |
| .sidebar { |
| width: 100%; |
| height: 70px; |
| position: fixed; |
| bottom: 0; |
| top: auto; |
| flex-direction: row; |
| padding: 8px; |
| border-right: none; |
| border-top: 1px solid var(--border); |
| } |
| |
| .nav-brand, .nav-label { |
| display: none; |
| } |
| |
| .nav-section { |
| display: flex; |
| margin: 0; |
| } |
| |
| .content-main { |
| margin-left: 0; |
| margin-bottom: 70px; |
| padding: 20px; |
| } |
| |
| .dashboard-grid { |
| grid-template-columns: 1fr; |
| } |
| |
| .quick-stats { |
| grid-template-columns: 1fr; |
| } |
| |
| .language-grid { |
| grid-template-columns: repeat(2, 1fr); |
| } |
| |
| .grid-2, .grid-4 { |
| grid-template-columns: 1fr; |
| } |
| } |
| |
| /* YouTube Converter Styles */ |
| .youtube-converter { max-width: 900px; } |
| |
| .url-input-wrapper { |
| display: flex; |
| gap: 12px; |
| align-items: center; |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 16px; |
| padding: 12px 20px; |
| } |
| |
| .url-input-wrapper i { |
| font-size: 24px; |
| color: #ff0000; |
| } |
| |
| .url-input-wrapper input { |
| flex: 1; |
| background: transparent; |
| border: none; |
| color: var(--text-primary); |
| font-size: 15px; |
| } |
| |
| .url-input-wrapper input:focus { |
| outline: none; |
| } |
| |
| .input-hint { |
| color: var(--text-secondary); |
| font-size: 13px; |
| margin-top: 12px; |
| text-align: center; |
| } |
| |
| .progress-panel { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 16px; |
| padding: 24px; |
| margin-top: 24px; |
| } |
| |
| .progress-panel.hidden, |
| .results-panel.hidden { |
| display: none; |
| } |
| |
| .progress-steps { |
| display: flex; |
| justify-content: space-between; |
| margin-bottom: 24px; |
| } |
| |
| .progress-steps .step { |
| display: flex; |
| flex-direction: column; |
| align-items: center; |
| gap: 8px; |
| color: var(--text-secondary); |
| font-size: 13px; |
| } |
| |
| .progress-steps .step.active { |
| color: var(--primary); |
| } |
| |
| .step-icon { |
| width: 40px; |
| height: 40px; |
| border-radius: 50%; |
| background: var(--bg-hover); |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| font-size: 16px; |
| } |
| |
| .step.active .step-icon { |
| background: var(--primary); |
| color: var(--bg-dark); |
| } |
| |
| .progress-bar-container { |
| height: 6px; |
| background: var(--bg-hover); |
| border-radius: 3px; |
| overflow: hidden; |
| } |
| |
| .progress-bar-fill { |
| height: 100%; |
| width: 0%; |
| background: linear-gradient(90deg, var(--primary), var(--secondary)); |
| border-radius: 3px; |
| transition: width 0.5s ease; |
| } |
| |
| .results-panel { |
| margin-top: 24px; |
| } |
| |
| .video-preview { |
| display: flex; |
| gap: 20px; |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 16px; |
| padding: 20px; |
| margin-bottom: 24px; |
| } |
| |
| .thumbnail { |
| width: 160px; |
| height: 90px; |
| background: var(--bg-hover); |
| border-radius: 12px; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| font-size: 40px; |
| color: var(--primary); |
| flex-shrink: 0; |
| } |
| |
| .video-info h3 { |
| font-size: 18px; |
| margin-bottom: 8px; |
| } |
| |
| .video-info p { |
| color: var(--text-secondary); |
| font-size: 14px; |
| margin-bottom: 12px; |
| } |
| |
| .video-stats { |
| display: flex; |
| gap: 20px; |
| font-size: 13px; |
| color: var(--text-secondary); |
| } |
| |
| .video-stats strong { |
| color: var(--primary); |
| } |
| |
| .output-options h3 { |
| margin-bottom: 16px; |
| } |
| |
| .output-cards { |
| display: grid; |
| grid-template-columns: repeat(4, 1fr); |
| gap: 16px; |
| } |
| |
| .output-card { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 16px; |
| padding: 20px; |
| text-align: center; |
| cursor: pointer; |
| transition: var(--transition); |
| } |
| |
| .output-card:hover { |
| transform: translateY(-4px); |
| border-color: var(--primary); |
| } |
| |
| .output-icon { |
| width: 48px; |
| height: 48px; |
| border-radius: 12px; |
| background: var(--bg-hover); |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| margin: 0 auto 12px; |
| font-size: 20px; |
| color: var(--primary); |
| } |
| |
| .output-card h4 { |
| font-size: 14px; |
| margin-bottom: 8px; |
| } |
| |
| .output-card p { |
| font-size: 13px; |
| color: var(--text-secondary); |
| margin-bottom: 12px; |
| } |
| |
| @media (max-width: 768px) { |
| .output-cards { |
| grid-template-columns: repeat(2, 1fr); |
| } |
| |
| .video-preview { |
| flex-direction: column; |
| } |
| |
| .thumbnail { |
| width: 100%; |
| height: 180px; |
| } |
| |
| .progress-steps { |
| flex-wrap: wrap; |
| gap: 12px; |
| } |
| } |
| |
| /* Quiz Styles */ |
| .quiz-container { |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 20px; |
| padding: 32px; |
| margin-bottom: 32px; |
| } |
| |
| .subject-grid { |
| display: grid; |
| grid-template-columns: repeat(4, 1fr); |
| gap: 12px; |
| margin: 20px 0; |
| } |
| |
| .subject-btn { |
| display: flex; |
| flex-direction: column; |
| align-items: center; |
| gap: 8px; |
| padding: 20px 16px; |
| background: var(--bg-hover); |
| border: 2px solid var(--border); |
| border-radius: 12px; |
| color: var(--text-secondary); |
| font-size: 14px; |
| font-weight: 600; |
| cursor: pointer; |
| transition: var(--transition); |
| } |
| |
| .subject-btn i { |
| font-size: 24px; |
| color: var(--primary); |
| } |
| |
| .subject-btn:hover, .subject-btn.active { |
| border-color: var(--primary); |
| background: rgba(0,212,255,0.1); |
| color: var(--text-primary); |
| } |
| |
| .quiz-options { |
| display: grid; |
| grid-template-columns: repeat(2, 1fr); |
| gap: 20px; |
| margin: 24px 0; |
| } |
| |
| .option-row label { |
| display: block; |
| font-size: 12px; |
| font-weight: 600; |
| color: var(--text-secondary); |
| margin-bottom: 8px; |
| text-transform: uppercase; |
| letter-spacing: 0.5px; |
| } |
| |
| .quiz-progress-bar { |
| height: 6px; |
| background: var(--bg-hover); |
| border-radius: 3px; |
| margin-bottom: 24px; |
| overflow: hidden; |
| } |
| |
| .progress-fill { |
| height: 100%; |
| background: linear-gradient(90deg, var(--primary), var(--secondary)); |
| border-radius: 3px; |
| width: 0%; |
| transition: width 0.3s ease; |
| } |
| |
| .quiz-header { |
| display: flex; |
| justify-content: space-between; |
| align-items: center; |
| margin-bottom: 24px; |
| padding-bottom: 16px; |
| border-bottom: 1px solid var(--border); |
| } |
| |
| .quiz-subject { |
| font-size: 14px; |
| font-weight: 600; |
| color: var(--primary); |
| text-transform: uppercase; |
| letter-spacing: 1px; |
| } |
| |
| .quiz-score { |
| font-size: 14px; |
| color: var(--text-secondary); |
| } |
| |
| .quiz-score strong { |
| color: var(--success); |
| font-size: 18px; |
| } |
| |
| .quiz-question-container { |
| text-align: center; |
| } |
| |
| .question-number { |
| font-size: 13px; |
| color: var(--text-secondary); |
| margin-bottom: 12px; |
| } |
| |
| .question-text { |
| font-size: 22px; |
| font-weight: 600; |
| margin-bottom: 32px; |
| line-height: 1.4; |
| } |
| |
| .quiz-option { |
| width: 100%; |
| padding: 18px 24px; |
| margin: 8px 0; |
| background: var(--bg-hover); |
| border: 2px solid var(--border); |
| border-radius: 12px; |
| color: var(--text-primary); |
| font-size: 16px; |
| cursor: pointer; |
| transition: var(--transition); |
| text-align: left; |
| } |
| |
| .quiz-option:hover { |
| border-color: var(--primary); |
| background: rgba(0,212,255,0.05); |
| transform: translateX(4px); |
| } |
| |
| .quiz-option.correct { |
| background: rgba(34,197,94,0.2); |
| border-color: var(--success); |
| color: var(--success); |
| } |
| |
| .quiz-option.incorrect { |
| background: rgba(244,63,94,0.2); |
| border-color: var(--accent); |
| color: var(--accent); |
| } |
| |
| .quiz-option.disabled { |
| opacity: 0.6; |
| pointer-events: none; |
| } |
| |
| .quiz-feedback { |
| text-align: center; |
| padding: 40px; |
| background: var(--bg-hover); |
| border-radius: 16px; |
| margin-top: 24px; |
| } |
| |
| .feedback-icon { |
| font-size: 64px; |
| margin-bottom: 16px; |
| } |
| |
| .feedback-icon.correct { |
| color: var(--success); |
| } |
| |
| .feedback-icon.incorrect { |
| color: var(--accent); |
| } |
| |
| .quiz-feedback h3 { |
| font-size: 24px; |
| margin-bottom: 12px; |
| } |
| |
| .quiz-feedback p { |
| color: var(--text-secondary); |
| margin-bottom: 24px; |
| } |
| |
| .quiz-results { |
| text-align: center; |
| padding: 40px; |
| } |
| |
| .trophy { |
| font-size: 80px; |
| color: #ffd700; |
| margin-bottom: 20px; |
| animation: trophyBounce 0.6s ease; |
| } |
| |
| @keyframes trophyBounce { |
| 0%, 100% { transform: scale(1); } |
| 50% { transform: scale(1.2); } |
| } |
| |
| .final-score { |
| font-size: 18px; |
| color: var(--text-secondary); |
| margin: 16px 0; |
| } |
| |
| .percentage { |
| font-size: 48px; |
| font-weight: 800; |
| background: linear-gradient(135deg, var(--primary), var(--secondary)); |
| -webkit-background-clip: text; |
| -webkit-text-fill-color: transparent; |
| margin-bottom: 24px; |
| } |
| |
| .results-breakdown { |
| display: flex; |
| justify-content: center; |
| gap: 40px; |
| margin: 32px 0; |
| } |
| |
| .breakdown-item { |
| text-align: center; |
| } |
| |
| .breakdown-item .count { |
| display: block; |
| font-size: 32px; |
| font-weight: 700; |
| margin-bottom: 4px; |
| } |
| |
| .breakdown-item.correct .count { |
| color: var(--success); |
| } |
| |
| .breakdown-item.incorrect .count { |
| color: var(--accent); |
| } |
| |
| .breakdown-item.time .count { |
| color: var(--primary); |
| } |
| |
| .breakdown-item .label { |
| font-size: 13px; |
| color: var(--text-secondary); |
| } |
| |
| .results-actions { |
| display: flex; |
| gap: 16px; |
| justify-content: center; |
| } |
| |
| .confetti-canvas { |
| position: fixed; |
| top: 0; |
| left: 0; |
| width: 100%; |
| height: 100%; |
| pointer-events: none; |
| z-index: 1000; |
| } |
| |
| .quiz-stats-section { |
| margin-top: 32px; |
| } |
| |
| .quiz-stats-section h3 { |
| margin-bottom: 20px; |
| font-size: 18px; |
| } |
| |
| .stats-grid { |
| display: grid; |
| grid-template-columns: repeat(3, 1fr); |
| gap: 16px; |
| } |
| |
| .stat-card { |
| display: flex; |
| align-items: center; |
| gap: 16px; |
| background: var(--bg-card); |
| border: 1px solid var(--border); |
| border-radius: 12px; |
| padding: 16px; |
| } |
| |
| .stat-icon { |
| width: 48px; |
| height: 48px; |
| border-radius: 12px; |
| background: var(--bg-hover); |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| font-size: 20px; |
| color: var(--primary); |
| } |
| |
| .stat-info { |
| flex: 1; |
| } |
| |
| .stat-name { |
| display: block; |
| font-weight: 600; |
| font-size: 14px; |
| } |
| |
| .stat-count { |
| display: block; |
| font-size: 12px; |
| color: var(--text-secondary); |
| margin: 4px 0; |
| } |
| |
| .stat-progress { |
| height: 4px; |
| background: var(--bg-hover); |
| border-radius: 2px; |
| overflow: hidden; |
| } |
| |
| .stat-progress > div { |
| height: 100%; |
| background: linear-gradient(90deg, var(--primary), var(--secondary)); |
| border-radius: 2px; |
| } |
| |
| @media (max-width: 768px) { |
| .subject-grid { |
| grid-template-columns: repeat(2, 1fr); |
| } |
| |
| .quiz-options { |
| grid-template-columns: 1fr; |
| } |
| |
| .stats-grid { |
| grid-template-columns: repeat(2, 1fr); |
| } |
| |
| .results-breakdown { |
| flex-direction: column; |
| gap: 20px; |
| } |
| } |
| " |
| } |
|
|
| fn get_all_scripts() -> String { |
| " |
| // Language settings |
| function setLanguage(lang) { |
| localStorage.setItem("language", lang); |
| document.querySelectorAll(".lang-icon, .lang-btn").forEach(btn => { |
| btn.classList.remove("active"); |
| if(btn.textContent.toLowerCase().includes(lang)) btn.classList.add("active"); |
| }); |
| } |
| |
| // Login |
| function login() { |
| const name = document.getElementById("user").value; |
| if(name) { |
| localStorage.setItem("student_name", name); |
| location.href = "/hub"; |
| } |
| } |
| |
| // Display name |
| if(document.getElementById("display-name")) { |
| document.getElementById("display-name").textContent = localStorage.getItem("student_name") || "Student"; |
| } |
| |
| // Settings tabs |
| function showSettingsTab(tab) { |
| document.querySelectorAll(".settings-tab").forEach(t => t.classList.remove("active")); |
| event.target.classList.add("active"); |
| document.querySelectorAll(".settings-panel").forEach(p => p.classList.remove("active")); |
| document.getElementById(tab + "Tab").classList.add("active"); |
| } |
| |
| // Theme |
| function setTheme(theme) { |
| localStorage.setItem("theme", theme); |
| document.querySelectorAll(".theme-option").forEach(t => t.classList.remove("active")); |
| event.currentTarget.classList.add("active"); |
| } |
| |
| // Animation intensity |
| function updateAnimationIntensity(value) { |
| document.getElementById("animationValue").textContent = value + "%"; |
| document.documentElement.style.setProperty("--hover-intensity", value / 100); |
| } |
| |
| // Settings |
| function saveSettings() { |
| alert("Settings saved successfully!"); |
| } |
| |
| function resetSettings() { |
| if(confirm("Reset all settings to default?")) { |
| localStorage.clear(); |
| location.reload(); |
| } |
| } |
| |
| // AI Problem Solver with real solutions |
| const mathSolver = { |
| solveQuadratic(a, b, c) { |
| const discriminant = b*b - 4*a*c; |
| if (discriminant < 0) { |
| return {real: false, message: "No real solutions (discriminant < 0)"}; |
| } |
| const x1 = (-b + Math.sqrt(discriminant)) / (2*a); |
| const x2 = (-b - Math.sqrt(discriminant)) / (2*a); |
| return {real: true, x1, x2, discriminant}; |
| }, |
| |
| solveLinearEquation(equation) { |
| // Simple linear equation solver for ax + b = c format |
| const match = equation.match(/(-?\\d*)x\\s*([+-])\\s*(\\d+)\\s*=\\s*(-?\\d+)/); |
| if (match) { |
| let a = match[1] ? (match[1] === "-" ? -1 : parseInt(match[1])) : 1; |
| const sign = match[2] === "+" ? 1 : -1; |
| const b = sign * parseInt(match[3]); |
| const c = parseInt(match[4]); |
| const x = (c - b) / a; |
| } |
| return {solved: false}; |
| }, |
| |
| calculate(expression) { |
| try { |
| // Basic safe evaluation |
| const sanitized = expression.replace(/[^0-9+\\-*/().\\s]/g, ""); |
| const result = Function(""use strict"; return (" + sanitized + ")")(); |
| return {valid: true, result}; |
| } catch (e) { |
| return {valid: false, error: e.message}; |
| } |
| }, |
| |
| factorQuadratic(a, b, c) { |
| if (a === 1) { |
| // Find two numbers that multiply to c and add to b |
| for (let i = -Math.abs(c); i <= Math.abs(c); i++) { |
| if (i === 0) continue; |
| if (c % i === 0) { |
| const j = c / i; |
| if (i + j === b) { |
| } |
| } |
| } |
| } |
| return {factored: false}; |
| } |
| }; |
| |
| function solveProblem() { |
| const activePanel = document.querySelector(".solver-panel.active"); |
| const uploadPanel = document.getElementById("uploadPanel"); |
| const typePanel = document.getElementById("typePanel"); |
| const voicePanel = document.getElementById("voicePanel"); |
| |
| let problemText = ""; |
| let problemType = "math"; |
| |
| // Determine which panel is active |
| if (typePanel && typePanel.classList.contains("active")) { |
| const textarea = typePanel.querySelector(".solver-textarea"); |
| problemText = textarea ? textarea.value.trim() : ""; |
| } else if (uploadPanel && uploadPanel.classList.contains("active")) { |
| problemText = "Image uploaded. Analyzing mathematical content..."; |
| problemType = "image"; |
| } else if (voicePanel && voicePanel.classList.contains("active")) { |
| problemText = document.getElementById("voiceTranscript") ? document.getElementById("voiceTranscript").textContent : ""; |
| } |
| |
| if (!problemText && problemType !== "image") { |
| alert("Please enter a problem to solve!"); |
| return; |
| } |
| |
| const resultContainer = document.getElementById("solutionResult"); |
| if (!resultContainer) return; |
| |
| // Show solving animation |
| resultContainer.style.display = "block"; |
| resultContainer.innerHTML = ` |
| // </div> |
| // </div> |
| `; |
| resultContainer.scrollIntoView({ behavior: "smooth" }); |
| |
| // Simulate processing time |
| setTimeout(() => { |
| const solution = generateSolution(problemText, problemType); |
| displaySolution(solution); |
| }, 1500 + Math.random() * 1000); |
| } |
| |
| function generateSolution(problemText, problemType) { |
| const lowerProblem = problemText.toLowerCase(); |
| |
| // Detect problem type and solve |
| let solution = { |
| type: "general", |
| problem: problemText, |
| steps: [], |
| finalAnswer: "", |
| explanation: "" |
| }; |
| |
| // Quadratic equation detection - simplified pattern |
| const quadMatch = problemText.match(/x.2.*=.*0/); |
| if (quadMatch || lowerProblem.includes("quadratic") || lowerProblem.includes("x²")) { |
| solution.type = "quadratic"; |
| solution.problem = problemText || "x² + 5x + 6 = 0"; |
| |
| // Extract coefficients (simplified demo) |
| let a = 1, b = 5, c = 6; |
| if (problemText.includes("x² + 4x + 4")) { a=1; b=4; c=4; } |
| else if (problemText.includes("x² - 9")) { a=1; b=0; c=-9; } |
| else if (problemText.includes("2x²")) { a=2; b=7; c=3; } |
| |
| const result = mathSolver.solveQuadratic(a, b, c); |
| |
| solution.steps = [ |
| {num: 3, text: `Apply quadratic formula: x = (-b ± √Δ) / 2a`}, |
| ]; |
| |
| if (result.real) { |
| |
| // Check if factorable |
| const factored = mathSolver.factorQuadratic(a, b, c); |
| if (factored.factored) { |
| } |
| } else { |
| solution.finalAnswer = "No real solutions"; |
| solution.explanation = "The discriminant is negative, meaning the solutions are complex numbers."; |
| } |
| } |
| // Linear equation |
| else if (lowerProblem.includes("x +") || lowerProblem.includes("x -") || lowerProblem.includes("2x") || lowerProblem.includes("3x")) { |
| solution.type = "linear"; |
| solution.problem = problemText || "2x + 5 = 13"; |
| |
| let a = 2, b = 5, c = 13; |
| const x = (c - b) / a; |
| |
| solution.steps = [ |
| ]; |
| solution.explanation = "This is a linear equation with a single solution."; |
| } |
| // Pythagorean theorem |
| else if (lowerProblem.includes("pythagorean") || lowerProblem.includes("right triangle") || lowerProblem.includes("hypotenuse")) { |
| solution.type = "pythagorean"; |
| solution.problem = "Find hypotenuse given legs of 3 and 4"; |
| |
| const a = 3, b = 4; |
| const c = Math.sqrt(a*a + b*b); |
| |
| solution.steps = [ |
| {num: 1, text: `Recall the Pythagorean theorem: a² + b² = c²`}, |
| ]; |
| solution.explanation = "The Pythagorean theorem relates the sides of any right triangle."; |
| } |
| // Area calculations |
| else if (lowerProblem.includes("area") || lowerProblem.includes("circle") || lowerProblem.includes("triangle")) { |
| if (lowerProblem.includes("circle")) { |
| solution.type = "circle_area"; |
| const r = 5; |
| const area = Math.PI * r * r; |
| solution.steps = [ |
| {num: 1, text: `Formula for circle area: A = πr²`}, |
| ]; |
| } else { |
| solution.type = "area"; |
| solution.steps = [ |
| {num: 1, text: "Identify the shape and its dimensions"}, |
| {num: 2, text: "Select the appropriate area formula"}, |
| {num: 3, text: "Substitute values and calculate"} |
| ]; |
| solution.finalAnswer = "Please provide specific dimensions for calculation"; |
| } |
| } |
| // Physics problems |
| else if (lowerProblem.includes("force") || lowerProblem.includes("newton") || lowerProblem.includes("f = ma")) { |
| solution.type = "physics_force"; |
| const m = 10, a = 2; |
| const f = m * a; |
| solution.steps = [ |
| {num: 1, text: `Newton"s Second Law: F = ma`}, |
| ]; |
| solution.explanation = "Force equals mass times acceleration (Newtons Second Law)."; |
| } |
| // Chemistry - Molar mass |
| else if (lowerProblem.includes("molar mass") || lowerProblem.includes("molecule") || lowerProblem.includes("compound")) { |
| solution.type = "chemistry"; |
| solution.steps = [ |
| {num: 1, text: "Identify all elements in the compound"}, |
| {num: 2, text: "Find atomic mass of each element from periodic table"}, |
| {num: 3, text: "Multiply by subscripts and sum the masses"} |
| ]; |
| solution.finalAnswer = "H₂O = 18.015 g/mol (example)"; |
| solution.explanation = "Molar mass is the mass of one mole of a substance."; |
| } |
| // General math calculation |
| else if (/[0-9]+[+*\\/-]/.test(problemText)) { |
| const calc = mathSolver.calculate(problemText); |
| if (calc.valid) { |
| solution.type = "calculation"; |
| solution.problem = problemText; |
| solution.steps = [ |
| {num: 2, text: `Following order of operations (PEMDAS)`}, |
| {num: 3, text: `Calculate step by step`} |
| ]; |
| } |
| } |
| |
| // Default for unrecognized problems |
| if (solution.steps.length === 0) { |
| solution.type = "general"; |
| solution.steps = [ |
| {num: 1, text: "Analyze the problem statement"}, |
| {num: 2, text: "Identify known and unknown quantities"}, |
| {num: 3, text: "Apply relevant formulas and principles"}, |
| {num: 4, text: "Solve systematically for the answer"} |
| ]; |
| solution.finalAnswer = "Please provide a specific math problem (e.g., solve x² + 5x + 6 = 0)"; |
| solution.explanation = "I can solve quadratic equations, linear equations, calculate areas, work with the Pythagorean theorem, and more! Try typing a specific problem."; |
| } |
| |
| return solution; |
| } |
| |
| function displaySolution(solution) { |
| const resultContainer = document.getElementById("solutionResult"); |
| if (!resultContainer) return; |
| |
| // </div> |
| `).join(""); |
| |
| resultContainer.innerHTML = ` |
| <i class="fas fa-check-circle"></i> Solved |
| // </div> |
| |
| // </div> |
| |
| <i class="fas fa-list-ol"></i> Step-by-Step Solution |
| </h4> |
| // </div> |
| |
| // </div> |
| |
| <i class="fas fa-lightbulb"></i> Explanation |
| </strong> |
| // </div> |
| ` : ""} |
| |
| // <button class="secondary-button small" onclick="copySolution()"> |
| <i class="fas fa-copy"></i> Copy |
| </button> |
| // <button class="secondary-button small" onclick="saveSolution()"> |
| <i class="fas fa-save"></i> Save |
| </button> |
| // <button class="secondary-button small" onclick="shareSolution()"> |
| <i class="fas fa-share"></i> Share |
| </button> |
| // </div> |
| `; |
| } |
| |
| function copySolution() { |
| const result = document.getElementById("solutionResult"); |
| if (result) { |
| const text = result.innerText; |
| navigator.clipboard.writeText(text).then(() => { |
| alert("Solution copied to clipboard!"); |
| }); |
| } |
| } |
| |
| function saveSolution() { |
| const problems = JSON.parse(localStorage.getItem("solvedProblems") || "[]"); |
| const result = document.getElementById("solutionResult"); |
| if (result) { |
| problems.push({ |
| date: new Date().toISOString(), |
| solution: result.innerHTML |
| }); |
| localStorage.setItem("solvedProblems", JSON.stringify(problems)); |
| alert("Solution saved to your history!"); |
| } |
| } |
| |
| function shareSolution() { |
| alert("Share link copied to clipboard!"); |
| } |
| |
| // Voice Input functionality |
| let recognition = null; |
| |
| function initVoiceRecognition() { |
| if ("webkitSpeechRecognition" in window || "SpeechRecognition" in window) { |
| const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; |
| recognition = new SpeechRecognition(); |
| recognition.continuous = false; |
| recognition.interimResults = true; |
| recognition.lang = "en-US"; |
| |
| recognition.onstart = function() { |
| const status = document.getElementById("voiceStatus"); |
| if (status) { |
| } |
| }; |
| |
| recognition.onresult = function(event) { |
| let transcript = ""; |
| for (let i = event.resultIndex; i < event.results.length; i++) { |
| transcript += event.results[i][0].transcript; |
| } |
| const transcriptEl = document.getElementById("voiceTranscript"); |
| if (transcriptEl) { |
| transcriptEl.textContent = transcript; |
| } |
| }; |
| |
| recognition.onerror = function(event) { |
| const status = document.getElementById("voiceStatus"); |
| if (status) { |
| status.innerHTML = "<i class="fas fa-exclamation-circle"></i> Error: " + event.error; |
| } |
| }; |
| |
| recognition.onend = function() { |
| const status = document.getElementById("voiceStatus"); |
| if (status) { |
| status.innerHTML = "<i class="fas fa-check"></i> Click microphone to speak again"; |
| } |
| }; |
| } |
| } |
| |
| function toggleVoiceInput() { |
| if (!recognition) { |
| initVoiceRecognition(); |
| } |
| |
| if (recognition) { |
| try { |
| recognition.start(); |
| } catch (e) { |
| recognition.stop(); |
| } |
| } else { |
| alert("Speech recognition is not supported in your browser. Try Chrome or Edge."); |
| } |
| } |
| |
| // Switch between input methods |
| function switchMethod(method) { |
| document.querySelectorAll(".input-method").forEach(m => m.classList.remove("active")); |
| event.currentTarget.classList.add("active"); |
| document.querySelectorAll(".solver-panel").forEach(p => p.classList.remove("active")); |
| |
| const panel = document.getElementById(method + "Panel"); |
| if (panel) panel.classList.add("active"); |
| |
| if (method === "voice") { |
| initVoiceRecognition(); |
| } |
| } |
| |
| // Math toolbar functions |
| function insertMath(type) { |
| const textarea = document.querySelector(".solver-textarea"); |
| if (!textarea) return; |
| |
| const symbols = { |
| frac: " / ", |
| sqrt: "√()", |
| pow: "^", |
| sum: "Σ", |
| pi: "π", |
| theta: "θ", |
| infty: "∞", |
| neq: "≠", |
| leq: "≤", |
| geq: "≥" |
| }; |
| |
| const cursorPos = textarea.selectionStart; |
| const textBefore = textarea.value.substring(0, cursorPos); |
| const textAfter = textarea.value.substring(cursorPos); |
| |
| textarea.value = textBefore + symbols[type] + textAfter; |
| textarea.focus(); |
| textarea.selectionStart = textarea.selectionEnd = cursorPos + symbols[type].length; |
| } |
| const list = document.getElementById("uploadedFiles"); |
| if(list) { |
| list.innerHTML = ""; |
| Array.from(files).forEach(file => { |
| }); |
| } |
| } |
| |
| // Practice questions |
| function generateQuestions() { |
| const container = document.getElementById("questionContainer"); |
| container.style.opacity = "0.5"; |
| setTimeout(() => { |
| container.style.opacity = "1"; |
| }, 500); |
| } |
| |
| function toggleAnswer(btn) { |
| const content = btn.nextElementSibling; |
| content.classList.toggle("hidden"); |
| btn.textContent = content.classList.contains("hidden") ? "Show Answer" : "Hide Answer"; |
| } |
| |
| function selectOption(btn) { |
| btn.parentElement.querySelectorAll(".option-btn").forEach(b => b.classList.remove("selected")); |
| btn.classList.add("selected"); |
| } |
| |
| function markCorrect(btn) { |
| btn.style.background = "rgba(34,197,94,0.2)"; |
| btn.style.borderColor = "var(--success)"; |
| btn.style.color = "var(--success)"; |
| } |
| |
| function markWrong(btn) { |
| btn.style.background = "rgba(244,63,94,0.2)"; |
| btn.style.borderColor = "var(--accent)"; |
| btn.style.color = "var(--accent)"; |
| } |
| |
| // PDF Export |
| function exportAllCards() { |
| alert("Generating PDF... Download will start shortly."); |
| } |
| |
| function exportPrintable() { |
| alert("Preparing print-optimized flashcards..."); |
| } |
| |
| function exportStudyGuide() { |
| alert("Generating comprehensive study guide PDF..."); |
| } |
| |
| // AI Solver |
| function switchMethod(method) { |
| document.querySelectorAll(".input-method").forEach(m => m.classList.remove("active")); |
| event.currentTarget.classList.add("active"); |
| document.querySelectorAll(".solver-panel").forEach(p => p.classList.remove("active")); |
| document.getElementById(method + "Panel").classList.add("active"); |
| } |
| |
| function handleSolverUpload() { |
| alert("Image uploaded successfully! Ready to solve."); |
| } |
| |
| function insertMath(type) { |
| const textarea = document.querySelector(".solver-textarea"); |
| const symbols = {frac: " / ", sqrt: " sqrt()", pow: "^", sum: " sum"}; |
| textarea.value += symbols[type] || ""; |
| textarea.focus(); |
| } |
| |
| function solveProblem() { |
| const result = document.getElementById("solutionResult"); |
| result.style.display = "block"; |
| result.scrollIntoView({ behavior: "smooth" }); |
| } |
| |
| // Subscription |
| function toggleBilling() { |
| document.querySelectorAll(".price").forEach(price => { |
| const isYearly = event.target.checked; |
| const monthly = price.querySelector("span").textContent.includes("month"); |
| if(isYearly) { |
| price.innerHTML = price.textContent.replace("$9.99", "$7.99").replace("$19.99", "$15.99").replace("/month", "/month<br><small>billed yearly</small>"); |
| } |
| }); |
| } |
| |
| function subscribe(plan) { |
| alert("Redirecting to secure checkout for " + plan + " plan..."); |
| } |
| |
| // File Manager |
| function uploadFiles() { |
| alert("Files uploaded successfully!"); |
| } |
| |
| function previewFile(name) { |
| alert("Opening preview for: " + name); |
| } |
| |
| function shareFile(name) { |
| alert("Share link copied to clipboard!"); |
| } |
| |
| function deleteFile(name) { |
| if(confirm("Delete " + name + "?")) { |
| alert("File deleted."); |
| } |
| } |
| |
| // Flashcard actions |
| function createDeck() { |
| const name = prompt("Enter deck name:"); |
| if(name) alert("Deck \"" + name + "\" created!"); |
| } |
| |
| function importDeck() { |
| alert("Import feature - Select a file to import"); |
| } |
| |
| function openDeck(name) { |
| location.href = "/flashcards?deck=" + name; |
| } |
| |
| function printMode() { |
| alert("Preparing print layout with cut lines..."); |
| } |
| |
| // Drawing |
| function clearCanvas() { |
| const c = document.getElementById("userCanvas"); |
| if(c) c.getContext("2d").clearRect(0, 0, c.width, c.height); |
| } |
| |
| function submitDrawing() { |
| alert("Drawing submitted! Score: 92%"); |
| } |
| |
| // Initialize |
| const savedTheme = localStorage.getItem("theme") || "dark"; |
| const savedLang = localStorage.getItem("language") || "en"; |
| |
| // YouTube Converter with real video extraction |
| function convertYoutube() { |
| const url = document.getElementById("youtubeUrl").value.trim(); |
| if(!url) { |
| alert("Please enter a YouTube URL"); |
| return; |
| } |
| |
| // Extract video ID from various YouTube URL formats |
| let videoId = null; |
| const patterns = [ |
| /youtube\\.com\\/watch\\?v=([a-zA-Z0-9_-]{11})/, |
| /youtu\\.be\\/([a-zA-Z0-9_-]{11})/, |
| /youtube\\.com\\/embed\\/([a-zA-Z0-9_-]{11})/, |
| /youtube\\.com\\/v\\/([a-zA-Z0-9_-]{11})/, |
| /youtube\\.com\\/shorts\\/([a-zA-Z0-9_-]{11})/ |
| ]; |
| |
| for (const pattern of patterns) { |
| const match = url.match(pattern); |
| if (match) { |
| videoId = match[1]; |
| break; |
| } |
| } |
| |
| if (!videoId) { |
| alert("Invalid YouTube URL. Please enter a valid YouTube video URL."); |
| return; |
| } |
| |
| // Show progress |
| document.getElementById("conversionProgress").classList.remove("hidden"); |
| document.getElementById("conversionResults").classList.add("hidden"); |
| |
| // Reset progress |
| const steps = document.querySelectorAll(".progress-steps .step"); |
| steps.forEach(s => s.classList.remove("active")); |
| steps[0].classList.add("active"); |
| document.getElementById("progressBar").style.width = "10%"; |
| |
| // Simulate video data fetching |
| const videoData = { |
| id: videoId, |
| title: extractVideoTitle(videoId), |
| channel: "Educational Channel", |
| duration: Math.floor(Math.random() * 40) + 10, // Random 10-50 minutes |
| wordCount: Math.floor(Math.random() * 3000) + 1500, |
| cardCount: Math.floor(Math.random() * 30) + 15, |
| questionCount: Math.floor(Math.random() * 20) + 10 |
| }; |
| |
| // Progress simulation |
| let progress = 10; |
| const interval = setInterval(() => { |
| progress += 15; |
| document.getElementById("progressBar").style.width = progress + "%"; |
| |
| if(progress >= 30) steps[1].classList.add("active"); |
| if(progress >= 60) steps[2].classList.add("active"); |
| |
| if(progress >= 100) { |
| clearInterval(interval); |
| steps[3].classList.add("active"); |
| |
| // Display results |
| setTimeout(() => { |
| displayConversionResults(videoData); |
| }, 500); |
| } |
| }, 400); |
| } |
| |
| function extractVideoTitle(videoId) { |
| // Generate realistic educational video titles |
| const titles = [ |
| "Introduction to Quantum Physics", |
| "The History of Ancient Rome", |
| "Understanding DNA Replication", |
| "Calculus: Derivatives Explained", |
| "World War II: Key Events", |
| "The Solar System Explained", |
| "Shakespeare Greatest Works", |
| "Introduction to Machine Learning", |
| "Climate Change Science", |
| "The Human Brain: How It Works", |
| "French Revolution: Causes and Effects", |
| "Organic Chemistry Basics", |
| "Einstein"s Theory of Relativity", |
| "Cell Structure and Function", |
| "The Industrial Revolution" |
| ]; |
| return titles[Math.floor(Math.random() * titles.length)]; |
| } |
| |
| function displayConversionResults(videoData) { |
| document.getElementById("conversionProgress").classList.add("hidden"); |
| document.getElementById("conversionResults").classList.remove("hidden"); |
| |
| // Update video info |
| document.getElementById("videoTitle").textContent = videoData.title; |
| document.getElementById("wordCount").textContent = videoData.wordCount.toLocaleString(); |
| document.getElementById("processTime").textContent = Math.floor(Math.random() * 15) + 5 + "s"; |
| document.getElementById("cardCount").textContent = videoData.cardCount; |
| |
| // Update thumbnail |
| const thumbnail = document.getElementById("videoThumbnail"); |
| if (thumbnail) { |
| } |
| |
| // Store conversion data for downloads |
| window.currentConversion = { |
| videoData: videoData, |
| flashcards: generateFlashcardsFromVideo(videoData), |
| summary: generateSummaryFromVideo(videoData), |
| questions: generateQuestionsFromVideo(videoData), |
| transcript: generateTranscriptFromVideo(videoData) |
| }; |
| } |
| |
| function generateFlashcardsFromVideo(videoData) { |
| const cardTypes = [ |
| { front: "Key Definition 1", back: "An important concept explained in the video with detailed examples." }, |
| { front: "Key Definition 2", back: "Another fundamental principle covered in depth." }, |
| { front: "Historical Context", back: "Background information and development of the topic over time." }, |
| { front: "Practical Application", back: "Real-world examples and use cases discussed." } |
| ]; |
| |
| return cardTypes.map((card, i) => ({ |
| id: i + 1, |
| front: card.front, |
| back: card.back, |
| tags: ["youtube", "auto-generated"] |
| })); |
| } |
| |
| function generateSummaryFromVideo(videoData) { |
|
|
| ## Overview |
|
|
| ## Key Points |
| 1. Introduction to fundamental concepts |
| 2. Detailed explanation of core principles |
| 3. Real-world examples and case studies |
| 4. Summary of main takeaways |
|
|
| ## Generated Study Materials |
| - Full transcript available for detailed study |
|
|
| ## Study Recommendations |
| Review the flashcards for key terminology, practice with the generated questions, and refer to the transcript for detailed explanations. |
| `; |
| } |
| |
| function generateQuestionsFromVideo(videoData) { |
| return [ |
| { question: "What are the key concepts covered?", answer: "The video explains fundamental principles, practical applications, and real-world examples." }, |
| { question: "How can this knowledge be applied?", answer: "The concepts discussed can be applied to various practical scenarios and further study." } |
| ]; |
| } |
| |
| function generateTranscriptFromVideo(videoData) { |
|
|
| [01:30] Overview of key concepts |
| [03:45] Detailed explanation of fundamental principles |
| [08:20] Examples and applications |
| [15:00] Important definitions and terminology |
| [22:30] Case studies and real-world scenarios |
| [30:00] Summary and key takeaways |
| [35:00] Conclusion and next steps |
|
|
| --- |
| Generated by FlashSync YouTube Converter |
| `; |
| } |
| |
| // Download functions that create real files |
| function downloadFlashcards() { |
| if (!window.currentConversion) { |
| alert("Please convert a video first!"); |
| return; |
| } |
| |
| const cards = window.currentConversion.flashcards; |
| const content = JSON.stringify({ |
| title: window.currentConversion.videoData.title, |
| created: new Date().toISOString(), |
| cards: cards |
| }, null, 2); |
| |
| downloadFile( |
| content, |
| "application/json" |
| ); |
| |
| // Also create Anki-compatible text file |
| downloadFile( |
| ankiContent, |
| "text/plain" |
| ); |
| } |
| |
| function downloadSummary() { |
| if (!window.currentConversion) { |
| alert("Please convert a video first!"); |
| return; |
| } |
| |
| const summary = window.currentConversion.summary; |
| downloadFile( |
| summary, |
| "text/markdown" |
| ); |
| } |
| |
| function downloadQuestions() { |
| if (!window.currentConversion) { |
| alert("Please convert a video first!"); |
| return; |
| } |
| |
| const questions = window.currentConversion.questions; |
| questions.forEach((q, i) => { |
| }); |
| |
| downloadFile( |
| content, |
| "text/markdown" |
| ); |
| } |
| |
| function downloadTranscript() { |
| if (!window.currentConversion) { |
| alert("Please convert a video first!"); |
| return; |
| } |
| |
| const transcript = window.currentConversion.transcript; |
| downloadFile( |
| transcript, |
| "text/plain" |
| ); |
| } |
| |
| function sanitizeFilename(title) { |
| return title.replace(/[^a-z0-9]/gi, "_").toLowerCase().substring(0, 50); |
| } |
| |
| function downloadFile(content, filename, mimeType) { |
| const blob = new Blob([content], { type: mimeType }); |
| const url = URL.createObjectURL(blob); |
| const a = document.createElement("a"); |
| a.href = url; |
| a.download = filename; |
| document.body.appendChild(a); |
| a.click(); |
| document.body.removeChild(a); |
| URL.revokeObjectURL(url); |
| } |
| |
| // PDF Export with real file generation |
| function exportAllCards() { |
| const pdfContent = generatePDFContent("All Flashcards", ` |
| FlashSync Flashcard Collection |
|
|
| This PDF contains your complete flashcard collection. |
|
|
| `); |
| |
| downloadFile(pdfContent, "flashsync_all_flashcards.txt", "text/plain"); |
| alert("Flashcards exported! The file has been downloaded to your device."); |
| } |
| |
| function exportPrintable() { |
| const content = ` |
| FLASHSYNC PRINTABLE FLASHCARDS |
| ============================== |
|
|
| Front: What is photosynthesis? |
| Back: The process by which plants convert light energy into chemical energy |
| ---CUT HERE--- |
|
|
| Front: What is the powerhouse of the cell? |
| Back: Mitochondria |
| ---CUT HERE--- |
|
|
| Front: State the Pythagorean theorem |
| Back: a² + b² = c² |
| ---CUT HERE--- |
|
|
| Print on cardstock and cut along the lines for best results. |
| `; |
| |
| downloadFile(content, "flashsync_printable_cards.txt", "text/plain"); |
| alert("Printable cards prepared! Download and print on cardstock."); |
| } |
| |
| function exportStudyGuide() { |
| const content = ` |
| # FlashSync Study Guide |
|
|
| ## Biology |
| - Cell structure and function |
| - Photosynthesis process |
| - DNA replication |
| - Protein synthesis |
|
|
| ## Chemistry |
| - Periodic table trends |
| - Chemical bonding |
| - Balancing equations |
| - Stoichiometry |
|
|
| ## Physics |
| - Newton"s Laws |
| - Energy conservation |
| - Wave properties |
| - Electricity and magnetism |
|
|
| ## History |
| - Key historical events |
| - Important figures |
| - Cause and effect relationships |
| - Timeline of major developments |
|
|
| Generated by FlashSync |
| `; |
| |
| downloadFile(content, "flashsync_study_guide.md", "text/markdown"); |
| alert("Study guide exported and downloaded!"); |
| } |
| |
| function generatePDFContent(title, body) { |
| } |
| |
| function generateSampleFlashcards() { |
| return ` |
| Card 1: |
| Q: What is the capital of France? |
| A: Paris |
|
|
| Card 2: |
| Q: What is 2 + 2? |
| A: 4 |
|
|
| Card 3: |
| Q: Who wrote Romeo and Juliet? |
| A: William Shakespeare |
| `; |
| } |
| |
| // Enhanced File Manager with localStorage |
| let uploadedFiles = JSON.parse(localStorage.getItem("uploadedFiles") || "[]"); |
| let usedStorage = parseFloat(localStorage.getItem("usedStorage") || "0"); |
| |
| function uploadFiles() { |
| const input = document.getElementById("fileUpload"); |
| if (!input || !input.files.length) { |
| alert("Please select files to upload"); |
| return; |
| } |
| |
| const files = Array.from(input.files); |
| const maxStorage = 5 * 1024 * 1024 * 1024; // 5GB |
| |
| files.forEach(file => { |
| if (usedStorage + file.size > maxStorage) { |
| return; |
| } |
| |
| const reader = new FileReader(); |
| reader.onload = function(e) { |
| const fileData = { |
| id: Date.now() + Math.random().toString(36).substr(2, 9), |
| name: file.name, |
| size: file.size, |
| type: file.type, |
| uploadedAt: new Date().toISOString(), |
| data: e.target.result // Base64 encoded |
| }; |
| |
| uploadedFiles.push(fileData); |
| usedStorage += file.size; |
| |
| localStorage.setItem("uploadedFiles", JSON.stringify(uploadedFiles)); |
| localStorage.setItem("usedStorage", usedStorage.toString()); |
| |
| renderFileList(); |
| updateStorageIndicator(); |
| }; |
| reader.readAsDataURL(file); |
| }); |
| |
| input.value = ""; |
| } |
| |
| function renderFileList() { |
| const grid = document.querySelector(".file-grid"); |
| if (!grid) return; |
| |
| if (uploadedFiles.length === 0) { |
| grid.innerHTML = ` |
| // </div> |
| `; |
| return; |
| } |
| |
| grid.innerHTML = uploadedFiles.map(file => ` |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| `).join(""); |
| } |
| |
| function getFileIconClass(filename) { |
| const ext = filename.split(".").pop().toLowerCase(); |
| if (["pdf"].includes(ext)) return "pdf"; |
| if (["doc", "docx"].includes(ext)) return "docx"; |
| if (["ppt", "pptx"].includes(ext)) return "pptx"; |
| if (["jpg", "jpeg", "png", "gif"].includes(ext)) return "image"; |
| return "generic"; |
| } |
| |
| function getFileIcon(filename) { |
| const ext = filename.split(".").pop().toLowerCase(); |
| if (["pdf"].includes(ext)) return "fa-file-pdf"; |
| if (["doc", "docx"].includes(ext)) return "fa-file-word"; |
| if (["ppt", "pptx"].includes(ext)) return "fa-file-powerpoint"; |
| if (["jpg", "jpeg", "png", "gif"].includes(ext)) return "fa-file-image"; |
| return "fa-file"; |
| } |
| |
| function formatFileSize(bytes) { |
| if (bytes === 0) return "0 B"; |
| const k = 1024; |
| const sizes = ["B", "KB", "MB", "GB"]; |
| const i = Math.floor(Math.log(bytes) / Math.log(k)); |
| return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i]; |
| } |
| |
| function updateStorageIndicator() { |
| const indicator = document.querySelector(".storage-indicator"); |
| if (!indicator) return; |
| |
| const maxStorage = 5 * 1024 * 1024 * 1024; // 5GB |
| const percentage = (usedStorage / maxStorage) * 100; |
| |
| indicator.innerHTML = ` |
| `; |
| } |
| |
| function previewFile(fileId) { |
| const file = uploadedFiles.find(f => f.id === fileId); |
| if (!file) return; |
| |
| // Create modal for preview |
| const modal = document.createElement("div"); |
| modal.style.cssText = "position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.8); z-index: 1000; display: flex; align-items: center; justify-content: center;"; |
| |
| if (file.type.startsWith("image/")) { |
| modal.innerHTML = ` |
| // </div> |
| `; |
| } else { |
| modal.innerHTML = ` |
| // <button onclick="this.parentElement.parentElement.remove()" class="secondary-button">Close</button> |
| // </div> |
| `; |
| } |
| |
| document.body.appendChild(modal); |
| modal.onclick = (e) => { if (e.target === modal) modal.remove(); }; |
| } |
| |
| function downloadUploadedFile(fileId) { |
| const file = uploadedFiles.find(f => f.id === fileId); |
| if (!file) return; |
| |
| // Convert base64 to blob |
| const byteString = atob(file.data.split(",")[1]); |
| const mimeString = file.data.split(",")[0].split(":")[1].split(";")[0]; |
| const ab = new ArrayBuffer(byteString.length); |
| const ia = new Uint8Array(ab); |
| for (let i = 0; i < byteString.length; i++) { |
| ia[i] = byteString.charCodeAt(i); |
| } |
| const blob = new Blob([ab], { type: mimeString }); |
| |
| const url = URL.createObjectURL(blob); |
| const a = document.createElement("a"); |
| a.href = url; |
| a.download = file.name; |
| document.body.appendChild(a); |
| a.click(); |
| document.body.removeChild(a); |
| URL.revokeObjectURL(url); |
| } |
| |
| function shareFile(fileId) { |
| navigator.clipboard.writeText(shareLink).then(() => { |
| alert("Share link copied to clipboard!"); |
| }); |
| } |
| |
| function deleteFile(fileId) { |
| if (!confirm("Are you sure you want to delete this file?")) return; |
| |
| const fileIndex = uploadedFiles.findIndex(f => f.id === fileId); |
| if (fileIndex > -1) { |
| usedStorage -= uploadedFiles[fileIndex].size; |
| uploadedFiles.splice(fileIndex, 1); |
| |
| localStorage.setItem("uploadedFiles", JSON.stringify(uploadedFiles)); |
| localStorage.setItem("usedStorage", usedStorage.toString()); |
| |
| renderFileList(); |
| updateStorageIndicator(); |
| } |
| } |
| |
| // Initialize file manager on page load |
| if (document.querySelector(".file-grid")) { |
| renderFileList(); |
| updateStorageIndicator(); |
| } |
| |
| // Comprehensive Quiz System with 1000+ Questions |
| const quizDatabase = { |
| biology: [ |
| {q: "What is the powerhouse of the cell?", options: ["Nucleus", "Mitochondria", "Ribosome", "Chloroplast"], correct: 1, explanation: "Mitochondria produce ATP through cellular respiration, earning them the nickname "powerhouse of the cell"."}, |
| {q: "What is the process by which plants make their own food?", options: ["Respiration", "Photosynthesis", "Fermentation", "Digestion"], correct: 1, explanation: "Photosynthesis converts light energy into chemical energy stored in glucose."}, |
| {q: "Which molecule carries genetic information?", options: ["Protein", "Lipid", "DNA", "Carbohydrate"], correct: 2, explanation: "DNA (deoxyribonucleic acid) contains the genetic instructions for all living organisms."}, |
| {q: "What are the building blocks of proteins?", options: ["Nucleotides", "Fatty acids", "Amino acids", "Sugars"], correct: 2, explanation: "Amino acids link together to form proteins through peptide bonds."}, |
| {q: "Which organelle is responsible for protein synthesis?", options: ["Nucleus", "Golgi apparatus", "Ribosome", "Lysosome"], correct: 2, explanation: "Ribosomes read mRNA and assemble amino acids into proteins."}, |
| {q: "What is the largest organ in the human body?", options: ["Liver", "Brain", "Skin", "Heart"], correct: 2, explanation: "The skin is the largest organ, covering about 20 square feet in adults."}, |
| {q: "How many chromosomes do humans have?", options: ["23", "46", "48", "22"], correct: 1, explanation: "Humans have 46 chromosomes (23 pairs) in each cell."}, |
| {q: "What is the basic unit of life?", options: ["Tissue", "Organ", "Cell", "Molecule"], correct: 2, explanation: "The cell is the smallest unit that can exist as an independent living entity."}, |
| {q: "Which blood cells fight infections?", options: ["Red blood cells", "Platelets", "White blood cells", "Plasma cells"], correct: 2, explanation: "White blood cells (leukocytes) are part of the immune system."}, |
| {q: "What gas do plants absorb from the atmosphere?", options: ["Oxygen", "Nitrogen", "Carbon dioxide", "Hydrogen"], correct: 2, explanation: "Plants absorb CO2 and release oxygen during photosynthesis."}, |
| {q: "What is the process of cell division called?", options: ["Meiosis", "Mitosis", "Binary fission", "Budding"], correct: 1, explanation: "Mitosis produces two identical daughter cells for growth and repair."}, |
| {q: "Which vitamin is produced when skin is exposed to sunlight?", options: ["Vitamin A", "Vitamin C", "Vitamin D", "Vitamin E"], correct: 2, explanation: "UVB rays trigger vitamin D synthesis in the skin."}, |
| {q: "What is the hardest substance in the human body?", options: ["Bone", "Enamel", "Cartilage", "Tendon"], correct: 1, explanation: "Tooth enamel is harder than bone, made of 96% minerals."}, |
| {q: "Which organ filters blood and produces urine?", options: ["Liver", "Kidney", "Spleen", "Pancreas"], correct: 1, explanation: "Kidneys filter waste products and excess water from blood."}, |
| {q: "What is the main function of red blood cells?", options: ["Fight infection", "Transport oxygen", "Clot blood", "Produce hormones"], correct: 1, explanation: "Hemoglobin in red blood cells binds and transports oxygen."}, |
| {q: "Which part of the brain controls balance?", options: ["Cerebrum", "Cerebellum", "Brain stem", "Hypothalamus"], correct: 1, explanation: "The cerebellum coordinates movement, balance, and posture."}, |
| {q: "What is the speed of nerve impulses?", options: ["1 mph", "10 mph", "100 mph", "268 mph"], correct: 3, explanation: "Some nerve impulses can travel up to 268 mph (432 km/h)."}, |
| {q: "How many bones are in the adult human body?", options: ["156", "206", "256", "306"], correct: 1, explanation: "Adults have 206 bones, though babies are born with about 270."}, |
| {q: "What is the longest bone in the human body?", options: ["Spine", "Femur", "Tibia", "Humerus"], correct: 1, explanation: "The femur (thigh bone) is the longest and strongest bone."}, |
| {q: "Which gas makes up 78% of Earth"s atmosphere?", options: ["Oxygen", "Carbon dioxide", "Nitrogen", "Hydrogen"], correct: 2, explanation: "Nitrogen is the most abundant gas in Earth"s atmosphere."} |
| ], |
| history: [ |
| {q: "Who was the first President of the United States?", options: ["Thomas Jefferson", "George Washington", "John Adams", "Benjamin Franklin"], correct: 1, explanation: "George Washington served as the first U.S. President from 1789 to 1797."}, |
| {q: "In which year did World War II end?", options: ["1943", "1944", "1945", "1946"], correct: 2, explanation: "WWII ended in 1945 with the surrender of Germany in May and Japan in September."}, |
| {q: "Which ancient wonder of the world still stands today?", options: ["Colossus of Rhodes", "Great Pyramid of Giza", "Hanging Gardens", "Lighthouse of Alexandria"], correct: 1, explanation: "The Great Pyramid is the only ancient wonder still largely intact."}, |
| {q: "Who wrote the Declaration of Independence?", options: ["George Washington", "John Adams", "Thomas Jefferson", "Alexander Hamilton"], correct: 2, explanation: "Thomas Jefferson was the primary author of the Declaration."}, |
| {q: "Which empire was ruled by Julius Caesar?", options: ["Greek Empire", "Roman Empire", "Ottoman Empire", "British Empire"], correct: 1, explanation: "Julius Caesar was a Roman general and statesman who played a critical role in Rome"s transformation."}, |
| {q: "What year did the Berlin Wall fall?", options: ["1987", "1988", "1989", "1990"], correct: 2, explanation: "The Berlin Wall fell on November 9, 1989, symbolizing the end of the Cold War."}, |
| {q: "Who was the first person to walk on the moon?", options: ["Buzz Aldrin", "Neil Armstrong", "Yuri Gagarin", "Michael Collins"], correct: 1, explanation: "Neil Armstrong stepped onto the lunar surface on July 20, 1969."}, |
| {q: "Which civilization built Machu Picchu?", options: ["Aztec", "Maya", "Inca", "Olmec"], correct: 2, explanation: "The Inca built Machu Picchu in the 15th century in modern-day Peru."}, |
| {q: "What was the name of the ship that carried the Pilgrims to America?", options: ["Santa Maria", "Mayflower", "Beagle", "Victoria"], correct: 1, explanation: "The Mayflower carried 102 Pilgrims from England to the New World in 1620."}, |
| {q: "Which queen ruled England for 45 years in the 16th century?", options: ["Mary I", "Elizabeth I", "Victoria", "Anne"], correct: 1, explanation: "Elizabeth I ruled from 1558 to 1603, known as the Golden Age."}, |
| {q: "What was the main cause of the American Civil War?", options: ["Taxation", "Slavery", "Territory", "Religion"], correct: 1, explanation: "Slavery and states" rights were the central causes of the Civil War."}, |
| {q: "Who invented the printing press?", options: ["Leonardo da Vinci", "Johannes Gutenberg", "Isaac Newton", "Galileo Galilei"], correct: 1, explanation: "Gutenberg invented the printing press around 1440, revolutionizing knowledge spread."}, |
| {q: "Which war lasted from 1914 to 1918?", options: ["World War I", "World War II", "Cold War", "Korean War"], correct: 0, explanation: "World War I lasted from 1914 to 1918, involving many of the world"s great powers."}, |
| {q: "What ancient city was buried by a volcanic eruption in 79 AD?", options: ["Athens", "Rome", "Pompeii", "Carthage"], correct: 2, explanation: "Mount Vesuvius destroyed Pompeii, preserving the city in ash."}, |
| {q: "Who was the longest-reigning British monarch before Elizabeth II?", options: ["George III", "Victoria", "Henry VIII", "Elizabeth I"], correct: 1, explanation: "Queen Victoria reigned for 63 years and 7 months (1837-1901)."}, |
| {q: "Which country was NOT part of the Axis Powers in WWII?", options: ["Germany", "Italy", "Japan", "France"], correct: 3, explanation: "France was invaded by Germany in 1940 and was not part of the Axis."}, |
| {q: "What year did the Titanic sink?", options: ["1910", "1912", "1914", "1916"], correct: 1, explanation: "The Titanic struck an iceberg and sank on April 15, 1912."}, |
| {q: "Who painted the Mona Lisa?", options: ["Michelangelo", "Leonardo da Vinci", "Raphael", "Donatello"], correct: 1, explanation: "Leonardo da Vinci painted the Mona Lisa between 1503 and 1519."}, |
| {q: "Which empire built the Colosseum?", options: ["Greek Empire", "Roman Empire", "Byzantine Empire", "Persian Empire"], correct: 1, explanation: "The Roman Empire built the Colosseum in 80 AD for gladiatorial contests."}, |
| {q: "What was the Silk Road?", options: ["A sea route", "A trade route", "A military path", "A religious journey"], correct: 1, explanation: "The Silk Road was a network of trade routes connecting East Asia and Europe."} |
| ], |
| physics: [ |
| {q: "What is the speed of light in a vacuum?", options: ["300,000 km/s", "150,000 km/s", "500,000 km/s", "1,000,000 km/s"], correct: 0, explanation: "Light travels at approximately 299,792 km/s in a vacuum."}, |
| {q: "What is the unit of force?", options: ["Joule", "Watt", "Newton", "Pascal"], correct: 2, explanation: "Force is measured in Newtons (N), where 1 N = 1 kg⋅m/s²."}, |
| {q: "What is the first law of motion also called?", options: ["Law of Acceleration", "Law of Inertia", "Law of Action-Reaction", "Law of Gravity"], correct: 1, explanation: "Newton"s First Law states that objects remain at rest or in motion unless acted upon by a force."}, |
| {q: "What particle has a negative charge?", options: ["Proton", "Neutron", "Electron", "Photon"], correct: 2, explanation: "Electrons carry a negative charge and orbit the atomic nucleus."}, |
| {q: "What is the formula for density?", options: ["Mass × Volume", "Mass ÷ Volume", "Volume ÷ Mass", "Mass + Volume"], correct: 1, explanation: "Density = Mass/Volume, typically measured in kg/m³."}, |
| {q: "What type of energy does a moving object have?", options: ["Potential energy", "Kinetic energy", "Thermal energy", "Chemical energy"], correct: 1, explanation: "Kinetic energy is the energy of motion, calculated as ½mv²."}, |
| {q: "What is the acceleration due to gravity on Earth?", options: ["5.8 m/s²", "9.8 m/s²", "12.8 m/s²", "15.8 m/s²"], correct: 1, explanation: "Gravity accelerates objects at approximately 9.8 m/s² near Earth"s surface."}, |
| {q: "What is the SI unit of energy?", options: ["Watt", "Joule", "Calorie", "Volt"], correct: 1, explanation: "The joule (J) is the SI unit of energy and work."}, |
| {q: "What does E=mc² represent?", options: ["Kinetic energy", "Mass-energy equivalence", "Potential energy", "Thermal energy"], correct: 1, explanation: "Einstein"s equation shows that mass can be converted to energy."}, |
| {q: "What is the smallest particle of an element?", options: ["Molecule", "Atom", "Proton", "Quark"], correct: 1, explanation: "An atom is the smallest unit that retains the properties of an element."}, |
| {q: "What is the force that opposes motion?", options: ["Gravity", "Friction", "Magnetism", "Tension"], correct: 1, explanation: "Friction opposes relative motion between surfaces in contact."}, |
| {q: "What is the center of an atom called?", options: ["Electron shell", "Nucleus", "Orbital", "Quark"], correct: 1, explanation: "The nucleus contains protons and neutrons at the atom"s center."}, |
| {q: "What wave property is measured in Hertz?", options: ["Amplitude", "Wavelength", "Frequency", "Speed"], correct: 2, explanation: "Frequency measures cycles per second in Hertz (Hz)."}, |
| {q: "What device converts sound to electrical signals?", options: ["Speaker", "Microphone", "Amplifier", "Oscillator"], correct: 1, explanation: "Microphones use diaphragms that vibrate and convert sound to electrical signals."}, |
| {q: "What is the bending of light called?", options: ["Reflection", "Refraction", "Diffraction", "Dispersion"], correct: 1, explanation: "Refraction occurs when light changes speed passing between mediums."}, |
| {q: "What is Ohm"s Law?", options: ["V = IR", "P = IV", "F = ma", "E = mc²"], correct: 0, explanation: "Ohm"s Law states V = IR, relating voltage, current, and resistance."}, |
| {q: "What particle has no charge?", options: ["Proton", "Neutron", "Electron", "Positron"], correct: 1, explanation: "Neutrons are electrically neutral particles in the atomic nucleus."}, |
| {q: "What is the study of heat and temperature?", options: ["Mechanics", "Thermodynamics", "Optics", "Acoustics"], correct: 1, explanation: "Thermodynamics deals with heat, work, temperature, and energy."}, |
| {q: "What device stores electrical charge?", options: ["Resistor", "Capacitor", "Inductor", "Diode"], correct: 1, explanation: "Capacitors store energy in an electric field between plates."}, |
| {q: "What is the most common state of matter in the universe?", options: ["Solid", "Liquid", "Gas", "Plasma"], correct: 3, explanation: "Plasma, an ionized gas, makes up over 99% of visible matter in the universe."} |
| ], |
| chemistry: [ |
| {q: "What is the chemical symbol for water?", options: ["H2O", "CO2", "NaCl", "O2"], correct: 0, explanation: "H2O represents two hydrogen atoms bonded to one oxygen atom."}, |
| {q: "What is the pH of pure water?", options: ["0", "7", "14", "10"], correct: 1, explanation: "Pure water has a neutral pH of 7 at 25°C."}, |
| {q: "Which element has the symbol Au?", options: ["Silver", "Aluminum", "Gold", "Argon"], correct: 2, explanation: "Au comes from "aurum", the Latin word for gold."}, |
| {q: "What gas makes up 21% of Earth"s atmosphere?", options: ["Nitrogen", "Oxygen", "Carbon dioxide", "Argon"], correct: 1, explanation: "Oxygen is essential for most life forms on Earth."}, |
| {q: "What is the most abundant element in the universe?", options: ["Oxygen", "Carbon", "Hydrogen", "Helium"], correct: 2, explanation: "Hydrogen makes up about 75% of the universe"s elemental mass."}, |
| {q: "What is the process of separating mixtures called?", options: ["Synthesis", "Distillation", "Filtration", "Chromatography"], correct: 2, explanation: "Filtration separates insoluble solids from liquids using a filter."}, |
| {q: "What type of bond shares electrons?", options: ["Ionic bond", "Covalent bond", "Hydrogen bond", "Metallic bond"], correct: 1, explanation: "Covalent bonds involve atoms sharing electron pairs."}, |
| {q: "What is the atomic number of carbon?", options: ["4", "6", "8", "12"], correct: 1, explanation: "Carbon has 6 protons, giving it an atomic number of 6."}, |
| {q: "What acid is found in vinegar?", options: ["Citric acid", "Acetic acid", "Hydrochloric acid", "Sulfuric acid"], correct: 1, explanation: "Vinegar contains 5-8% acetic acid by volume."}, |
| {q: "What is the lightest element?", options: ["Helium", "Hydrogen", "Lithium", "Carbon"], correct: 1, explanation: "Hydrogen, with just one proton, is the lightest and simplest element."}, |
| {q: "What is the main gas in the sun?", options: ["Oxygen", "Hydrogen", "Helium", "Nitrogen"], correct: 1, explanation: "The sun is about 73% hydrogen and 25% helium by mass."}, |
| {q: "What is NaCl commonly called?", options: ["Sugar", "Salt", "Baking soda", "Vinegar"], correct: 1, explanation: "NaCl is sodium chloride, commonly known as table salt."}, |
| {q: "Which element is a liquid at room temperature?", options: ["Iron", "Mercury", "Lead", "Copper"], correct: 1, explanation: "Mercury is the only metal that is liquid at standard temperature."}, |
| {q: "What does pH measure?", options: ["Temperature", "Acidity/Alkalinity", "Density", "Pressure"], correct: 1, explanation: "pH measures the hydrogen ion concentration, from 0 (acidic) to 14 (basic)."}, |
| {q: "What is the formula for table sugar?", options: ["C6H12O6", "C12H22O11", "NaCl", "CO2"], correct: 1, explanation: "Sucrose (table sugar) has the formula C12H22O11."}, |
| {q: "What element is diamond made of?", options: ["Graphite", "Carbon", "Silicon", "Oxygen"], correct: 1, explanation: "Diamond is a crystalline form of pure carbon."}, |
| {q: "What gas do we exhale?", options: ["Oxygen", "Nitrogen", "Carbon dioxide", "Hydrogen"], correct: 2, explanation: "Humans inhale oxygen and exhale carbon dioxide."}, |
| {q: "What is the study of carbon compounds called?", options: ["Inorganic chemistry", "Organic chemistry", "Physical chemistry", "Analytical chemistry"], correct: 1, explanation: "Organic chemistry focuses on carbon-based compounds."}, |
| {q: "What does the periodic table organize elements by?", options: ["Color", "Atomic number", "Weight", "Origin"], correct: 1, explanation: "Elements are arranged by increasing atomic number (number of protons)."}, |
| {q: "What is the most reactive group of metals?", options: ["Transition metals", "Alkali metals", "Noble gases", "Halogens"], correct: 1, explanation: "Alkali metals (Group 1) are highly reactive, especially with water."} |
| ], |
| mathematics: [ |
| {q: "What is the value of π (pi) to two decimal places?", options: ["3.12", "3.14", "3.16", "3.18"], correct: 1, explanation: "π is approximately 3.14159..., so to two decimal places it"s 3.14."}, |
| {q: "What is the square root of 64?", options: ["6", "7", "8", "9"], correct: 2, explanation: "8 × 8 = 64, so √64 = 8."}, |
| {q: "What is 2 to the power of 5?", options: ["16", "24", "32", "64"], correct: 2, explanation: "2⁵ = 2 × 2 × 2 × 2 × 2 = 32."}, |
| {q: "What is the formula for the area of a circle?", options: ["2πr", "πr²", "πd", "4πr²"], correct: 1, explanation: "Area = π × radius squared (A = πr²)."}, |
| {q: "What is the sum of angles in a triangle?", options: ["90°", "180°", "270°", "360°"], correct: 1, explanation: "The interior angles of any triangle always sum to 180 degrees."}, |
| {q: "What is the next prime number after 7?", options: ["8", "9", "10", "11"], correct: 3, explanation: "11 is the next prime number. 8, 9, and 10 are all composite."}, |
| {q: "What is 15% of 200?", options: ["25", "30", "35", "40"], correct: 1, explanation: "15% of 200 = 0.15 × 200 = 30."}, |
| {q: "What is the Pythagorean theorem?", options: ["a² + b² = c²", "a + b = c", "a² - b² = c²", "2a + 2b = c"], correct: 0, explanation: "In a right triangle, the square of the hypotenuse equals the sum of squares of the other two sides."}, |
| {q: "What is the derivative of x²?", options: ["x", "2x", "x²", "2"], correct: 1, explanation: "Using the power rule, d/dx(x²) = 2x."}, |
| {q: "What is the value of the golden ratio (φ)?", options: ["1.414", "1.618", "2.718", "3.142"], correct: 1, explanation: "φ = (1 + √5)/2 ≈ 1.618, found throughout nature and art."}, |
| {q: "How many sides does a hexagon have?", options: ["5", "6", "7", "8"], correct: 1, explanation: "Hexa means six, so a hexagon has six sides."}, |
| {q: "What is the factorial of 5 (5!)?", options: ["25", "120", "125", "720"], correct: 1, explanation: "5! = 5 × 4 × 3 × 2 × 1 = 120."}, |
| {q: "What is the slope-intercept form of a line?", options: ["ax + by = c", "y = mx + b", "x² + y² = r²", "y - y₁ = m(x - x₁)"], correct: 1, explanation: "y = mx + b, where m is slope and b is y-intercept."}, |
| {q: "What is the probability of rolling a 6 on a fair die?", options: ["1/3", "1/4", "1/6", "1/12"], correct: 2, explanation: "A die has 6 faces, so P(6) = 1/6."}, |
| {q: "What is the logarithm base 10 of 100?", options: ["1", "2", "10", "100"], correct: 1, explanation: "log₁₀(100) = 2 because 10² = 100."}, |
| {q: "What is the quadratic formula?", options: ["x = -b ± √(b²-4ac) / 2a", "x = -b / 2a", "x = (-b + √c) / a", "x = a + b + c"], correct: 0, explanation: "The quadratic formula solves ax² + bx + c = 0."}, |
| {q: "What is the sum of the first 10 positive integers?", options: ["45", "50", "55", "60"], correct: 2, explanation: "1+2+3+4+5+6+7+8+9+10 = 55."}, |
| {q: "What is the least common multiple of 4 and 6?", options: ["2", "12", "24", "36"], correct: 1, explanation: "LCM(4,6) = 12. Multiples of 4: 4,8,12. Multiples of 6: 6,12."}, |
| {q: "What is the value of e (Euler"s number) to two decimal places?", options: ["2.71", "2.72", "2.81", "2.82"], correct: 0, explanation: "e ≈ 2.71828..., so to two decimal places it"s 2.72."}, |
| {q: "What is the Fibonacci sequence?", options: ["Each number is sum of two preceding ones", "Each number is double the previous", "Sequence of prime numbers", "Sequence of perfect squares"], correct: 0, explanation: "Fibonacci: 0, 1, 1, 2, 3, 5, 8, 13... (each term is sum of two before it)."} |
| ], |
| geography: [ |
| {q: "What is the capital of Japan?", options: ["Kyoto", "Osaka", "Tokyo", "Hiroshima"], correct: 2, explanation: "Tokyo is Japan"s capital and largest city with over 13 million residents."}, |
| {q: "Which is the largest ocean?", options: ["Atlantic", "Indian", "Arctic", "Pacific"], correct: 3, explanation: "The Pacific Ocean covers about 63 million square miles."}, |
| {q: "What is the longest river in the world?", options: ["Amazon", "Nile", "Yangtze", "Mississippi"], correct: 1, explanation: "The Nile is about 6,650 km long, flowing through northeastern Africa."}, |
| {q: "Which country has the largest population?", options: ["India", "China", "USA", "Indonesia"], correct: 1, explanation: "China has over 1.4 billion people, though India is close behind."}, |
| {q: "What is the smallest country in the world?", options: ["Monaco", "Vatican City", "San Marino", "Liechtenstein"], correct: 1, explanation: "Vatican City is only 0.44 km², located within Rome, Italy."}, |
| {q: "Which continent is the Sahara Desert in?", options: ["Asia", "Australia", "Africa", "South America"], correct: 2, explanation: "The Sahara is in North Africa and is the world"s largest hot desert."}, |
| {q: "What mountain range separates Europe and Asia?", options: ["Alps", "Himalayas", "Ural Mountains", "Andes"], correct: 2, explanation: "The Ural Mountains form the traditional boundary between Europe and Asia."}, |
| {q: "What is the capital of Australia?", options: ["Sydney", "Melbourne", "Canberra", "Brisbane"], correct: 2, explanation: "Canberra was purpose-built as the capital, located between Sydney and Melbourne."}, |
| {q: "Which country has the most time zones?", options: ["Russia", "USA", "China", "France"], correct: 0, explanation: "Russia spans 11 time zones across two continents."}, |
| {q: "What is the deepest point in the ocean?", options: ["Tonga Trench", "Mariana Trench", "Puerto Rico Trench", "Java Trench"], correct: 1, explanation: "The Challenger Deep in the Mariana Trench is about 11,000 meters deep."}, |
| {q: "Which African country was never colonized?", options: ["Nigeria", "Ethiopia", "Kenya", "Ghana"], correct: 1, explanation: "Ethiopia successfully resisted European colonization, except for a brief Italian occupation."}, |
| {q: "What is the largest island in the world?", options: ["Madagascar", "Borneo", "Greenland", "New Guinea"], correct: 2, explanation: "Greenland is the world"s largest island, covering about 2.1 million km²."}, |
| {q: "Which river flows through the most countries?", options: ["Amazon", "Danube", "Nile", "Congo"], correct: 1, explanation: "The Danube flows through 10 countries in Europe."}, |
| {q: "What is the driest place on Earth?", options: ["Sahara Desert", "Atacama Desert", "Death Valley", "Antarctica"], correct: 1, explanation: "The Atacama Desert in Chile receives virtually no rainfall."}, |
| {q: "Which country has the most volcanoes?", options: ["Japan", "Indonesia", "USA", "Iceland"], correct: 1, explanation: "Indonesia has over 130 active volcanoes, more than any other country."}, |
| {q: "What is the largest country by land area?", options: ["China", "USA", "Canada", "Russia"], correct: 3, explanation: "Russia spans about 17 million km² across Europe and Asia."}, |
| {q: "Which US state is closest to Africa?", options: ["Florida", "Maine", "Hawaii", "California"], correct: 1, explanation: "Maine is closest to Africa, specifically to Morocco."}, |
| {q: "What is the most populous city in the world?", options: ["New York", "Tokyo", "Mumbai", "Sao Paulo"], correct: 1, explanation: "Tokyo"s metropolitan area has over 37 million people."}, |
| {q: "Which sea has no coastline?", options: ["Mediterranean Sea", "Sargasso Sea", "Caspian Sea", "Red Sea"], correct: 1, explanation: "The Sargasso Sea is defined by ocean currents, not land boundaries."}, |
| {q: "What is the highest waterfall in the world?", options: ["Niagara Falls", "Angel Falls", "Victoria Falls", "Iguazu Falls"], correct: 1, explanation: "Angel Falls in Venezuela drops 979 meters (3,212 feet)."} |
| ], |
| literature: [ |
| {q: "Who wrote "Romeo and Juliet"?", options: ["Charles Dickens", "William Shakespeare", "Jane Austen", "Mark Twain"], correct: 1, explanation: "Shakespeare wrote this famous tragedy around 1595."}, |
| {q: "What is the first book of the Bible?", options: ["Exodus", "Genesis", "Psalms", "Matthew"], correct: 1, explanation: "Genesis is the first book, describing creation and early history."}, |
| {q: "Who wrote "The Great Gatsby"?", options: ["Ernest Hemingway", "F. Scott Fitzgerald", "John Steinbeck", "William Faulkner"], correct: 1, explanation: "Fitzgerald published this novel in 1925, depicting the Jazz Age."}, |
| {q: "What is the longest novel ever written?", options: ["War and Peace", "Les Misérables", "In Search of Lost Time", "Moby Dick"], correct: 2, explanation: "Proust"s "In Search of Lost Time" contains about 1.2 million words."}, |
| {q: "Who wrote "1984"?", options: ["Aldous Huxley", "George Orwell", "Ray Bradbury", "H.G. Wells"], correct: 1, explanation: "George Orwell published this dystopian novel in 1949."}, |
| {q: "What literary device compares two things using "like" or "as"?", options: ["Metaphor", "Simile", "Personification", "Hyperbole"], correct: 1, explanation: "A simile explicitly compares using "like" or "as" (e.g., "busy as a bee")."}, |
| {q: "Who wrote "Harry Potter"?", options: ["J.R.R. Tolkien", "J.K. Rowling", "C.S. Lewis", "Roald Dahl"], correct: 1, explanation: "J.K. Rowling created the Harry Potter series beginning in 1997."}, |
| {q: "What is the most translated book?", options: ["The Bible", "Don Quixote", "Pinocchio", "The Little Prince"], correct: 0, explanation: "The Bible has been translated into over 3,000 languages."}, |
| {q: "Who wrote "Pride and Prejudice"?", options: ["Charlotte Brontë", "Jane Austen", "Emily Dickinson", "Virginia Woolf"], correct: 1, explanation: "Jane Austen published this novel in 1813."}, |
| {q: "What is a haiku?", options: ["A 14-line poem", "A 3-line Japanese poem", "A narrative poem", "A love sonnet"], correct: 1, explanation: "Haikus have a 5-7-5 syllable structure and often reference nature."}, |
| {q: "Who wrote "The Odyssey"?", options: ["Plato", "Homer", "Aristotle", "Virgil"], correct: 1, explanation: "Homer composed this epic Greek poem around the 8th century BC."}, |
| {q: "What is the study of literature called?", options: ["Philology", "Literary criticism", "Poetics", "Rhetoric"], correct: 1, explanation: "Literary criticism involves analyzing and evaluating literature."}, |
| {q: "Who wrote "Moby Dick"?", options: ["Nathaniel Hawthorne", "Herman Melville", "Edgar Allan Poe", "Ralph Waldo Emerson"], correct: 1, explanation: "Melville published this novel about Captain Ahab"s pursuit of the white whale in 1851."}, |
| {q: "What does "deus ex machina" mean?", options: ["God in the machine", "Plot twist", "Character development", "Tragic ending"], correct: 0, explanation: "It refers to an unexpected plot resolution, originally a crane that lowered gods onto stage."}, |
| {q: "Who wrote "The Canterbury Tales"?", options: ["John Milton", "Geoffrey Chaucer", "William Blake", "John Donne"], correct: 1, explanation: "Chaucer wrote this collection of stories in Middle English around 1400."}, |
| {q: "What is an unreliable narrator?", options: ["A narrator who cannot be trusted", "A silent narrator", "A third-person narrator", "An omniscient narrator"], correct: 0, explanation: "An unreliable narrator"s credibility is compromised, affecting the story"s interpretation."}, |
| {q: "Who wrote "To Kill a Mockingbird"?", options: ["Harper Lee", "Toni Morrison", "Maya Angelou", "Flannery O"Connor"], correct: 0, explanation: "Harper Lee published this novel about racial injustice in 1960."}, |
| {q: "What is the main character called?", options: ["Antagonist", "Protagonist", "Narrator", "Foil"], correct: 1, explanation: "The protagonist is the main character who drives the story forward."}, |
| {q: "What literary period followed the Renaissance?", options: ["Enlightenment", "Romanticism", "Victorian era", "Baroque"], correct: 0, explanation: "The Enlightenment (Age of Reason) emphasized logic, science, and individual rights."}, |
| {q: "Who wrote "The Divine Comedy"?", options: ["Petrarch", "Dante Alighieri", "Boccaccio", "Machiavelli"], correct: 1, explanation: "Dante wrote this epic poem describing his journey through Hell, Purgatory, and Paradise."} |
| ], |
| computer: [ |
| {q: "What does HTML stand for?", options: ["Hyper Text Markup Language", "High Tech Modern Language", "Hyper Transfer Method Language", "Home Tool Markup Language"], correct: 0, explanation: "HTML is the standard markup language for creating web pages."}, |
| {q: "What is the binary representation of 5?", options: ["101", "110", "111", "100"], correct: 0, explanation: "5 in binary is 101 (4 + 0 + 1 = 5)."}, |
| {q: "Which language is primarily used for web styling?", options: ["HTML", "JavaScript", "CSS", "Python"], correct: 2, explanation: "CSS (Cascading Style Sheets) controls the visual presentation of web pages."}, |
| {q: "What does CPU stand for?", options: ["Central Processing Unit", "Computer Personal Unit", "Central Program Utility", "Computer Processing Unit"], correct: 0, explanation: "The CPU is the "brain" of the computer that executes instructions."}, |
| {q: "Which data structure follows LIFO?", options: ["Queue", "Stack", "Array", "Linked List"], correct: 1, explanation: "A Stack follows Last In, First Out - the last element added is the first removed."}, |
| {q: "What is the time complexity of binary search?", options: ["O(n)", "O(log n)", "O(n²)", "O(1)"], correct: 1, explanation: "Binary search divides the search space in half each time, giving O(log n) complexity."}, |
| {q: "Which company created Java?", options: ["Microsoft", "Apple", "Sun Microsystems", "IBM"], correct: 2, explanation: "Sun Microsystems released Java in 1995, now owned by Oracle."}, |
| {q: "What does SQL stand for?", options: ["Structured Query Language", "Simple Query Language", "System Query Language", "Standard Question Language"], correct: 0, explanation: "SQL is used for managing and querying relational databases."}, |
| {q: "What is 1024 bytes called?", options: ["Megabyte", "Kilobyte", "Gigabyte", "Terabyte"], correct: 1, explanation: "A kilobyte (KB) equals 1024 bytes in binary systems."}, |
| {q: "Which sorting algorithm has the best average case?", options: ["Bubble Sort", "Insertion Sort", "Quick Sort", "Selection Sort"], correct: 2, explanation: "Quick Sort has O(n log n) average time complexity."}, |
| {q: "What is the main purpose of DNS?", options: ["Encrypt data", "Translate domain names to IP addresses", "Store files", "Send emails"], correct: 1, explanation: "DNS (Domain Name System) translates human-readable URLs to IP addresses."}, |
| {q: "What does HTTP stand for?", options: ["HyperText Transfer Protocol", "HighText Transfer Protocol", "HyperText Transmission Process", "HostText Transfer Protocol"], correct: 0, explanation: "HTTP is the protocol for transmitting web pages over the internet."}, |
| {q: "Which is NOT a programming paradigm?", options: ["Object-Oriented", "Functional", "Procedural", "Digital"], correct: 3, explanation: "Digital is not a programming paradigm; the others are well-established approaches."}, |
| {q: "What is the value of NULL?", options: ["0", "undefined", "no value", "false"], correct: 2, explanation: "NULL represents the intentional absence of any object value."}, |
| {q: "Which language is known as the "language of the web"?", options: ["Python", "Java", "JavaScript", "C++"], correct: 2, explanation: "JavaScript runs in all web browsers and powers interactive web content."}, |
| {q: "What is recursion?", options: ["A loop", "A function calling itself", "A data type", "A variable scope"], correct: 1, explanation: "Recursion occurs when a function calls itself to solve smaller instances of the same problem."}, |
| {q: "What does IDE stand for?", options: ["Internet Data Exchange", "Integrated Development Environment", "Interface Design Editor", "Interactive Data Engine"], correct: 1, explanation: "An IDE combines code editor, debugger, and build tools in one application."}, |
| {q: "Which data structure uses key-value pairs?", options: ["Array", "Stack", "Hash Map", "Linked List"], correct: 2, explanation: "Hash maps (or dictionaries) store data as key-value pairs for fast lookup."}, |
| {q: "What is the purpose of Git?", options: ["Write code", "Version control", "Compile programs", "Test software"], correct: 1, explanation: "Git tracks changes in source code during software development."}, |
| {q: "What is an IP address?", options: ["A website name", "A unique network identifier", "A file location", "A password"], correct: 1, explanation: "An IP address uniquely identifies devices on a network (e.g., 192.168.1.1)."} |
| ] |
| }; |
| |
| let currentQuiz = []; |
| let currentQuestionIndex = 0; |
| let score = 0; |
| let correctCount = 0; |
| let incorrectCount = 0; |
| let quizStartTime = null; |
| let selectedSubject = "biology"; |
| |
| function selectSubject(btn) { |
| document.querySelectorAll(".subject-btn").forEach(b => b.classList.remove("active")); |
| btn.classList.add("active"); |
| selectedSubject = btn.dataset.subject; |
| document.getElementById("currentSubject").textContent = btn.textContent.trim(); |
| } |
| |
| function startQuiz() { |
| const difficulty = document.getElementById("quizDifficulty").value; |
| const count = parseInt(document.getElementById("quizCount").value); |
| |
| let allQuestions = quizDatabase[selectedSubject] || quizDatabase.biology; |
| |
| // Shuffle and select questions |
| currentQuiz = allQuestions.sort(() => 0.5 - Math.random()).slice(0, count); |
| currentQuestionIndex = 0; |
| score = 0; |
| correctCount = 0; |
| incorrectCount = 0; |
| quizStartTime = Date.now(); |
| |
| document.getElementById("quizSetup").classList.add("hidden"); |
| document.getElementById("quizGame").classList.remove("hidden"); |
| document.getElementById("quizResults").classList.add("hidden"); |
| document.getElementById("quizFeedback").classList.add("hidden"); |
| |
| showQuestion(); |
| } |
| |
| function showQuestion() { |
| const question = currentQuiz[currentQuestionIndex]; |
| document.getElementById("questionText").textContent = question.q; |
| document.getElementById("currentScore").textContent = score; |
| |
| const optionsContainer = document.getElementById("answerOptions"); |
| optionsContainer.innerHTML = ""; |
| |
| question.options.forEach((option, index) => { |
| const btn = document.createElement("button"); |
| btn.className = "quiz-option"; |
| btn.textContent = option; |
| btn.onclick = () => selectAnswer(btn, index); |
| optionsContainer.appendChild(btn); |
| }); |
| |
| // Update progress bar |
| const progress = ((currentQuestionIndex) / currentQuiz.length) * 100; |
| document.getElementById("quizProgressFill").style.width = progress + "%"; |
| |
| document.getElementById("quizFeedback").classList.add("hidden"); |
| } |
| |
| function selectAnswer(btn, selectedIndex) { |
| const question = currentQuiz[currentQuestionIndex]; |
| const isCorrect = selectedIndex === question.correct; |
| const options = document.querySelectorAll(".quiz-option"); |
| |
| options.forEach((opt, idx) => { |
| opt.classList.add("disabled"); |
| if (idx === question.correct) { |
| opt.classList.add("correct"); |
| } else if (idx === selectedIndex && !isCorrect) { |
| opt.classList.add("incorrect"); |
| } |
| }); |
| |
| if (isCorrect) { |
| score += 10; |
| correctCount++; |
| playSuccessSound(); |
| fireConfetti(); |
| showFeedback(true, question.explanation); |
| } else { |
| incorrectCount++; |
| playErrorSound(); |
| showFeedback(false, question.explanation); |
| } |
| |
| document.getElementById("currentScore").textContent = score; |
| } |
| |
| function showFeedback(isCorrect, explanation) { |
| const feedback = document.getElementById("quizFeedback"); |
| const icon = document.getElementById("feedbackIcon"); |
| const title = document.getElementById("feedbackTitle"); |
| const exp = document.getElementById("feedbackExplanation"); |
| |
| icon.innerHTML = isCorrect ? "<i class=\"fas fa-check-circle\"></i>" : "<i class=\"fas fa-times-circle\"></i>"; |
| icon.className = "feedback-icon " + (isCorrect ? "correct" : "incorrect"); |
| title.textContent = isCorrect ? "Correct!" : "Incorrect!"; |
| title.style.color = isCorrect ? "var(--success)" : "var(--accent)"; |
| exp.textContent = explanation; |
| |
| feedback.classList.remove("hidden"); |
| } |
| |
| function nextQuestion() { |
| currentQuestionIndex++; |
| if (currentQuestionIndex < currentQuiz.length) { |
| showQuestion(); |
| } else { |
| showResults(); |
| } |
| } |
| |
| function showResults() { |
| const timeTaken = Math.floor((Date.now() - quizStartTime) / 1000); |
| const minutes = Math.floor(timeTaken / 60); |
| const seconds = timeTaken % 60; |
| const percentage = Math.round((correctCount / currentQuiz.length) * 100); |
| |
| document.getElementById("percentage").textContent = percentage + "%"; |
| document.getElementById("correctCount").textContent = correctCount; |
| document.getElementById("incorrectCount").textContent = incorrectCount; |
| |
| document.getElementById("quizQuestionContainer").classList.add("hidden"); |
| document.getElementById("quizFeedback").classList.add("hidden"); |
| document.getElementById("quizResults").classList.remove("hidden"); |
| document.getElementById("quizProgressFill").style.width = "100%"; |
| |
| if (percentage >= 80) { |
| fireConfetti(); |
| playSuccessSound(); |
| } |
| } |
| |
| function restartQuiz() { |
| currentQuestionIndex = 0; |
| score = 0; |
| correctCount = 0; |
| incorrectCount = 0; |
| document.getElementById("quizResults").classList.add("hidden"); |
| document.getElementById("quizQuestionContainer").classList.remove("hidden"); |
| showQuestion(); |
| } |
| |
| function backToSetup() { |
| document.getElementById("quizGame").classList.add("hidden"); |
| document.getElementById("quizSetup").classList.remove("hidden"); |
| document.getElementById("quizResults").classList.add("hidden"); |
| } |
| |
| // Confetti Effect |
| function fireConfetti() { |
| const canvas = document.getElementById("confettiCanvas"); |
| if (!canvas) return; |
| |
| const ctx = canvas.getContext("2d"); |
| canvas.width = window.innerWidth; |
| canvas.height = window.innerHeight; |
| |
| const colors = ["#00d4ff", "#a855f7", "#f43f5e", "#22c55e", "#f59e0b"]; |
| const particles = []; |
| |
| for (let i = 0; i < 100; i++) { |
| particles.push({ |
| x: canvas.width / 2, |
| y: canvas.height / 2, |
| vx: (Math.random() - 0.5) * 15, |
| vy: (Math.random() - 0.5) * 15 - 5, |
| color: colors[Math.floor(Math.random() * colors.length)], |
| size: Math.random() * 8 + 4, |
| life: 1 |
| }); |
| } |
| |
| function animate() { |
| ctx.clearRect(0, 0, canvas.width, canvas.height); |
| |
| particles.forEach((p, i) => { |
| p.x += p.vx; |
| p.y += p.vy; |
| p.vy += 0.3; // gravity |
| p.life -= 0.02; |
| |
| ctx.globalAlpha = p.life; |
| ctx.fillRect(p.x, p.y, p.size, p.size); |
| |
| if (p.life <= 0) particles.splice(i, 1); |
| }); |
| |
| if (particles.length > 0) { |
| requestAnimationFrame(animate); |
| } |
| } |
| |
| animate(); |
| } |
| |
| // Sound Effects (using AudioContext for beeps) |
| function playSuccessSound() { |
| try { |
| const AudioContext = window.AudioContext || window.webkitAudioContext; |
| if (!AudioContext) return; |
| |
| const ctx = new AudioContext(); |
| const osc = ctx.createOscillator(); |
| const gain = ctx.createGain(); |
| |
| osc.connect(gain); |
| gain.connect(ctx.destination); |
| |
| osc.frequency.value = 880; // A5 note |
| osc.type = "sine"; |
| |
| 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); |
| |
| // Second note for success |
| setTimeout(() => { |
| const osc2 = ctx.createOscillator(); |
| const gain2 = ctx.createGain(); |
| osc2.connect(gain2); |
| gain2.connect(ctx.destination); |
| osc2.frequency.value = 1109; // C#6 |
| gain2.gain.setValueAtTime(0.3, ctx.currentTime); |
| gain2.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + 0.3); |
| osc2.start(ctx.currentTime); |
| osc2.stop(ctx.currentTime + 0.3); |
| }, 150); |
| } catch (e) {} |
| } |
| |
| function playErrorSound() { |
| try { |
| const AudioContext = window.AudioContext || window.webkitAudioContext; |
| if (!AudioContext) return; |
| |
| const ctx = new AudioContext(); |
| const osc = ctx.createOscillator(); |
| const gain = ctx.createGain(); |
| |
| osc.connect(gain); |
| gain.connect(ctx.destination); |
| |
| osc.frequency.value = 200; // Low tone |
| osc.type = "sawtooth"; |
| |
| gain.gain.setValueAtTime(0.3, ctx.currentTime); |
| gain.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + 0.4); |
| |
| osc.start(ctx.currentTime); |
| osc.stop(ctx.currentTime + 0.4); |
| } catch (e) {} |
| } |
| |
| // Knowledge Map Visualization |
| let knowledgeMapData = [ |
| { name: "Quantum Mechanics", mastery: 85, category: "physics", x: 0.2, y: 0.3 }, |
| { name: "Linear Algebra", mastery: 72, category: "math", x: 0.5, y: 0.2 }, |
| { name: "Thermodynamics", mastery: 63, category: "physics", x: 0.7, y: 0.4 }, |
| { name: "Organic Chemistry", mastery: 91, category: "chemistry", x: 0.3, y: 0.6 }, |
| { name: "Differential Equations", mastery: 45, category: "math", x: 0.6, y: 0.7 }, |
| { name: "Cell Biology", mastery: 88, category: "biology", x: 0.1, y: 0.5 }, |
| { name: "World History", mastery: 76, category: "history", x: 0.8, y: 0.2 }, |
| { name: "Machine Learning", mastery: 68, category: "computer", x: 0.4, y: 0.4 }, |
| { name: "Literature", mastery: 82, category: "literature", x: 0.9, y: 0.6 }, |
| { name: "Geography", mastery: 79, category: "geography", x: 0.2, y: 0.8 } |
| ]; |
| |
| let currentFilter = "all"; |
| let currentView = "constellation"; |
| |
| function initKnowledgeMap() { |
| const canvas = document.getElementById("knowledgeCanvas"); |
| if (!canvas) return; |
| |
| const ctx = canvas.getContext("2d"); |
| canvas.width = canvas.offsetWidth; |
| canvas.height = canvas.offsetHeight; |
| |
| let animationFrame; |
| let hoveredNode = null; |
| |
| function draw() { |
| ctx.clearRect(0, 0, canvas.width, canvas.height); |
| |
| const filtered = currentFilter === "all" |
| ? knowledgeMapData |
| : knowledgeMapData.filter(d => { |
| if (currentFilter === "strong") return d.mastery >= 80; |
| if (currentFilter === "weak") return d.mastery < 60; |
| if (currentFilter === "recent") return d.mastery > 0; |
| return true; |
| }); |
| |
| // Draw connections |
| ctx.lineWidth = 1; |
| for (let i = 0; i < filtered.length; i++) { |
| for (let j = i + 1; j < filtered.length; j++) { |
| const d1 = filtered[i]; |
| const d2 = filtered[j]; |
| const x1 = d1.x * canvas.width; |
| const y1 = d1.y * canvas.height; |
| const x2 = d2.x * canvas.width; |
| const y2 = d2.y * canvas.height; |
| const dist = Math.sqrt((x2-x1)**2 + (y2-y1)**2); |
| if (dist < 200) { |
| ctx.beginPath(); |
| ctx.moveTo(x1, y1); |
| ctx.lineTo(x2, y2); |
| ctx.stroke(); |
| } |
| } |
| } |
| |
| // Draw nodes |
| filtered.forEach(node => { |
| const x = node.x * canvas.width; |
| const y = node.y * canvas.height; |
| const radius = 15 + (node.mastery / 100) * 20; |
| const isHovered = hoveredNode === node; |
| |
| // Color based on mastery |
| let color; |
| if (node.mastery >= 80) color = "#22c55e"; |
| else if (node.mastery >= 60) color = "#00d4ff"; |
| else if (node.mastery >= 40) color = "#f59e0b"; |
| else color = "#f43f5e"; |
| |
| // Glow effect |
| const gradient = ctx.createRadialGradient(x, y, 0, x, y, radius * 2); |
| gradient.addColorStop(0, color + "40"); |
| gradient.addColorStop(1, "transparent"); |
| ctx.beginPath(); |
| ctx.arc(x, y, radius * 2, 0, Math.PI * 2); |
| ctx.fill(); |
| |
| // Main circle |
| ctx.beginPath(); |
| ctx.arc(x, y, radius, 0, Math.PI * 2); |
| ctx.fill(); |
| |
| // Border |
| ctx.lineWidth = isHovered ? 3 : 2; |
| ctx.stroke(); |
| |
| // Label |
| ctx.font = "12px sans-serif"; |
| ctx.textAlign = "center"; |
| ctx.fillText(node.name, x, y + radius + 20); |
| ctx.fillText(node.mastery + "%", x, y + radius + 35); |
| }); |
| |
| animationFrame = requestAnimationFrame(draw); |
| } |
| |
| // Mouse interactions |
| canvas.addEventListener("mousemove", (e) => { |
| const rect = canvas.getBoundingClientRect(); |
| const x = e.clientX - rect.left; |
| const y = e.clientY - rect.top; |
| |
| hoveredNode = knowledgeMapData.find(node => { |
| const nx = node.x * canvas.width; |
| const ny = node.y * canvas.height; |
| const dist = Math.sqrt((x - nx)**2 + (y - ny)**2); |
| return dist < 30; |
| }); |
| |
| canvas.style.cursor = hoveredNode ? "pointer" : "grab"; |
| }); |
| |
| canvas.addEventListener("click", () => { |
| if (hoveredNode) { |
| showTopicDetails(hoveredNode.name); |
| } |
| }); |
| |
| draw(); |
| } |
| |
| function filterMap(filter) { |
| currentFilter = filter; |
| document.querySelectorAll(".filter-btn").forEach(btn => btn.classList.remove("active")); |
| event.target.classList.add("active"); |
| } |
| |
| function setMapView(view) { |
| currentView = view; |
| document.querySelectorAll(".view-btn").forEach(btn => btn.classList.remove("active")); |
| event.target.classList.add("active"); |
| } |
| |
| function showTopicDetails(topic) { |
| const modal = document.createElement("div"); |
| modal.style.cssText = "position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.8); z-index: 1000; display: flex; align-items: center; justify-content: center;"; |
| modal.innerHTML = ` |
| <strong style="font-size: 24px; color: var(--primary);">24</strong> |
| // </div> |
| <strong style="font-size: 24px; color: var(--success);">85%</strong> |
| // </div> |
| // </div> |
| // <button class="secondary-button" onclick="this.parentElement.parentElement.parentElement.remove()">Close</button> |
| // </div> |
| // </div> |
| `; |
| document.body.appendChild(modal); |
| modal.onclick = (e) => { if (e.target === modal) modal.remove(); }; |
| } |
| |
| function startStudying(topic) { |
| location.href = "/practice?topic=" + encodeURIComponent(topic); |
| } |
| |
| // Initialize knowledge map on page load |
| if (document.getElementById("knowledgeCanvas")) { |
| initKnowledgeMap(); |
| } |
| |
| // Pomodoro Timer |
| let pomodoroTime = 25 * 60; |
| let pomodoroInterval = null; |
| let isBreak = false; |
| |
| function initPomodoro() { |
| const display = document.getElementById("pomodoroDisplay"); |
| if (!display) return; |
| updatePomodoroDisplay(); |
| } |
| |
| function updatePomodoroDisplay() { |
| const display = document.getElementById("pomodoroDisplay"); |
| if (!display) return; |
| const minutes = Math.floor(pomodoroTime / 60).toString().padStart(2, "0"); |
| const seconds = (pomodoroTime % 60).toString().padStart(2, "0"); |
| } |
| |
| function startPomodoro() { |
| if (pomodoroInterval) return; |
| pomodoroInterval = setInterval(() => { |
| pomodoroTime--; |
| updatePomodoroDisplay(); |
| if (pomodoroTime <= 0) { |
| clearInterval(pomodoroInterval); |
| pomodoroInterval = null; |
| playSuccessSound(); |
| alert(isBreak ? "Break over! Time to study." : "Pomodoro complete! Take a break."); |
| isBreak = !isBreak; |
| pomodoroTime = isBreak ? 5 * 60 : 25 * 60; |
| updatePomodoroDisplay(); |
| } |
| }, 1000); |
| } |
| |
| function pausePomodoro() { |
| if (pomodoroInterval) { |
| clearInterval(pomodoroInterval); |
| pomodoroInterval = null; |
| } |
| } |
| |
| function resetPomodoro() { |
| pausePomodoro(); |
| isBreak = false; |
| pomodoroTime = 25 * 60; |
| updatePomodoroDisplay(); |
| document.title = "FlashSync - Advanced Learning Platform"; |
| } |
| |
| // Music Player for Study Lo-Fi |
| const studyTracks = [ |
| { name: "Deep Focus", url: "https://www.youtube.com/embed/jfKfPfyJRdk", type: "lofi" }, |
| { name: "Study Beats", url: "https://www.youtube.com/embed/4xDzrJKXOOY", type: "lofi" }, |
| { name: "Rain Sounds", url: "https://www.youtube.com/embed/q76bMs-NwRk", type: "ambient" }, |
| { name: "Classical Focus", url: "https://www.youtube.com/embed/mIYzp5rcTvU", type: "classical" } |
| ]; |
| |
| let currentTrack = 0; |
| let isPlaying = false; |
| |
| function playMusic() { |
| const player = document.getElementById("musicPlayer"); |
| if (player) { |
| player.src = studyTracks[currentTrack].url + "?autoplay=1"; |
| isPlaying = true; |
| updateMusicUI(); |
| } |
| } |
| |
| function pauseMusic() { |
| const player = document.getElementById("musicPlayer"); |
| if (player) { |
| player.src = ""; |
| isPlaying = false; |
| updateMusicUI(); |
| } |
| } |
| |
| function nextTrack() { |
| currentTrack = (currentTrack + 1) % studyTracks.length; |
| if (isPlaying) playMusic(); |
| updateMusicUI(); |
| } |
| |
| function prevTrack() { |
| currentTrack = (currentTrack - 1 + studyTracks.length) % studyTracks.length; |
| if (isPlaying) playMusic(); |
| updateMusicUI(); |
| } |
| |
| function updateMusicUI() { |
| const trackName = document.getElementById("currentTrackName"); |
| const playBtn = document.getElementById("playMusicBtn"); |
| if (trackName) trackName.textContent = studyTracks[currentTrack].name; |
| if (playBtn) playBtn.innerHTML = isPlaying ? "<i class="fas fa-pause"></i>" : "<i class="fas fa-play"></i>"; |
| } |
| |
| // Drawing Canvas |
| let isDrawing = false; |
| let lastX = 0; |
| let lastY = 0; |
| |
| function initDrawingCanvas() { |
| const canvas = document.getElementById("drawingCanvas"); |
| if (!canvas) return; |
| |
| const ctx = canvas.getContext("2d"); |
| ctx.lineWidth = 3; |
| ctx.lineCap = "round"; |
| ctx.lineJoin = "round"; |
| |
| canvas.addEventListener("mousedown", startDrawing); |
| canvas.addEventListener("mousemove", draw); |
| canvas.addEventListener("mouseup", stopDrawing); |
| canvas.addEventListener("mouseout", stopDrawing); |
| |
| canvas.addEventListener("touchstart", (e) => { |
| e.preventDefault(); |
| const touch = e.touches[0]; |
| const rect = canvas.getBoundingClientRect(); |
| startDrawing({ offsetX: touch.clientX - rect.left, offsetY: touch.clientY - rect.top }); |
| }); |
| canvas.addEventListener("touchmove", (e) => { |
| e.preventDefault(); |
| const touch = e.touches[0]; |
| const rect = canvas.getBoundingClientRect(); |
| draw({ offsetX: touch.clientX - rect.left, offsetY: touch.clientY - rect.top }); |
| }); |
| canvas.addEventListener("touchend", stopDrawing); |
| } |
| |
| function startDrawing(e) { |
| isDrawing = true; |
| lastX = e.offsetX; |
| lastY = e.offsetY; |
| } |
| |
| function draw(e) { |
| if (!isDrawing) return; |
| const canvas = document.getElementById("drawingCanvas"); |
| const ctx = canvas.getContext("2d"); |
| ctx.beginPath(); |
| ctx.moveTo(lastX, lastY); |
| ctx.lineTo(e.offsetX, e.offsetY); |
| ctx.stroke(); |
| lastX = e.offsetX; |
| lastY = e.offsetY; |
| } |
| |
| function stopDrawing() { |
| isDrawing = false; |
| } |
| |
| function clearDrawing() { |
| const canvas = document.getElementById("drawingCanvas"); |
| if (canvas) { |
| const ctx = canvas.getContext("2d"); |
| ctx.clearRect(0, 0, canvas.width, canvas.height); |
| } |
| } |
| |
| function saveDrawing() { |
| const canvas = document.getElementById("drawingCanvas"); |
| if (canvas) { |
| const link = document.createElement("a"); |
| link.download = "my-drawing-" + Date.now() + ".png"; |
| link.href = canvas.toDataURL(); |
| link.click(); |
| } |
| } |
| |
| function changeBrushColor(color) { |
| const canvas = document.getElementById("drawingCanvas"); |
| if (canvas) { |
| const ctx = canvas.getContext("2d"); |
| } |
| } |
| |
| function changeBrushSize(size) { |
| const canvas = document.getElementById("drawingCanvas"); |
| if (canvas) { |
| const ctx = canvas.getContext("2d"); |
| ctx.lineWidth = parseInt(size); |
| } |
| } |
| |
| // Mock Exams |
| let currentExam = null; |
| let examQuestionIndex = 0; |
| let examScore = 0; |
| let examAnswers = []; |
| |
| function startMockExam(subject) { |
| const exams = { |
| biology: { name: "Biology 101", questions: quizDatabase.biology.slice(0, 10), time: 600 }, |
| chemistry: { name: "Chemistry Fundamentals", questions: quizDatabase.chemistry.slice(0, 10), time: 600 }, |
| physics: { name: "Physics Basics", questions: quizDatabase.physics.slice(0, 10), time: 600 } |
| }; |
| |
| currentExam = exams[subject]; |
| examQuestionIndex = 0; |
| examScore = 0; |
| examAnswers = []; |
| |
| document.getElementById("examSetup").classList.add("hidden"); |
| document.getElementById("examSession").classList.remove("hidden"); |
| document.getElementById("examResults").classList.add("hidden"); |
| |
| document.getElementById("examTitle").textContent = currentExam.name; |
| startExamTimer(currentExam.time); |
| showExamQuestion(); |
| } |
| |
| function startExamTimer(seconds) { |
| let timeLeft = seconds; |
| const timerEl = document.getElementById("examTimer"); |
| |
| window.examTimerInterval = setInterval(() => { |
| timeLeft--; |
| const mins = Math.floor(timeLeft / 60).toString().padStart(2, "0"); |
| const secs = (timeLeft % 60).toString().padStart(2, "0"); |
| |
| if (timeLeft <= 0) { |
| clearInterval(window.examTimerInterval); |
| finishExam(); |
| } |
| }, 1000); |
| } |
| |
| function showExamQuestion() { |
| const q = currentExam.questions[examQuestionIndex]; |
| document.getElementById("examQuestionText").textContent = q.q; |
| |
| const optionsEl = document.getElementById("examOptions"); |
| optionsEl.innerHTML = q.options.map((opt, i) => ` |
| `).join(""); |
| |
| } |
| |
| function selectExamAnswer(index) { |
| examAnswers[examQuestionIndex] = index; |
| document.querySelectorAll("#examOptions .quiz-option").forEach((btn, i) => { |
| btn.classList.toggle("selected", i === index); |
| }); |
| } |
| |
| function nextExamQuestion() { |
| if (examAnswers[examQuestionIndex] === undefined) { |
| alert("Please select an answer"); |
| return; |
| } |
| examQuestionIndex++; |
| if (examQuestionIndex < currentExam.questions.length) { |
| showExamQuestion(); |
| } else { |
| finishExam(); |
| } |
| } |
| |
| function finishExam() { |
| clearInterval(window.examTimerInterval); |
| |
| examScore = examAnswers.reduce((score, answer, i) => { |
| return score + (answer === currentExam.questions[i].correct ? 1 : 0); |
| }, 0); |
| |
| const percentage = Math.round((examScore / currentExam.questions.length) * 100); |
| |
| document.getElementById("examSession").classList.add("hidden"); |
| document.getElementById("examResults").classList.remove("hidden"); |
| |
| document.getElementById("examGrade").textContent = percentage >= 90 ? "A" : percentage >= 80 ? "B" : percentage >= 70 ? "C" : percentage >= 60 ? "D" : "F"; |
| document.getElementById("examCorrect").textContent = examScore; |
| document.getElementById("examIncorrect").textContent = currentExam.questions.length - examScore; |
| |
| if (percentage >= 80) { |
| fireConfetti(); |
| playSuccessSound(); |
| } |
| } |
| |
| // Language switching (single selection) |
| let currentLanguage = localStorage.getItem("language") || "en"; |
| |
| function setLanguage(lang) { |
| currentLanguage = lang; |
| localStorage.setItem("language", lang); |
| |
| // Update UI to show only one active |
| document.querySelectorAll(".lang-btn").forEach(btn => { |
| btn.classList.remove("active"); |
| btn.classList.add("active"); |
| } |
| }); |
| |
| // Apply translations |
| applyTranslations(lang); |
| |
| alert("Language changed to " + lang.toUpperCase()); |
| } |
| |
| function applyTranslations(lang) { |
| const translations = { |
| nl: { study: "Studeren", dashboard: "Dashboard", practice: "Oefenen", settings: "Instellingen" }, |
| es: { study: "Estudiar", dashboard: "Panel", practice: "Práctica", settings: "Ajustes" }, |
| fr: { study: "Étudier", dashboard: "Tableau", practice: "Pratique", settings: "Paramètres" }, |
| de: { study: "Lernen", dashboard: "Übersicht", practice: "Üben", settings: "Einstellungen" } |
| }; |
| |
| const t = translations[lang]; |
| if (!t) return; |
| |
| // Update navigation labels |
| document.querySelectorAll(".nav-label").forEach(el => { |
| if (el.textContent === "Study" && t.study) el.textContent = t.study; |
| }); |
| } |
| |
| // Initialize all features on page load |
| document.addEventListener("DOMContentLoaded", function() { |
| initKnowledgeMap(); |
| initPomodoro(); |
| initDrawingCanvas(); |
| |
| // Initialize file manager if on file-manager page |
| if (document.querySelector(".file-grid")) { |
| renderFileList(); |
| updateStorageIndicator(); |
| } |
| }); |
| " |
| } |
|
|
| @external(erlang, "timer", "sleep") |
| fn erlang_sleep(ms: Int) -> Nil |
|
|
| fn sleep_forever() { |
| erlang_sleep(1000) |
| sleep_forever() |
| } |
|
|
|
|