Upload 4 files
Browse files- Apache License.txt +17 -0
- README.md +104 -0
- index.html +2036 -0
- 📘 Educator & Student Guide Educati.txt +78 -0
Apache License.txt
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Apache License
|
| 2 |
+
Version 2.0, January 2004
|
| 3 |
+
http://www.apache.org/licenses/
|
| 4 |
+
|
| 5 |
+
Copyright 2025 Shift Mind AI Labs
|
| 6 |
+
|
| 7 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
| 8 |
+
you may not use this file except in compliance with the License.
|
| 9 |
+
You may obtain a copy of the License at
|
| 10 |
+
|
| 11 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
| 12 |
+
|
| 13 |
+
Unless required by applicable law or agreed to in writing, software
|
| 14 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
| 15 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 16 |
+
See the License for the specific language governing permissions and
|
| 17 |
+
limitations under the License.
|
README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: "🧠 Educational Activity Intelligence Analyzer"
|
| 3 |
+
emoji: "📊"
|
| 4 |
+
colorFrom: "indigo"
|
| 5 |
+
colorTo: "yellow"
|
| 6 |
+
sdk: "static"
|
| 7 |
+
sdk_version: "0.1.0"
|
| 8 |
+
app_file: "index.html"
|
| 9 |
+
pinned: false
|
| 10 |
+
---
|
| 11 |
+
|
| 12 |
+
# 🧠 Educational Activity Intelligence Analyzer
|
| 13 |
+
**Developed by Shift Mind AI Labs**
|
| 14 |
+
|
| 15 |
+
The Educational Activity Intelligence Analyzer is an open-source, privacy-first, AI-driven platform for advanced teaching activity analysis.
|
| 16 |
+
Powered by a multi-agent system, it deeply evaluates any teaching activity using the **PICRAT Model**, **Bloom's Taxonomy**, and best practices in digital pedagogy. The tool outputs structured, actionable reports and practical scenarios—instantly, in 90+ languages, with full local privacy.
|
| 17 |
+
|
| 18 |
+
---
|
| 19 |
+
|
| 20 |
+
## 🚀 Features
|
| 21 |
+
|
| 22 |
+
- **Multi-Agent Deep Analysis:**
|
| 23 |
+
Three specialized AI agents deliver structured PICRAT + Bloom’s evaluation, practical enhancement scenarios, and meta-level recommendations.
|
| 24 |
+
- **Custom Scenario Input:**
|
| 25 |
+
Paste or describe any lesson or teaching activity for a bespoke, professional review.
|
| 26 |
+
- **Multilingual UI & Output:**
|
| 27 |
+
Supports 90+ languages (OpenAI API required; 100% local processing).
|
| 28 |
+
- **Practical Recommendations:**
|
| 29 |
+
Includes critical thinking assessment, tech integration strategies, and real-world classroom scenarios.
|
| 30 |
+
- **Modern UI:**
|
| 31 |
+
Clean, accessible interface; RTL/LTR support, instant translation, color-coded cards.
|
| 32 |
+
- **Privacy-First:**
|
| 33 |
+
API key and content **never** leave your browser/device.
|
| 34 |
+
|
| 35 |
+
---
|
| 36 |
+
|
| 37 |
+
## 🛠 How to Use
|
| 38 |
+
|
| 39 |
+
1. **Open the tool** in your browser (local or Hugging Face Space).
|
| 40 |
+
2. **Select your language** and enter your OpenAI API key (stored only in your browser).
|
| 41 |
+
3. **Describe your teaching activity** (minimum 10 characters for valid input).
|
| 42 |
+
4. **Click “Analyze Activity”**.
|
| 43 |
+
5. **Read and copy** the 3-agent outputs:
|
| 44 |
+
- *Agent 1:* PICRAT/Bloom’s critical analysis
|
| 45 |
+
- *Agent 2:* Practical scenarios and improvement strategies
|
| 46 |
+
- *Agent 3:* Meta-analysis and recommendations
|
| 47 |
+
6. **Switch languages or clear cache** as needed (RTL/LTR fully supported).
|
| 48 |
+
|
| 49 |
+
---
|
| 50 |
+
|
| 51 |
+
## 👩🏫 For Educators: Use Cases
|
| 52 |
+
|
| 53 |
+
- **Lesson/Activity Evaluation:**
|
| 54 |
+
Get instant, expert-aligned feedback for lesson plans or classroom activities.
|
| 55 |
+
- **Professional Development:**
|
| 56 |
+
Analyze and improve tech integration, student engagement, and higher-order thinking.
|
| 57 |
+
- **Differentiation & Reflection:**
|
| 58 |
+
Output can be used for teacher reflection, peer review, and portfolio evidence.
|
| 59 |
+
- **Multilingual Classrooms:**
|
| 60 |
+
Instantly switch UI/output to support ELLs and international staff.
|
| 61 |
+
|
| 62 |
+
---
|
| 63 |
+
|
| 64 |
+
## 👨🎓 For Students/Researchers
|
| 65 |
+
|
| 66 |
+
- **Study Effective Teaching:**
|
| 67 |
+
See practical breakdowns of teaching models and their cognitive impact.
|
| 68 |
+
- **Scenario Planning:**
|
| 69 |
+
Use agent outputs as templates for assignments or educational design.
|
| 70 |
+
- **Cross-language Analysis:**
|
| 71 |
+
Analyze teaching activities in both your native language and English.
|
| 72 |
+
|
| 73 |
+
---
|
| 74 |
+
|
| 75 |
+
## 🔐 Data Privacy
|
| 76 |
+
|
| 77 |
+
- Your OpenAI API key and all activity data **never leave your device**.
|
| 78 |
+
- Nothing is transmitted to Shift Mind AI Labs, Hugging Face, or third parties.
|
| 79 |
+
|
| 80 |
+
---
|
| 81 |
+
|
| 82 |
+
## 📄 License
|
| 83 |
+
|
| 84 |
+
Licensed under the [Apache License 2.0](./LICENSE).
|
| 85 |
+
|
| 86 |
+
---
|
| 87 |
+
|
| 88 |
+
## 🧠 About Shift Mind AI Labs
|
| 89 |
+
|
| 90 |
+
Shift Mind AI Labs creates open-source, ethical AI tools for education and digital transformation.
|
| 91 |
+
|
| 92 |
+
🌐 https://www.shiftmind.io
|
| 93 |
+
✉️ info@shiftmind.io
|
| 94 |
+
|
| 95 |
+
---
|
| 96 |
+
|
| 97 |
+
## 🙌 Contributing
|
| 98 |
+
|
| 99 |
+
Feedback, feature requests, and collaborations are welcome!
|
| 100 |
+
For research pilots or integration partnerships: **info@shiftmind.io**
|
| 101 |
+
|
| 102 |
+
---
|
| 103 |
+
|
| 104 |
+
*Enabling teachers and students everywhere to optimize learning activities—securely, ethically, and with deep insight.*
|
index.html
ADDED
|
@@ -0,0 +1,2036 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en" dir="ltr">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Educational Activity Intelligence Analyzer</title>
|
| 7 |
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 8 |
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 9 |
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
| 10 |
+
|
| 11 |
+
<style>
|
| 12 |
+
/* CSS Reset and Base Styles */
|
| 13 |
+
*, *::before, *::after {
|
| 14 |
+
box-sizing: border-box;
|
| 15 |
+
margin: 0;
|
| 16 |
+
padding: 0;
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
/* CSS Custom Properties */
|
| 20 |
+
:root {
|
| 21 |
+
/* Color System - Intelligence/Analysis theme */
|
| 22 |
+
--color-primary: #7c3aed;
|
| 23 |
+
--color-primary-hover: #6d28d9;
|
| 24 |
+
--color-secondary: #3b82f6;
|
| 25 |
+
--color-accent: #8b5cf6;
|
| 26 |
+
--color-success: #10b981;
|
| 27 |
+
--color-warning: #f59e0b;
|
| 28 |
+
--color-error: #ef4444;
|
| 29 |
+
|
| 30 |
+
/* Neutral Colors - Light Mode */
|
| 31 |
+
--color-background: #faf7ff;
|
| 32 |
+
--color-surface: #ffffff;
|
| 33 |
+
--color-surface-elevated: #ffffff;
|
| 34 |
+
--color-border: #e9d5ff;
|
| 35 |
+
--color-border-focus: #7c3aed;
|
| 36 |
+
--color-text-primary: #1f2937;
|
| 37 |
+
--color-text-secondary: #4b5563;
|
| 38 |
+
--color-text-muted: #6b7280;
|
| 39 |
+
|
| 40 |
+
/* Typography */
|
| 41 |
+
--font-family-primary: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
| 42 |
+
|
| 43 |
+
/* Optimized Spacing System */
|
| 44 |
+
--spacing-xs: 0.25rem;
|
| 45 |
+
--spacing-sm: 0.5rem;
|
| 46 |
+
--spacing-md: 0.75rem;
|
| 47 |
+
--spacing-lg: 1rem;
|
| 48 |
+
--spacing-xl: 1.25rem;
|
| 49 |
+
--spacing-2xl: 1.5rem;
|
| 50 |
+
--spacing-3xl: 2rem;
|
| 51 |
+
|
| 52 |
+
/* Border Radius */
|
| 53 |
+
--radius-sm: 0.375rem;
|
| 54 |
+
--radius-md: 0.5rem;
|
| 55 |
+
--radius-lg: 0.75rem;
|
| 56 |
+
--radius-xl: 1rem;
|
| 57 |
+
|
| 58 |
+
/* Shadows */
|
| 59 |
+
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
| 60 |
+
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
| 61 |
+
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
| 62 |
+
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
|
| 63 |
+
|
| 64 |
+
/* Transitions */
|
| 65 |
+
--transition-fast: 150ms ease-in-out;
|
| 66 |
+
--transition-normal: 250ms ease-in-out;
|
| 67 |
+
--transition-slow: 350ms ease-in-out;
|
| 68 |
+
|
| 69 |
+
/* Layout */
|
| 70 |
+
--container-max-width: 1200px;
|
| 71 |
+
--content-max-width: 1000px;
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
/* RTL Support */
|
| 75 |
+
[dir="rtl"] {
|
| 76 |
+
text-align: right;
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
[dir="rtl"] .app-container {
|
| 80 |
+
direction: rtl;
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
[dir="rtl"] .api-key-compact {
|
| 84 |
+
left: auto;
|
| 85 |
+
right: var(--spacing-lg);
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
[dir="rtl"] .language-switcher {
|
| 89 |
+
right: auto;
|
| 90 |
+
left: var(--spacing-lg);
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
/* Dark Mode Support */
|
| 94 |
+
@media (prefers-color-scheme: dark) {
|
| 95 |
+
:root {
|
| 96 |
+
--color-background: #0f0a1a;
|
| 97 |
+
--color-surface: #1e1b31;
|
| 98 |
+
--color-surface-elevated: #2d2a45;
|
| 99 |
+
--color-border: #2d2a45;
|
| 100 |
+
--color-text-primary: #f9fafb;
|
| 101 |
+
--color-text-secondary: #d1d5db;
|
| 102 |
+
--color-text-muted: #9ca3af;
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
/* Base Styles */
|
| 107 |
+
html {
|
| 108 |
+
font-size: 16px;
|
| 109 |
+
line-height: 1.5;
|
| 110 |
+
scroll-behavior: smooth;
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
body {
|
| 114 |
+
font-family: var(--font-family-primary);
|
| 115 |
+
background-color: var(--color-background);
|
| 116 |
+
color: var(--color-text-primary);
|
| 117 |
+
line-height: 1.5;
|
| 118 |
+
-webkit-font-smoothing: antialiased;
|
| 119 |
+
-moz-osx-font-smoothing: grayscale;
|
| 120 |
+
min-height: 100vh;
|
| 121 |
+
transition: all 0.3s ease;
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
/* Language Selection Landing */
|
| 125 |
+
.language-landing {
|
| 126 |
+
display: block;
|
| 127 |
+
max-width: 600px;
|
| 128 |
+
margin: 50px auto;
|
| 129 |
+
background: var(--color-surface);
|
| 130 |
+
border-radius: var(--radius-xl);
|
| 131 |
+
box-shadow: var(--shadow-lg);
|
| 132 |
+
padding: 40px;
|
| 133 |
+
text-align: center;
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
.language-landing h1 {
|
| 137 |
+
font-size: 2.5rem;
|
| 138 |
+
font-weight: 800;
|
| 139 |
+
background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-secondary) 100%);
|
| 140 |
+
-webkit-background-clip: text;
|
| 141 |
+
-webkit-text-fill-color: transparent;
|
| 142 |
+
background-clip: text;
|
| 143 |
+
margin-bottom: 15px;
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
.language-landing p {
|
| 147 |
+
font-size: 1.1rem;
|
| 148 |
+
color: var(--color-text-secondary);
|
| 149 |
+
margin-bottom: 30px;
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
.language-selector {
|
| 153 |
+
margin-bottom: 25px;
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
.language-selector label {
|
| 157 |
+
display: block;
|
| 158 |
+
margin-bottom: 10px;
|
| 159 |
+
font-weight: 600;
|
| 160 |
+
color: var(--color-text-primary);
|
| 161 |
+
font-size: 1.1rem;
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
.language-selector select {
|
| 165 |
+
width: 100%;
|
| 166 |
+
padding: 15px 20px;
|
| 167 |
+
border: 2px solid var(--color-border);
|
| 168 |
+
border-radius: var(--radius-lg);
|
| 169 |
+
font-size: 1.1rem;
|
| 170 |
+
font-family: inherit;
|
| 171 |
+
background: var(--color-surface);
|
| 172 |
+
transition: all 0.2s ease;
|
| 173 |
+
margin-bottom: 20px;
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
.language-selector select:focus {
|
| 177 |
+
outline: none;
|
| 178 |
+
border-color: var(--color-border-focus);
|
| 179 |
+
box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.1);
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
.api-key-landing {
|
| 183 |
+
margin-bottom: 25px;
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
.api-key-landing label {
|
| 187 |
+
display: block;
|
| 188 |
+
margin-bottom: 10px;
|
| 189 |
+
font-weight: 600;
|
| 190 |
+
color: var(--color-text-primary);
|
| 191 |
+
font-size: 1.1rem;
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
.api-key-landing input {
|
| 195 |
+
width: 100%;
|
| 196 |
+
padding: 15px 20px;
|
| 197 |
+
border: 2px solid var(--color-border);
|
| 198 |
+
border-radius: var(--radius-lg);
|
| 199 |
+
font-size: 1.1rem;
|
| 200 |
+
background: var(--color-surface);
|
| 201 |
+
transition: all 0.2s ease;
|
| 202 |
+
font-family: 'Courier New', monospace;
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
.api-key-landing input:focus {
|
| 206 |
+
outline: none;
|
| 207 |
+
border-color: var(--color-border-focus);
|
| 208 |
+
box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.1);
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
.start-btn {
|
| 212 |
+
background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-secondary) 100%);
|
| 213 |
+
color: white;
|
| 214 |
+
padding: 18px 40px;
|
| 215 |
+
border: none;
|
| 216 |
+
border-radius: var(--radius-lg);
|
| 217 |
+
font-size: 1.2rem;
|
| 218 |
+
font-weight: 700;
|
| 219 |
+
cursor: pointer;
|
| 220 |
+
transition: all 0.3s ease;
|
| 221 |
+
width: 100%;
|
| 222 |
+
}
|
| 223 |
+
|
| 224 |
+
.start-btn:hover {
|
| 225 |
+
transform: translateY(-2px);
|
| 226 |
+
box-shadow: 0 12px 24px -8px rgba(124, 58, 237, 0.4);
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
.start-btn:disabled {
|
| 230 |
+
opacity: 0.7;
|
| 231 |
+
cursor: not-allowed;
|
| 232 |
+
transform: none;
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
/* Cache Management Section */
|
| 236 |
+
.cache-management {
|
| 237 |
+
background: rgba(124, 58, 237, 0.05);
|
| 238 |
+
border: 1px solid rgba(124, 58, 237, 0.1);
|
| 239 |
+
border-radius: var(--radius-lg);
|
| 240 |
+
padding: 20px;
|
| 241 |
+
margin-bottom: 25px;
|
| 242 |
+
text-align: center;
|
| 243 |
+
}
|
| 244 |
+
|
| 245 |
+
.cache-management h3 {
|
| 246 |
+
color: var(--color-primary);
|
| 247 |
+
margin-bottom: 15px;
|
| 248 |
+
font-size: 1.1rem;
|
| 249 |
+
font-weight: 600;
|
| 250 |
+
}
|
| 251 |
+
|
| 252 |
+
.cache-status-display {
|
| 253 |
+
background: rgba(16, 185, 129, 0.1);
|
| 254 |
+
border: 1px solid rgba(16, 185, 129, 0.2);
|
| 255 |
+
color: var(--color-success);
|
| 256 |
+
padding: 12px 16px;
|
| 257 |
+
border-radius: var(--radius-md);
|
| 258 |
+
margin-bottom: 15px;
|
| 259 |
+
font-size: 0.9rem;
|
| 260 |
+
font-weight: 500;
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
.cache-status-display.no-cache {
|
| 264 |
+
background: rgba(100, 116, 139, 0.1);
|
| 265 |
+
border-color: rgba(100, 116, 139, 0.2);
|
| 266 |
+
color: var(--color-text-secondary);
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
.clear-cache-btn {
|
| 270 |
+
background: linear-gradient(135deg, var(--color-warning) 0%, #f59e0b 100%);
|
| 271 |
+
color: white;
|
| 272 |
+
padding: 12px 24px;
|
| 273 |
+
border: none;
|
| 274 |
+
border-radius: var(--radius-md);
|
| 275 |
+
font-size: 0.9rem;
|
| 276 |
+
font-weight: 600;
|
| 277 |
+
cursor: pointer;
|
| 278 |
+
transition: all 0.3s ease;
|
| 279 |
+
}
|
| 280 |
+
|
| 281 |
+
.clear-cache-btn:hover {
|
| 282 |
+
transform: translateY(-1px);
|
| 283 |
+
box-shadow: 0 6px 12px -4px rgba(245, 158, 11, 0.4);
|
| 284 |
+
}
|
| 285 |
+
|
| 286 |
+
.clear-cache-btn:disabled {
|
| 287 |
+
opacity: 0.5;
|
| 288 |
+
cursor: not-allowed;
|
| 289 |
+
transform: none;
|
| 290 |
+
}
|
| 291 |
+
|
| 292 |
+
/* Cache Status Indicator */
|
| 293 |
+
.cache-status {
|
| 294 |
+
background: rgba(16, 185, 129, 0.1);
|
| 295 |
+
border: 1px solid rgba(16, 185, 129, 0.2);
|
| 296 |
+
color: var(--color-success);
|
| 297 |
+
padding: 8px 12px;
|
| 298 |
+
border-radius: var(--radius-sm);
|
| 299 |
+
margin-bottom: 15px;
|
| 300 |
+
font-size: 0.85rem;
|
| 301 |
+
text-align: center;
|
| 302 |
+
font-weight: 500;
|
| 303 |
+
display: none;
|
| 304 |
+
}
|
| 305 |
+
|
| 306 |
+
.cache-status.cached {
|
| 307 |
+
display: block;
|
| 308 |
+
}
|
| 309 |
+
|
| 310 |
+
.cache-status.translating {
|
| 311 |
+
background: rgba(124, 58, 237, 0.1);
|
| 312 |
+
border-color: rgba(124, 58, 237, 0.2);
|
| 313 |
+
color: var(--color-primary);
|
| 314 |
+
}
|
| 315 |
+
|
| 316 |
+
/* Translation Loading Overlay */
|
| 317 |
+
.translation-overlay {
|
| 318 |
+
position: fixed;
|
| 319 |
+
top: 0;
|
| 320 |
+
left: 0;
|
| 321 |
+
width: 100%;
|
| 322 |
+
height: 100%;
|
| 323 |
+
background: rgba(124, 58, 237, 0.9);
|
| 324 |
+
display: none;
|
| 325 |
+
justify-content: center;
|
| 326 |
+
align-items: center;
|
| 327 |
+
z-index: 10000;
|
| 328 |
+
color: white;
|
| 329 |
+
text-align: center;
|
| 330 |
+
}
|
| 331 |
+
|
| 332 |
+
.translation-content {
|
| 333 |
+
background: rgba(255, 255, 255, 0.1);
|
| 334 |
+
padding: 40px;
|
| 335 |
+
border-radius: var(--radius-xl);
|
| 336 |
+
backdrop-filter: blur(10px);
|
| 337 |
+
}
|
| 338 |
+
|
| 339 |
+
.translation-spinner {
|
| 340 |
+
width: 50px;
|
| 341 |
+
height: 50px;
|
| 342 |
+
border: 4px solid rgba(255, 255, 255, 0.3);
|
| 343 |
+
border-radius: 50%;
|
| 344 |
+
border-top-color: white;
|
| 345 |
+
animation: spin 1s ease-in-out infinite;
|
| 346 |
+
margin: 0 auto 20px;
|
| 347 |
+
}
|
| 348 |
+
|
| 349 |
+
/* Main Application (Hidden Initially) */
|
| 350 |
+
.main-app {
|
| 351 |
+
display: none;
|
| 352 |
+
}
|
| 353 |
+
|
| 354 |
+
/* Layout Components */
|
| 355 |
+
.app-container {
|
| 356 |
+
min-height: 100vh;
|
| 357 |
+
max-width: var(--container-max-width);
|
| 358 |
+
margin: 0 auto;
|
| 359 |
+
padding: var(--spacing-lg);
|
| 360 |
+
position: relative;
|
| 361 |
+
}
|
| 362 |
+
|
| 363 |
+
/* Language Switcher in Main App */
|
| 364 |
+
.language-switcher {
|
| 365 |
+
position: absolute;
|
| 366 |
+
top: var(--spacing-lg);
|
| 367 |
+
right: var(--spacing-lg);
|
| 368 |
+
display: flex;
|
| 369 |
+
gap: 10px;
|
| 370 |
+
align-items: center;
|
| 371 |
+
z-index: 10;
|
| 372 |
+
}
|
| 373 |
+
|
| 374 |
+
.language-switch-btn {
|
| 375 |
+
background: rgba(124, 58, 237, 0.05);
|
| 376 |
+
border: 1px solid rgba(124, 58, 237, 0.1);
|
| 377 |
+
border-radius: var(--radius-md);
|
| 378 |
+
padding: 8px 12px;
|
| 379 |
+
font-size: 12px;
|
| 380 |
+
cursor: pointer;
|
| 381 |
+
transition: all 0.2s ease;
|
| 382 |
+
color: var(--color-primary);
|
| 383 |
+
font-weight: 500;
|
| 384 |
+
}
|
| 385 |
+
|
| 386 |
+
.language-switch-btn:hover {
|
| 387 |
+
background: rgba(124, 58, 237, 0.1);
|
| 388 |
+
}
|
| 389 |
+
|
| 390 |
+
.mini-clear-cache {
|
| 391 |
+
background: rgba(245, 158, 11, 0.1);
|
| 392 |
+
border: 1px solid rgba(245, 158, 11, 0.2);
|
| 393 |
+
color: var(--color-warning);
|
| 394 |
+
padding: 6px 10px;
|
| 395 |
+
border-radius: var(--radius-sm);
|
| 396 |
+
font-size: 11px;
|
| 397 |
+
cursor: pointer;
|
| 398 |
+
transition: all 0.2s ease;
|
| 399 |
+
font-weight: 500;
|
| 400 |
+
}
|
| 401 |
+
|
| 402 |
+
.mini-clear-cache:hover {
|
| 403 |
+
background: rgba(245, 158, 11, 0.2);
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
/* Compact API Key in Top-Left */
|
| 407 |
+
.api-key-compact {
|
| 408 |
+
position: absolute;
|
| 409 |
+
top: var(--spacing-lg);
|
| 410 |
+
left: var(--spacing-lg);
|
| 411 |
+
z-index: 10;
|
| 412 |
+
background: var(--color-surface);
|
| 413 |
+
border: 1px solid var(--color-border);
|
| 414 |
+
border-radius: var(--radius-lg);
|
| 415 |
+
padding: var(--spacing-md) var(--spacing-lg);
|
| 416 |
+
box-shadow: var(--shadow-md);
|
| 417 |
+
transition: all var(--transition-normal);
|
| 418 |
+
max-width: 280px;
|
| 419 |
+
}
|
| 420 |
+
|
| 421 |
+
.api-key-compact:hover {
|
| 422 |
+
box-shadow: var(--shadow-lg);
|
| 423 |
+
}
|
| 424 |
+
|
| 425 |
+
.api-key-compact-label {
|
| 426 |
+
display: block;
|
| 427 |
+
font-size: 0.75rem;
|
| 428 |
+
font-weight: 600;
|
| 429 |
+
color: var(--color-text-secondary);
|
| 430 |
+
margin-bottom: var(--spacing-xs);
|
| 431 |
+
text-transform: uppercase;
|
| 432 |
+
letter-spacing: 0.05em;
|
| 433 |
+
}
|
| 434 |
+
|
| 435 |
+
.api-key-compact-input {
|
| 436 |
+
width: 100%;
|
| 437 |
+
padding: var(--spacing-sm) var(--spacing-md);
|
| 438 |
+
border: 1px solid var(--color-border);
|
| 439 |
+
border-radius: var(--radius-sm);
|
| 440 |
+
font-size: 0.875rem;
|
| 441 |
+
background: var(--color-background);
|
| 442 |
+
color: var(--color-text-primary);
|
| 443 |
+
transition: all var(--transition-fast);
|
| 444 |
+
font-family: 'Courier New', monospace;
|
| 445 |
+
}
|
| 446 |
+
|
| 447 |
+
.api-key-compact-input:focus {
|
| 448 |
+
outline: none;
|
| 449 |
+
border-color: var(--color-border-focus);
|
| 450 |
+
box-shadow: 0 0 0 2px rgb(124 58 237 / 0.1);
|
| 451 |
+
}
|
| 452 |
+
|
| 453 |
+
.api-key-compact-input::placeholder {
|
| 454 |
+
color: var(--color-text-muted);
|
| 455 |
+
font-size: 0.75rem;
|
| 456 |
+
}
|
| 457 |
+
|
| 458 |
+
/* Main Content */
|
| 459 |
+
.app-main {
|
| 460 |
+
max-width: var(--content-max-width);
|
| 461 |
+
margin: 0 auto;
|
| 462 |
+
padding-top: var(--spacing-2xl);
|
| 463 |
+
}
|
| 464 |
+
|
| 465 |
+
/* Header */
|
| 466 |
+
.app-header {
|
| 467 |
+
text-align: center;
|
| 468 |
+
margin-bottom: var(--spacing-3xl);
|
| 469 |
+
}
|
| 470 |
+
|
| 471 |
+
.app-title {
|
| 472 |
+
font-size: 2.5rem;
|
| 473 |
+
font-weight: 700;
|
| 474 |
+
background: linear-gradient(135deg, var(--color-primary), var(--color-secondary));
|
| 475 |
+
-webkit-background-clip: text;
|
| 476 |
+
-webkit-text-fill-color: transparent;
|
| 477 |
+
background-clip: text;
|
| 478 |
+
margin-bottom: var(--spacing-lg);
|
| 479 |
+
line-height: 1.2;
|
| 480 |
+
}
|
| 481 |
+
|
| 482 |
+
.app-subtitle {
|
| 483 |
+
font-size: 1.125rem;
|
| 484 |
+
color: var(--color-text-secondary);
|
| 485 |
+
max-width: 700px;
|
| 486 |
+
margin: 0 auto;
|
| 487 |
+
line-height: 1.4;
|
| 488 |
+
}
|
| 489 |
+
|
| 490 |
+
/* Input Section */
|
| 491 |
+
.input-section {
|
| 492 |
+
background: var(--color-surface);
|
| 493 |
+
border-radius: var(--radius-xl);
|
| 494 |
+
padding: var(--spacing-3xl);
|
| 495 |
+
box-shadow: var(--shadow-md);
|
| 496 |
+
margin-bottom: var(--spacing-3xl);
|
| 497 |
+
transition: all var(--transition-normal);
|
| 498 |
+
}
|
| 499 |
+
|
| 500 |
+
.input-section:hover {
|
| 501 |
+
box-shadow: var(--shadow-lg);
|
| 502 |
+
}
|
| 503 |
+
|
| 504 |
+
.section-title {
|
| 505 |
+
font-size: 1.5rem;
|
| 506 |
+
font-weight: 600;
|
| 507 |
+
color: var(--color-text-primary);
|
| 508 |
+
margin-bottom: var(--spacing-xl);
|
| 509 |
+
text-align: center;
|
| 510 |
+
}
|
| 511 |
+
|
| 512 |
+
.form-group {
|
| 513 |
+
margin-bottom: var(--spacing-xl);
|
| 514 |
+
}
|
| 515 |
+
|
| 516 |
+
.form-label {
|
| 517 |
+
display: block;
|
| 518 |
+
font-size: 1rem;
|
| 519 |
+
font-weight: 600;
|
| 520 |
+
color: var(--color-text-primary);
|
| 521 |
+
margin-bottom: var(--spacing-md);
|
| 522 |
+
}
|
| 523 |
+
|
| 524 |
+
.form-textarea {
|
| 525 |
+
width: 100%;
|
| 526 |
+
min-height: 120px;
|
| 527 |
+
padding: var(--spacing-lg);
|
| 528 |
+
border: 2px solid var(--color-border);
|
| 529 |
+
border-radius: var(--radius-lg);
|
| 530 |
+
font-size: 1rem;
|
| 531 |
+
font-family: var(--font-family-primary);
|
| 532 |
+
background: var(--color-background);
|
| 533 |
+
color: var(--color-text-primary);
|
| 534 |
+
transition: all var(--transition-fast);
|
| 535 |
+
resize: vertical;
|
| 536 |
+
}
|
| 537 |
+
|
| 538 |
+
.form-textarea:focus {
|
| 539 |
+
outline: none;
|
| 540 |
+
border-color: var(--color-border-focus);
|
| 541 |
+
box-shadow: 0 0 0 3px rgb(124 58 237 / 0.1);
|
| 542 |
+
}
|
| 543 |
+
|
| 544 |
+
.form-textarea::placeholder {
|
| 545 |
+
color: var(--color-text-muted);
|
| 546 |
+
}
|
| 547 |
+
|
| 548 |
+
.analyze-button {
|
| 549 |
+
display: inline-flex;
|
| 550 |
+
align-items: center;
|
| 551 |
+
gap: var(--spacing-md);
|
| 552 |
+
padding: var(--spacing-lg) var(--spacing-3xl);
|
| 553 |
+
font-size: 1.125rem;
|
| 554 |
+
font-weight: 600;
|
| 555 |
+
color: white;
|
| 556 |
+
background: linear-gradient(135deg, var(--color-primary), var(--color-secondary));
|
| 557 |
+
border: none;
|
| 558 |
+
border-radius: var(--radius-lg);
|
| 559 |
+
cursor: pointer;
|
| 560 |
+
transition: all var(--transition-normal);
|
| 561 |
+
box-shadow: var(--shadow-md);
|
| 562 |
+
position: relative;
|
| 563 |
+
overflow: hidden;
|
| 564 |
+
margin: 0 auto;
|
| 565 |
+
display: block;
|
| 566 |
+
}
|
| 567 |
+
|
| 568 |
+
.analyze-button:hover:not(:disabled) {
|
| 569 |
+
transform: translateY(-2px);
|
| 570 |
+
box-shadow: var(--shadow-xl);
|
| 571 |
+
}
|
| 572 |
+
|
| 573 |
+
.analyze-button:active {
|
| 574 |
+
transform: translateY(0);
|
| 575 |
+
}
|
| 576 |
+
|
| 577 |
+
.analyze-button:disabled {
|
| 578 |
+
opacity: 0.7;
|
| 579 |
+
cursor: not-allowed;
|
| 580 |
+
transform: none;
|
| 581 |
+
}
|
| 582 |
+
|
| 583 |
+
.button-text {
|
| 584 |
+
transition: opacity var(--transition-fast);
|
| 585 |
+
}
|
| 586 |
+
|
| 587 |
+
.loading-spinner {
|
| 588 |
+
display: none;
|
| 589 |
+
width: 20px;
|
| 590 |
+
height: 20px;
|
| 591 |
+
border: 2px solid rgba(255, 255, 255, 0.3);
|
| 592 |
+
border-top: 2px solid white;
|
| 593 |
+
border-radius: 50%;
|
| 594 |
+
animation: spin 1s linear infinite;
|
| 595 |
+
}
|
| 596 |
+
|
| 597 |
+
@keyframes spin {
|
| 598 |
+
0% { transform: rotate(0deg); }
|
| 599 |
+
100% { transform: rotate(360deg); }
|
| 600 |
+
}
|
| 601 |
+
|
| 602 |
+
/* Results Section */
|
| 603 |
+
.results-container {
|
| 604 |
+
display: grid;
|
| 605 |
+
gap: var(--spacing-3xl);
|
| 606 |
+
margin-top: var(--spacing-3xl);
|
| 607 |
+
}
|
| 608 |
+
|
| 609 |
+
.agent-card {
|
| 610 |
+
background: var(--color-surface);
|
| 611 |
+
border: 1px solid var(--color-border);
|
| 612 |
+
border-radius: var(--radius-xl);
|
| 613 |
+
padding: var(--spacing-3xl);
|
| 614 |
+
box-shadow: var(--shadow-md);
|
| 615 |
+
transition: all var(--transition-normal);
|
| 616 |
+
position: relative;
|
| 617 |
+
overflow: hidden;
|
| 618 |
+
}
|
| 619 |
+
|
| 620 |
+
.agent-card:hover {
|
| 621 |
+
box-shadow: var(--shadow-lg);
|
| 622 |
+
border-color: var(--color-accent);
|
| 623 |
+
}
|
| 624 |
+
|
| 625 |
+
.agent-card::before {
|
| 626 |
+
content: '';
|
| 627 |
+
position: absolute;
|
| 628 |
+
top: 0;
|
| 629 |
+
left: 0;
|
| 630 |
+
right: 0;
|
| 631 |
+
height: 4px;
|
| 632 |
+
background: linear-gradient(90deg, var(--color-primary), var(--color-secondary));
|
| 633 |
+
}
|
| 634 |
+
|
| 635 |
+
.agent-header {
|
| 636 |
+
display: flex;
|
| 637 |
+
align-items: center;
|
| 638 |
+
gap: var(--spacing-lg);
|
| 639 |
+
margin-bottom: var(--spacing-xl);
|
| 640 |
+
}
|
| 641 |
+
|
| 642 |
+
.agent-icon {
|
| 643 |
+
width: 48px;
|
| 644 |
+
height: 48px;
|
| 645 |
+
background: linear-gradient(135deg, var(--color-primary), var(--color-secondary));
|
| 646 |
+
border-radius: 50%;
|
| 647 |
+
display: flex;
|
| 648 |
+
align-items: center;
|
| 649 |
+
justify-content: center;
|
| 650 |
+
color: white;
|
| 651 |
+
font-weight: 700;
|
| 652 |
+
font-size: 1.25rem;
|
| 653 |
+
}
|
| 654 |
+
|
| 655 |
+
.agent-title {
|
| 656 |
+
font-size: 1.5rem;
|
| 657 |
+
font-weight: 600;
|
| 658 |
+
color: var(--color-text-primary);
|
| 659 |
+
margin: 0;
|
| 660 |
+
}
|
| 661 |
+
|
| 662 |
+
.agent-subtitle {
|
| 663 |
+
font-size: 0.875rem;
|
| 664 |
+
color: var(--color-text-secondary);
|
| 665 |
+
margin: 0;
|
| 666 |
+
}
|
| 667 |
+
|
| 668 |
+
.agent-content {
|
| 669 |
+
background: var(--color-background);
|
| 670 |
+
border-radius: var(--radius-lg);
|
| 671 |
+
padding: var(--spacing-xl);
|
| 672 |
+
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
| 673 |
+
font-size: 0.875rem;
|
| 674 |
+
line-height: 1.6;
|
| 675 |
+
color: var(--color-text-primary);
|
| 676 |
+
white-space: pre-wrap;
|
| 677 |
+
word-wrap: break-word;
|
| 678 |
+
border: 1px solid var(--color-border);
|
| 679 |
+
min-height: 100px;
|
| 680 |
+
max-height: 600px;
|
| 681 |
+
overflow-y: auto;
|
| 682 |
+
}
|
| 683 |
+
|
| 684 |
+
.agent-content:empty::before {
|
| 685 |
+
content: 'Analysis will appear here...';
|
| 686 |
+
color: var(--color-text-muted);
|
| 687 |
+
font-style: italic;
|
| 688 |
+
font-family: var(--font-family-primary);
|
| 689 |
+
}
|
| 690 |
+
|
| 691 |
+
/* Loading States */
|
| 692 |
+
.agent-card.loading .agent-content {
|
| 693 |
+
display: flex;
|
| 694 |
+
align-items: center;
|
| 695 |
+
justify-content: center;
|
| 696 |
+
min-height: 120px;
|
| 697 |
+
}
|
| 698 |
+
|
| 699 |
+
.agent-card.loading .agent-content::before {
|
| 700 |
+
content: '';
|
| 701 |
+
width: 32px;
|
| 702 |
+
height: 32px;
|
| 703 |
+
border: 3px solid var(--color-border);
|
| 704 |
+
border-top: 3px solid var(--color-primary);
|
| 705 |
+
border-radius: 50%;
|
| 706 |
+
animation: spin 1s linear infinite;
|
| 707 |
+
}
|
| 708 |
+
|
| 709 |
+
/* Error Handling */
|
| 710 |
+
.error-message {
|
| 711 |
+
background: #fef2f2;
|
| 712 |
+
border: 1px solid #fecaca;
|
| 713 |
+
color: var(--color-error);
|
| 714 |
+
padding: var(--spacing-lg);
|
| 715 |
+
border-radius: var(--radius-lg);
|
| 716 |
+
margin-bottom: var(--spacing-lg);
|
| 717 |
+
display: flex;
|
| 718 |
+
align-items: center;
|
| 719 |
+
gap: var(--spacing-md);
|
| 720 |
+
}
|
| 721 |
+
|
| 722 |
+
.error-icon {
|
| 723 |
+
font-size: 1.25rem;
|
| 724 |
+
}
|
| 725 |
+
|
| 726 |
+
.error-dismiss {
|
| 727 |
+
margin-left: auto;
|
| 728 |
+
background: none;
|
| 729 |
+
border: none;
|
| 730 |
+
color: var(--color-error);
|
| 731 |
+
cursor: pointer;
|
| 732 |
+
font-size: 1.25rem;
|
| 733 |
+
padding: var(--spacing-xs);
|
| 734 |
+
border-radius: var(--radius-sm);
|
| 735 |
+
}
|
| 736 |
+
|
| 737 |
+
.error-dismiss:hover {
|
| 738 |
+
background: rgba(239, 68, 68, 0.1);
|
| 739 |
+
}
|
| 740 |
+
|
| 741 |
+
/* Hidden sections */
|
| 742 |
+
.hidden {
|
| 743 |
+
display: none !important;
|
| 744 |
+
}
|
| 745 |
+
|
| 746 |
+
/* Footer */
|
| 747 |
+
.app-footer {
|
| 748 |
+
text-align: center;
|
| 749 |
+
padding: var(--spacing-xl);
|
| 750 |
+
color: var(--color-text-secondary);
|
| 751 |
+
font-size: 0.9rem;
|
| 752 |
+
margin-top: var(--spacing-3xl);
|
| 753 |
+
}
|
| 754 |
+
|
| 755 |
+
/* Responsive Design */
|
| 756 |
+
@media (max-width: 768px) {
|
| 757 |
+
.language-landing {
|
| 758 |
+
margin: 20px auto;
|
| 759 |
+
padding: 30px 20px;
|
| 760 |
+
}
|
| 761 |
+
|
| 762 |
+
.app-container {
|
| 763 |
+
padding: var(--spacing-md);
|
| 764 |
+
}
|
| 765 |
+
|
| 766 |
+
.api-key-compact {
|
| 767 |
+
position: static;
|
| 768 |
+
margin-bottom: var(--spacing-xl);
|
| 769 |
+
max-width: none;
|
| 770 |
+
}
|
| 771 |
+
|
| 772 |
+
.language-switcher {
|
| 773 |
+
position: relative;
|
| 774 |
+
top: auto;
|
| 775 |
+
right: auto;
|
| 776 |
+
margin-bottom: var(--spacing-xl);
|
| 777 |
+
justify-content: center;
|
| 778 |
+
}
|
| 779 |
+
|
| 780 |
+
.app-main {
|
| 781 |
+
padding-top: 0;
|
| 782 |
+
}
|
| 783 |
+
|
| 784 |
+
.app-title {
|
| 785 |
+
font-size: 2rem;
|
| 786 |
+
}
|
| 787 |
+
|
| 788 |
+
.app-subtitle {
|
| 789 |
+
font-size: 1rem;
|
| 790 |
+
}
|
| 791 |
+
|
| 792 |
+
.input-section,
|
| 793 |
+
.agent-card {
|
| 794 |
+
padding: var(--spacing-xl);
|
| 795 |
+
}
|
| 796 |
+
|
| 797 |
+
.agent-header {
|
| 798 |
+
flex-direction: column;
|
| 799 |
+
text-align: center;
|
| 800 |
+
gap: var(--spacing-md);
|
| 801 |
+
}
|
| 802 |
+
|
| 803 |
+
.agent-content {
|
| 804 |
+
font-size: 0.8rem;
|
| 805 |
+
max-height: 400px;
|
| 806 |
+
}
|
| 807 |
+
}
|
| 808 |
+
|
| 809 |
+
@media (max-width: 480px) {
|
| 810 |
+
.language-landing h1 {
|
| 811 |
+
font-size: 2rem;
|
| 812 |
+
}
|
| 813 |
+
|
| 814 |
+
.app-title {
|
| 815 |
+
font-size: 1.8rem;
|
| 816 |
+
}
|
| 817 |
+
}
|
| 818 |
+
|
| 819 |
+
/* Accessibility */
|
| 820 |
+
.sr-only {
|
| 821 |
+
position: absolute;
|
| 822 |
+
width: 1px;
|
| 823 |
+
height: 1px;
|
| 824 |
+
padding: 0;
|
| 825 |
+
margin: -1px;
|
| 826 |
+
overflow: hidden;
|
| 827 |
+
clip: rect(0, 0, 0, 0);
|
| 828 |
+
white-space: nowrap;
|
| 829 |
+
border: 0;
|
| 830 |
+
}
|
| 831 |
+
|
| 832 |
+
/* Focus styles for keyboard navigation */
|
| 833 |
+
.analyze-button:focus,
|
| 834 |
+
.api-key-compact-input:focus,
|
| 835 |
+
.form-textarea:focus {
|
| 836 |
+
outline: 2px solid var(--color-primary);
|
| 837 |
+
outline-offset: 2px;
|
| 838 |
+
}
|
| 839 |
+
|
| 840 |
+
/* Reduced motion support */
|
| 841 |
+
@media (prefers-reduced-motion: reduce) {
|
| 842 |
+
*,
|
| 843 |
+
*::before,
|
| 844 |
+
*::after {
|
| 845 |
+
animation-duration: 0.01ms !important;
|
| 846 |
+
animation-iteration-count: 1 !important;
|
| 847 |
+
transition-duration: 0.01ms !important;
|
| 848 |
+
scroll-behavior: auto !important;
|
| 849 |
+
}
|
| 850 |
+
}
|
| 851 |
+
|
| 852 |
+
/* Custom scrollbar for agent content */
|
| 853 |
+
.agent-content::-webkit-scrollbar {
|
| 854 |
+
width: 8px;
|
| 855 |
+
}
|
| 856 |
+
|
| 857 |
+
.agent-content::-webkit-scrollbar-track {
|
| 858 |
+
background: var(--color-border);
|
| 859 |
+
border-radius: var(--radius-sm);
|
| 860 |
+
}
|
| 861 |
+
|
| 862 |
+
.agent-content::-webkit-scrollbar-thumb {
|
| 863 |
+
background: var(--color-accent);
|
| 864 |
+
border-radius: var(--radius-sm);
|
| 865 |
+
}
|
| 866 |
+
|
| 867 |
+
.agent-content::-webkit-scrollbar-thumb:hover {
|
| 868 |
+
background: var(--color-primary);
|
| 869 |
+
}
|
| 870 |
+
</style>
|
| 871 |
+
</head>
|
| 872 |
+
|
| 873 |
+
<body>
|
| 874 |
+
<!-- Translation Loading Overlay -->
|
| 875 |
+
<div class="translation-overlay" id="translationOverlay">
|
| 876 |
+
<div class="translation-content">
|
| 877 |
+
<div class="translation-spinner"></div>
|
| 878 |
+
<h2 id="translationTitle">Translating Interface...</h2>
|
| 879 |
+
<p id="translationMessage">Please wait while we translate the interface to your selected language.</p>
|
| 880 |
+
</div>
|
| 881 |
+
</div>
|
| 882 |
+
|
| 883 |
+
<!-- Language Selection Landing Page -->
|
| 884 |
+
<div class="language-landing" id="languageLanding">
|
| 885 |
+
<h1 data-translate="app_title">Educational Activity Intelligence Analyzer</h1>
|
| 886 |
+
<p data-translate="welcome_message">Welcome! Please select your preferred language and enter your API key to get started with advanced multi-agent analysis of teaching activities.</p>
|
| 887 |
+
|
| 888 |
+
<!-- Cache Status Indicator -->
|
| 889 |
+
<div class="cache-status" id="cacheStatus">
|
| 890 |
+
💾 Translations cached - instant loading!
|
| 891 |
+
</div>
|
| 892 |
+
|
| 893 |
+
<!-- Cache Management Section -->
|
| 894 |
+
<div class="cache-management" id="cacheManagement">
|
| 895 |
+
<h3 data-translate="cache_management_title">🗂️ Translation Cache Management</h3>
|
| 896 |
+
<div class="cache-status-display" id="cacheStatusDisplay">
|
| 897 |
+
<span data-translate="cache_status_checking">Checking cache status...</span>
|
| 898 |
+
</div>
|
| 899 |
+
<button class="clear-cache-btn" id="clearCacheBtn" data-translate="clear_cache_button">
|
| 900 |
+
🗑️ Clear All Cached Translations
|
| 901 |
+
</button>
|
| 902 |
+
</div>
|
| 903 |
+
|
| 904 |
+
<div class="language-selector">
|
| 905 |
+
<label for="languageSelect" data-translate="select_language">🌐 Select Language</label>
|
| 906 |
+
<select id="languageSelect">
|
| 907 |
+
<option value="en">🇺🇸 English</option>
|
| 908 |
+
<option value="es">🇪🇸 Español (Spanish)</option>
|
| 909 |
+
<option value="fr">🇫🇷 Français (French)</option>
|
| 910 |
+
<option value="de">🇩🇪 Deutsch (German)</option>
|
| 911 |
+
<option value="zh">🇨🇳 中文 (Chinese)</option>
|
| 912 |
+
<option value="ja">🇯🇵 日本語 (Japanese)</option>
|
| 913 |
+
<option value="ko">🇰🇷 한국어 (Korean)</option>
|
| 914 |
+
<option value="pt">🇵🇹 Português (Portuguese)</option>
|
| 915 |
+
<option value="it">🇮🇹 Italiano (Italian)</option>
|
| 916 |
+
<option value="ar">🇸🇦 العربية (Arabic)</option>
|
| 917 |
+
<option value="ru">🇷🇺 Русский (Russian)</option>
|
| 918 |
+
<option value="hi">🇮🇳 हिन्दी (Hindi)</option>
|
| 919 |
+
<option value="bn">🇧🇩 বাংলা (Bengali)</option>
|
| 920 |
+
<option value="ur">🇵🇰 اردو (Urdu)</option>
|
| 921 |
+
<option value="tr">🇹🇷 Türkçe (Turkish)</option>
|
| 922 |
+
<option value="pl">🇵🇱 Polski (Polish)</option>
|
| 923 |
+
<option value="nl">🇳🇱 Nederlands (Dutch)</option>
|
| 924 |
+
<option value="sv">🇸🇪 Svenska (Swedish)</option>
|
| 925 |
+
<option value="da">🇩🇰 Dansk (Danish)</option>
|
| 926 |
+
<option value="no">🇳🇴 Norsk (Norwegian)</option>
|
| 927 |
+
<option value="fi">🇫🇮 Suomi (Finnish)</option>
|
| 928 |
+
<option value="is">🇮🇸 Íslenska (Icelandic)</option>
|
| 929 |
+
<option value="cs">🇨🇿 Čeština (Czech)</option>
|
| 930 |
+
<option value="sk">🇸🇰 Slovenčina (Slovak)</option>
|
| 931 |
+
<option value="hu">🇭🇺 Magyar (Hungarian)</option>
|
| 932 |
+
<option value="ro">🇷🇴 Română (Romanian)</option>
|
| 933 |
+
<option value="bg">🇧🇬 Български (Bulgarian)</option>
|
| 934 |
+
<option value="hr">🇭🇷 Hrvatski (Croatian)</option>
|
| 935 |
+
<option value="sr">🇷🇸 Српски (Serbian)</option>
|
| 936 |
+
<option value="sl">🇸🇮 Slovenščina (Slovenian)</option>
|
| 937 |
+
<option value="mk">🇲🇰 Македонски (Macedonian)</option>
|
| 938 |
+
<option value="sq">🇦🇱 Shqip (Albanian)</option>
|
| 939 |
+
<option value="lv">🇱🇻 Latviešu (Latvian)</option>
|
| 940 |
+
<option value="lt">🇱🇹 Lietuvių (Lithuanian)</option>
|
| 941 |
+
<option value="et">🇪🇪 Eesti (Estonian)</option>
|
| 942 |
+
<option value="mt">🇲🇹 Malti (Maltese)</option>
|
| 943 |
+
<option value="ga">🇮🇪 Gaeilge (Irish)</option>
|
| 944 |
+
<option value="cy">🏴 Cymraeg (Welsh)</option>
|
| 945 |
+
<option value="eu">🏴 Euskera (Basque)</option>
|
| 946 |
+
<option value="ca">🏴 Català (Catalan)</option>
|
| 947 |
+
<option value="gl">🏴 Galego (Galician)</option>
|
| 948 |
+
<option value="el">🇬🇷 Ελληνικά (Greek)</option>
|
| 949 |
+
<option value="he">🇮🇱 עברית (Hebrew)</option>
|
| 950 |
+
<option value="fa">🇮🇷 فارسی (Persian)</option>
|
| 951 |
+
<option value="ps">🇦🇫 پښتو (Pashto)</option>
|
| 952 |
+
<option value="ku">🏴 کوردی (Kurdish)</option>
|
| 953 |
+
<option value="az">🇦🇿 Azərbaycan (Azerbaijani)</option>
|
| 954 |
+
<option value="kk">🇰🇿 Қазақша (Kazakh)</option>
|
| 955 |
+
<option value="ky">🇰🇬 Кыргызча (Kyrgyz)</option>
|
| 956 |
+
<option value="uz">🇺🇿 O'zbek (Uzbek)</option>
|
| 957 |
+
<option value="tk">🇹🇲 Türkmen (Turkmen)</option>
|
| 958 |
+
<option value="tg">🇹🇯 Тоҷикӣ (Tajik)</option>
|
| 959 |
+
<option value="mn">🇲🇳 Монгол (Mongolian)</option>
|
| 960 |
+
<option value="ka">🇬🇪 ქართული (Georgian)</option>
|
| 961 |
+
<option value="hy">🇦🇲 Հայերեն (Armenian)</option>
|
| 962 |
+
<option value="th">🇹🇭 ไทย (Thai)</option>
|
| 963 |
+
<option value="vi">🇻🇳 Tiếng Việt (Vietnamese)</option>
|
| 964 |
+
<option value="lo">🇱🇦 ລາວ (Lao)</option>
|
| 965 |
+
<option value="km">🇰🇭 ខ្មែរ (Khmer)</option>
|
| 966 |
+
<option value="my">🇲🇲 မြန်မာ (Myanmar)</option>
|
| 967 |
+
<option value="si">🇱🇰 සිංහල (Sinhala)</option>
|
| 968 |
+
<option value="ta">🇱🇰 தமிழ் (Tamil)</option>
|
| 969 |
+
<option value="te">🇮🇳 తెలుగు (Telugu)</option>
|
| 970 |
+
<option value="kn">🇮🇳 ಕನ್ನಡ (Kannada)</option>
|
| 971 |
+
<option value="ml">🇮🇳 മലയാളം (Malayalam)</option>
|
| 972 |
+
<option value="gu">🇮🇳 ગુજરાતી (Gujarati)</option>
|
| 973 |
+
<option value="pa">🇮🇳 ਪੰਜਾਬੀ (Punjabi)</option>
|
| 974 |
+
<option value="or">🇮🇳 ଓଡ଼ିଆ (Odia)</option>
|
| 975 |
+
<option value="as">🇮🇳 অসমীয়া (Assamese)</option>
|
| 976 |
+
<option value="ne">🇳🇵 नेपाली (Nepali)</option>
|
| 977 |
+
<option value="dz">🇧🇹 རྫོང་ཁ (Dzongkha)</option>
|
| 978 |
+
<option value="bo">🏔️ བོད་ཡིག (Tibetan)</option>
|
| 979 |
+
<option value="id">🇮🇩 Bahasa Indonesia</option>
|
| 980 |
+
<option value="ms">🇲🇾 Bahasa Melayu (Malay)</option>
|
| 981 |
+
<option value="tl">🇵🇭 Filipino (Tagalog)</option>
|
| 982 |
+
<option value="ceb">🇵🇭 Cebuano</option>
|
| 983 |
+
<option value="haw">🏝️ ʻŌlelo Hawaiʻi (Hawaiian)</option>
|
| 984 |
+
<option value="mi">🇳🇿 Te Reo Māori (Maori)</option>
|
| 985 |
+
<option value="sm">🇼🇸 Gagana Samoa (Samoan)</option>
|
| 986 |
+
<option value="to">🇹🇴 Lea Fakatonga (Tongan)</option>
|
| 987 |
+
<option value="fj">🇫🇯 Na Vosa Vakaviti (Fijian)</option>
|
| 988 |
+
<option value="mg">🇲🇬 Malagasy</option>
|
| 989 |
+
<option value="sw">🇰🇪 Kiswahili (Swahili)</option>
|
| 990 |
+
<option value="zu">🇿🇦 isiZulu (Zulu)</option>
|
| 991 |
+
<option value="xh">🇿🇦 isiXhosa (Xhosa)</option>
|
| 992 |
+
<option value="af">🇿🇦 Afrikaans</option>
|
| 993 |
+
<option value="st">🇱🇸 Sesotho (Southern Sotho)</option>
|
| 994 |
+
<option value="tn">🇧🇼 Setswana (Tswana)</option>
|
| 995 |
+
<option value="ss">🇸🇿 siSwati (Swati)</option>
|
| 996 |
+
<option value="ve">🇿🇦 Tshivenḓa (Venda)</option>
|
| 997 |
+
<option value="ts">🇿🇦 Xitsonga (Tsonga)</option>
|
| 998 |
+
<option value="nr">🇿🇦 isiNdebele (Southern Ndebele)</option>
|
| 999 |
+
<option value="am">🇪🇹 አማርኛ (Amharic)</option>
|
| 1000 |
+
<option value="ti">🇪🇷 ትግርኛ (Tigrinya)</option>
|
| 1001 |
+
<option value="om">🇪🇹 Afaan Oromoo (Oromo)</option>
|
| 1002 |
+
<option value="so">🇸🇴 Soomaali (Somali)</option>
|
| 1003 |
+
<option value="ha">🇳🇬 Hausa</option>
|
| 1004 |
+
<option value="yo">🇳🇬 Yorùbá (Yoruba)</option>
|
| 1005 |
+
<option value="ig">🇳🇬 Igbo</option>
|
| 1006 |
+
<option value="ff">🇸🇳 Fulfulde (Fulani)</option>
|
| 1007 |
+
<option value="wo">🇸🇳 Wolof</option>
|
| 1008 |
+
<option value="bm">🇲🇱 Bamanankan (Bambara)</option>
|
| 1009 |
+
<option value="rn">🇧🇮 Kirundi (Rundi)</option>
|
| 1010 |
+
<option value="rw">🇷🇼 Kinyarwanda (Rwanda)</option>
|
| 1011 |
+
<option value="lg">🇺🇬 Luganda</option>
|
| 1012 |
+
<option value="ny">🇲🇼 Chichewa (Nyanja)</option>
|
| 1013 |
+
<option value="sn">🇿🇼 chiShona (Shona)</option>
|
| 1014 |
+
<option value="nd">🇿🇼 isiNdebele (Northern Ndebele)</option>
|
| 1015 |
+
</select>
|
| 1016 |
+
</div>
|
| 1017 |
+
|
| 1018 |
+
<div class="api-key-landing">
|
| 1019 |
+
<label for="apiKeyLanding" data-translate="api_key_label">🔑 OpenAI API Key</label>
|
| 1020 |
+
<input type="password" id="apiKeyLanding" placeholder="Enter your OpenAI API key" data-translate-placeholder="api_key_placeholder">
|
| 1021 |
+
</div>
|
| 1022 |
+
|
| 1023 |
+
<button class="start-btn" id="startBtn" data-translate="start_button">🚀 Start Educational Analysis</button>
|
| 1024 |
+
</div>
|
| 1025 |
+
|
| 1026 |
+
<!-- Main Application -->
|
| 1027 |
+
<div class="main-app" id="mainApp">
|
| 1028 |
+
<div class="app-container">
|
| 1029 |
+
<!-- Language Switcher -->
|
| 1030 |
+
<div class="language-switcher" id="languageSwitcher">
|
| 1031 |
+
<div class="language-switch-btn" onclick="showLanguageLanding()">
|
| 1032 |
+
<span data-translate="change_language">🌐 Change Language</span>
|
| 1033 |
+
</div>
|
| 1034 |
+
<div class="mini-clear-cache" onclick="clearAllTranslationCache()" title="Clear translation cache">
|
| 1035 |
+
<span data-translate="clear_cache_mini">🗑️ Clear Cache</span>
|
| 1036 |
+
</div>
|
| 1037 |
+
</div>
|
| 1038 |
+
|
| 1039 |
+
<!-- Compact API Key in Top-Left -->
|
| 1040 |
+
<div class="api-key-compact">
|
| 1041 |
+
<label for="apiKey" class="api-key-compact-label" data-translate="api_key_short">API Key</label>
|
| 1042 |
+
<input
|
| 1043 |
+
type="password"
|
| 1044 |
+
id="apiKey"
|
| 1045 |
+
class="api-key-compact-input"
|
| 1046 |
+
data-translate-placeholder="api_key_placeholder"
|
| 1047 |
+
autocomplete="off"
|
| 1048 |
+
>
|
| 1049 |
+
</div>
|
| 1050 |
+
|
| 1051 |
+
<main class="app-main">
|
| 1052 |
+
<header class="app-header">
|
| 1053 |
+
<h1 class="app-title" data-translate="app_title">Educational Activity Intelligence Analyzer</h1>
|
| 1054 |
+
<p class="app-subtitle" data-translate="app_subtitle">
|
| 1055 |
+
Advanced multi-agent analysis of teaching activities using PICRAT model, Bloom's Taxonomy, and practical scenario development.
|
| 1056 |
+
Get comprehensive insights from three specialized AI agents to enhance your educational technology integration.
|
| 1057 |
+
</p>
|
| 1058 |
+
</header>
|
| 1059 |
+
|
| 1060 |
+
<!-- Input Section -->
|
| 1061 |
+
<section class="input-section">
|
| 1062 |
+
<h2 class="section-title" data-translate="section_title">Describe Your Teaching Activity</h2>
|
| 1063 |
+
<form id="analysisForm">
|
| 1064 |
+
<div class="form-group">
|
| 1065 |
+
<label for="activityDescription" class="form-label" data-translate="activity_label">Activity Description</label>
|
| 1066 |
+
<textarea
|
| 1067 |
+
id="activityDescription"
|
| 1068 |
+
class="form-textarea"
|
| 1069 |
+
data-translate-placeholder="activity_placeholder"
|
| 1070 |
+
required
|
| 1071 |
+
></textarea>
|
| 1072 |
+
</div>
|
| 1073 |
+
<button type="submit" class="analyze-button">
|
| 1074 |
+
<span class="button-text" data-translate="analyze_button">🧠 Analyze Activity</span>
|
| 1075 |
+
<div class="loading-spinner" id="loadingSpinner"></div>
|
| 1076 |
+
</button>
|
| 1077 |
+
</form>
|
| 1078 |
+
</section>
|
| 1079 |
+
|
| 1080 |
+
<!-- Results Section -->
|
| 1081 |
+
<section class="results-container">
|
| 1082 |
+
<!-- Agent 1: Deep Structured Analysis -->
|
| 1083 |
+
<div class="agent-card" id="agent1Card">
|
| 1084 |
+
<div class="agent-header">
|
| 1085 |
+
<div class="agent-icon">1</div>
|
| 1086 |
+
<div>
|
| 1087 |
+
<h3 class="agent-title" data-translate="agent1_title">Deep Structured Analysis</h3>
|
| 1088 |
+
<p class="agent-subtitle" data-translate="agent1_subtitle">PICRAT Model • Bloom's Taxonomy • Critical Thinking Assessment</p>
|
| 1089 |
+
</div>
|
| 1090 |
+
</div>
|
| 1091 |
+
<div class="agent-content" id="analysisOutput1"></div>
|
| 1092 |
+
</div>
|
| 1093 |
+
|
| 1094 |
+
<!-- Agent 2: Practical Scenarios -->
|
| 1095 |
+
<div class="agent-card" id="agent2Card">
|
| 1096 |
+
<div class="agent-header">
|
| 1097 |
+
<div class="agent-icon">2</div>
|
| 1098 |
+
<div>
|
| 1099 |
+
<h3 class="agent-title" data-translate="agent2_title">Practical Scenarios</h3>
|
| 1100 |
+
<p class="agent-subtitle" data-translate="agent2_subtitle">Implementation Strategies • Enhancement Opportunities • Real-world Applications</p>
|
| 1101 |
+
</div>
|
| 1102 |
+
</div>
|
| 1103 |
+
<div class="agent-content" id="analysisOutput2"></div>
|
| 1104 |
+
</div>
|
| 1105 |
+
|
| 1106 |
+
<!-- Agent 3: Feedback & Overview -->
|
| 1107 |
+
<div class="agent-card" id="agent3Card">
|
| 1108 |
+
<div class="agent-header">
|
| 1109 |
+
<div class="agent-icon">3</div>
|
| 1110 |
+
<div>
|
| 1111 |
+
<h3 class="agent-title" data-translate="agent3_title">Meta-Analysis & Recommendations</h3>
|
| 1112 |
+
<p class="agent-subtitle" data-translate="agent3_subtitle">Synthesis • Best Practices Alignment • Strategic Recommendations</p>
|
| 1113 |
+
</div>
|
| 1114 |
+
</div>
|
| 1115 |
+
<div class="agent-content" id="analysisOutput3"></div>
|
| 1116 |
+
</div>
|
| 1117 |
+
</section>
|
| 1118 |
+
</main>
|
| 1119 |
+
|
| 1120 |
+
<footer class="app-footer">
|
| 1121 |
+
<p>Created By Shift Mind AI Labs</p>
|
| 1122 |
+
</footer>
|
| 1123 |
+
</div>
|
| 1124 |
+
</div>
|
| 1125 |
+
|
| 1126 |
+
<script>
|
| 1127 |
+
// RTL languages list
|
| 1128 |
+
const rtlLanguages = ['ar', 'he', 'fa', 'ur', 'ps', 'ku'];
|
| 1129 |
+
|
| 1130 |
+
// Current language and API key
|
| 1131 |
+
let currentLanguage = 'en';
|
| 1132 |
+
let currentApiKey = '';
|
| 1133 |
+
|
| 1134 |
+
// Language names mapping
|
| 1135 |
+
const languageNames = {
|
| 1136 |
+
en: 'English', es: 'Spanish', fr: 'French', de: 'German', zh: 'Chinese',
|
| 1137 |
+
ja: 'Japanese', ko: 'Korean', pt: 'Portuguese', it: 'Italian', ar: 'Arabic',
|
| 1138 |
+
ru: 'Russian', hi: 'Hindi', bn: 'Bengali', ur: 'Urdu', tr: 'Turkish',
|
| 1139 |
+
pl: 'Polish', nl: 'Dutch', sv: 'Swedish', da: 'Danish', no: 'Norwegian',
|
| 1140 |
+
fi: 'Finnish', is: 'Icelandic', cs: 'Czech', sk: 'Slovak', hu: 'Hungarian',
|
| 1141 |
+
ro: 'Romanian', bg: 'Bulgarian', hr: 'Croatian', sr: 'Serbian', sl: 'Slovenian',
|
| 1142 |
+
mk: 'Macedonian', sq: 'Albanian', lv: 'Latvian', lt: 'Lithuanian', et: 'Estonian',
|
| 1143 |
+
mt: 'Maltese', ga: 'Irish', cy: 'Welsh', eu: 'Basque', ca: 'Catalan',
|
| 1144 |
+
gl: 'Galician', el: 'Greek', he: 'Hebrew', fa: 'Persian', ps: 'Pashto',
|
| 1145 |
+
ku: 'Kurdish', az: 'Azerbaijani', kk: 'Kazakh', ky: 'Kyrgyz', uz: 'Uzbek',
|
| 1146 |
+
tk: 'Turkmen', tg: 'Tajik', mn: 'Mongolian', ka: 'Georgian', hy: 'Armenian',
|
| 1147 |
+
th: 'Thai', vi: 'Vietnamese', lo: 'Lao', km: 'Khmer', my: 'Myanmar',
|
| 1148 |
+
si: 'Sinhala', ta: 'Tamil', te: 'Telugu', kn: 'Kannada', ml: 'Malayalam',
|
| 1149 |
+
gu: 'Gujarati', pa: 'Punjabi', or: 'Odia', as: 'Assamese', ne: 'Nepali',
|
| 1150 |
+
dz: 'Dzongkha', bo: 'Tibetan', id: 'Indonesian', ms: 'Malay', tl: 'Filipino',
|
| 1151 |
+
ceb: 'Cebuano', haw: 'Hawaiian', mi: 'Maori', sm: 'Samoan', to: 'Tongan',
|
| 1152 |
+
fj: 'Fijian', mg: 'Malagasy', sw: 'Swahili', zu: 'Zulu', xh: 'Xhosa',
|
| 1153 |
+
af: 'Afrikaans', st: 'Southern Sotho', tn: 'Tswana', ss: 'Swati', ve: 'Venda',
|
| 1154 |
+
ts: 'Tsonga', nr: 'Southern Ndebele', am: 'Amharic', ti: 'Tigrinya', om: 'Oromo',
|
| 1155 |
+
so: 'Somali', ha: 'Hausa', yo: 'Yoruba', ig: 'Igbo', ff: 'Fulani',
|
| 1156 |
+
wo: 'Wolof', bm: 'Bambara', rn: 'Rundi', rw: 'Rwanda', lg: 'Luganda',
|
| 1157 |
+
ny: 'Chichewa', sn: 'Shona', nd: 'Northern Ndebele'
|
| 1158 |
+
};
|
| 1159 |
+
|
| 1160 |
+
// Translation cache management
|
| 1161 |
+
const CACHE_PREFIX = 'educational_analyzer_translations_';
|
| 1162 |
+
const CACHE_VERSION = '1.0';
|
| 1163 |
+
|
| 1164 |
+
// Check if translations are cached for a language
|
| 1165 |
+
function isLanguageCached(language) {
|
| 1166 |
+
const cacheKey = CACHE_PREFIX + language;
|
| 1167 |
+
const cached = localStorage.getItem(cacheKey);
|
| 1168 |
+
return cached !== null;
|
| 1169 |
+
}
|
| 1170 |
+
|
| 1171 |
+
// Save translations to cache
|
| 1172 |
+
function saveTranslationsToCache(language, translations) {
|
| 1173 |
+
const cacheKey = CACHE_PREFIX + language;
|
| 1174 |
+
const cacheData = {
|
| 1175 |
+
version: CACHE_VERSION,
|
| 1176 |
+
timestamp: Date.now(),
|
| 1177 |
+
translations: translations
|
| 1178 |
+
};
|
| 1179 |
+
localStorage.setItem(cacheKey, JSON.stringify(cacheData));
|
| 1180 |
+
console.log(`Translations cached for ${language}`);
|
| 1181 |
+
}
|
| 1182 |
+
|
| 1183 |
+
// Load translations from cache
|
| 1184 |
+
function loadTranslationsFromCache(language) {
|
| 1185 |
+
const cacheKey = CACHE_PREFIX + language;
|
| 1186 |
+
const cached = localStorage.getItem(cacheKey);
|
| 1187 |
+
|
| 1188 |
+
if (cached) {
|
| 1189 |
+
try {
|
| 1190 |
+
const cacheData = JSON.parse(cached);
|
| 1191 |
+
if (cacheData.version === CACHE_VERSION) {
|
| 1192 |
+
console.log(`Translations loaded from cache for ${language}`);
|
| 1193 |
+
return cacheData.translations;
|
| 1194 |
+
}
|
| 1195 |
+
} catch (error) {
|
| 1196 |
+
console.error('Error parsing cached translations:', error);
|
| 1197 |
+
}
|
| 1198 |
+
}
|
| 1199 |
+
return null;
|
| 1200 |
+
}
|
| 1201 |
+
|
| 1202 |
+
// Get all cached languages
|
| 1203 |
+
function getCachedLanguages() {
|
| 1204 |
+
const cachedLanguages = [];
|
| 1205 |
+
for (let i = 0; i < localStorage.length; i++) {
|
| 1206 |
+
const key = localStorage.key(i);
|
| 1207 |
+
if (key && key.startsWith(CACHE_PREFIX)) {
|
| 1208 |
+
const language = key.replace(CACHE_PREFIX, '');
|
| 1209 |
+
cachedLanguages.push(language);
|
| 1210 |
+
}
|
| 1211 |
+
}
|
| 1212 |
+
return cachedLanguages;
|
| 1213 |
+
}
|
| 1214 |
+
|
| 1215 |
+
// Clear all translation cache
|
| 1216 |
+
function clearAllTranslationCache() {
|
| 1217 |
+
const cachedLanguages = getCachedLanguages();
|
| 1218 |
+
|
| 1219 |
+
if (cachedLanguages.length === 0) {
|
| 1220 |
+
alert('No cached translations to clear.');
|
| 1221 |
+
return;
|
| 1222 |
+
}
|
| 1223 |
+
|
| 1224 |
+
const languageList = cachedLanguages.map(lang => languageNames[lang] || lang).join(', ');
|
| 1225 |
+
const confirmMessage = `Are you sure you want to clear all cached translations?\n\nCached languages: ${languageList}\n\nThis will require re-downloading translations when switching languages.`;
|
| 1226 |
+
|
| 1227 |
+
if (confirm(confirmMessage)) {
|
| 1228 |
+
// Clear all translation caches
|
| 1229 |
+
cachedLanguages.forEach(language => {
|
| 1230 |
+
const cacheKey = CACHE_PREFIX + language;
|
| 1231 |
+
localStorage.removeItem(cacheKey);
|
| 1232 |
+
});
|
| 1233 |
+
|
| 1234 |
+
// Update cache status
|
| 1235 |
+
updateCacheStatus(currentLanguage);
|
| 1236 |
+
updateCacheStatusDisplay();
|
| 1237 |
+
|
| 1238 |
+
alert(`Cache cleared successfully!\n\n${cachedLanguages.length} language(s) removed from cache.`);
|
| 1239 |
+
|
| 1240 |
+
// Ask if user wants to reload current language translations
|
| 1241 |
+
if (currentLanguage !== 'en' && cachedLanguages.includes(currentLanguage)) {
|
| 1242 |
+
if (confirm('Would you like to reload the current language translations?')) {
|
| 1243 |
+
applyLanguage(currentLanguage);
|
| 1244 |
+
}
|
| 1245 |
+
}
|
| 1246 |
+
}
|
| 1247 |
+
}
|
| 1248 |
+
|
| 1249 |
+
// Update cache status indicator
|
| 1250 |
+
function updateCacheStatus(language) {
|
| 1251 |
+
const cacheStatus = document.getElementById('cacheStatus');
|
| 1252 |
+
const isCached = isLanguageCached(language);
|
| 1253 |
+
|
| 1254 |
+
if (language === 'en') {
|
| 1255 |
+
cacheStatus.classList.remove('cached', 'translating');
|
| 1256 |
+
return;
|
| 1257 |
+
}
|
| 1258 |
+
|
| 1259 |
+
if (isCached) {
|
| 1260 |
+
cacheStatus.textContent = '💾 Translations cached - instant loading!';
|
| 1261 |
+
cacheStatus.classList.add('cached');
|
| 1262 |
+
cacheStatus.classList.remove('translating');
|
| 1263 |
+
} else {
|
| 1264 |
+
cacheStatus.textContent = '🔄 First time translation - will be cached for future use';
|
| 1265 |
+
cacheStatus.classList.add('translating');
|
| 1266 |
+
cacheStatus.classList.remove('cached');
|
| 1267 |
+
}
|
| 1268 |
+
}
|
| 1269 |
+
|
| 1270 |
+
// Update cache status display in management section
|
| 1271 |
+
function updateCacheStatusDisplay() {
|
| 1272 |
+
const cacheStatusDisplay = document.getElementById('cacheStatusDisplay');
|
| 1273 |
+
const clearCacheBtn = document.getElementById('clearCacheBtn');
|
| 1274 |
+
const cachedLanguages = getCachedLanguages();
|
| 1275 |
+
|
| 1276 |
+
if (cachedLanguages.length === 0) {
|
| 1277 |
+
cacheStatusDisplay.textContent = '📭 No cached translations';
|
| 1278 |
+
cacheStatusDisplay.className = 'cache-status-display no-cache';
|
| 1279 |
+
clearCacheBtn.disabled = true;
|
| 1280 |
+
} else {
|
| 1281 |
+
const languageList = cachedLanguages.map(lang => languageNames[lang] || lang).join(', ');
|
| 1282 |
+
cacheStatusDisplay.textContent = `💾 ${cachedLanguages.length} language(s) cached: ${languageList}`;
|
| 1283 |
+
cacheStatusDisplay.className = 'cache-status-display';
|
| 1284 |
+
clearCacheBtn.disabled = false;
|
| 1285 |
+
}
|
| 1286 |
+
}
|
| 1287 |
+
|
| 1288 |
+
// Initialize the application
|
| 1289 |
+
function initializeApp() {
|
| 1290 |
+
// Load saved language and API key
|
| 1291 |
+
const savedLanguage = localStorage.getItem('educational_analyzer_language') || 'en';
|
| 1292 |
+
const savedApiKey = localStorage.getItem('educational_analyzer_api_key') || '';
|
| 1293 |
+
|
| 1294 |
+
currentLanguage = savedLanguage;
|
| 1295 |
+
currentApiKey = savedApiKey;
|
| 1296 |
+
|
| 1297 |
+
// Set language selector
|
| 1298 |
+
document.getElementById('languageSelect').value = currentLanguage;
|
| 1299 |
+
document.getElementById('apiKeyLanding').value = currentApiKey;
|
| 1300 |
+
|
| 1301 |
+
// Apply direction for current language
|
| 1302 |
+
applyDirection(currentLanguage);
|
| 1303 |
+
|
| 1304 |
+
// Update cache status
|
| 1305 |
+
updateCacheStatus(currentLanguage);
|
| 1306 |
+
updateCacheStatusDisplay();
|
| 1307 |
+
|
| 1308 |
+
// Show appropriate screen
|
| 1309 |
+
if (currentApiKey && currentLanguage) {
|
| 1310 |
+
showMainApp();
|
| 1311 |
+
} else {
|
| 1312 |
+
showLanguageLanding();
|
| 1313 |
+
}
|
| 1314 |
+
}
|
| 1315 |
+
|
| 1316 |
+
// Apply language direction
|
| 1317 |
+
function applyDirection(language) {
|
| 1318 |
+
currentLanguage = language;
|
| 1319 |
+
|
| 1320 |
+
// Set document language and direction
|
| 1321 |
+
document.documentElement.lang = language;
|
| 1322 |
+
document.documentElement.dir = rtlLanguages.includes(language) ? 'rtl' : 'ltr';
|
| 1323 |
+
|
| 1324 |
+
// Save language preference
|
| 1325 |
+
localStorage.setItem('educational_analyzer_language', language);
|
| 1326 |
+
|
| 1327 |
+
// Update cache status
|
| 1328 |
+
updateCacheStatus(language);
|
| 1329 |
+
}
|
| 1330 |
+
|
| 1331 |
+
// API call function for translation
|
| 1332 |
+
async function translateText(text, targetLanguage) {
|
| 1333 |
+
if (!currentApiKey) {
|
| 1334 |
+
throw new Error('API key is required for translation');
|
| 1335 |
+
}
|
| 1336 |
+
|
| 1337 |
+
const languageName = languageNames[targetLanguage] || 'English';
|
| 1338 |
+
|
| 1339 |
+
const prompt = `Translate the following text to ${languageName}. Provide ONLY the exact translation without any explanations, additional information, or formatting:
|
| 1340 |
+
|
| 1341 |
+
"${text}"`;
|
| 1342 |
+
|
| 1343 |
+
const payload = {
|
| 1344 |
+
model: "gpt-4o-mini",
|
| 1345 |
+
messages: [{ role: "user", content: prompt }],
|
| 1346 |
+
max_tokens: 500,
|
| 1347 |
+
temperature: 0.1
|
| 1348 |
+
};
|
| 1349 |
+
|
| 1350 |
+
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
| 1351 |
+
method: "POST",
|
| 1352 |
+
headers: {
|
| 1353 |
+
"Content-Type": "application/json",
|
| 1354 |
+
"Authorization": `Bearer ${currentApiKey}`
|
| 1355 |
+
},
|
| 1356 |
+
body: JSON.stringify(payload)
|
| 1357 |
+
});
|
| 1358 |
+
|
| 1359 |
+
if (!response.ok) {
|
| 1360 |
+
const errorData = await response.json();
|
| 1361 |
+
throw new Error(errorData.error?.message || "Translation API request failed");
|
| 1362 |
+
}
|
| 1363 |
+
|
| 1364 |
+
const data = await response.json();
|
| 1365 |
+
return data.choices[0].message.content.trim();
|
| 1366 |
+
}
|
| 1367 |
+
|
| 1368 |
+
// Apply cached translations to UI
|
| 1369 |
+
function applyCachedTranslations(translations) {
|
| 1370 |
+
// Apply text translations
|
| 1371 |
+
Object.keys(translations.texts).forEach(originalText => {
|
| 1372 |
+
const translation = translations.texts[originalText];
|
| 1373 |
+
const elements = document.querySelectorAll(`[data-translate]`);
|
| 1374 |
+
|
| 1375 |
+
elements.forEach(element => {
|
| 1376 |
+
const originalElementText = element.getAttribute('data-original-text') || element.textContent;
|
| 1377 |
+
if (originalElementText === originalText) {
|
| 1378 |
+
element.textContent = translation;
|
| 1379 |
+
}
|
| 1380 |
+
});
|
| 1381 |
+
});
|
| 1382 |
+
|
| 1383 |
+
// Apply placeholder translations
|
| 1384 |
+
Object.keys(translations.placeholders).forEach(originalPlaceholder => {
|
| 1385 |
+
const translation = translations.placeholders[originalPlaceholder];
|
| 1386 |
+
const elements = document.querySelectorAll(`[data-translate-placeholder]`);
|
| 1387 |
+
|
| 1388 |
+
elements.forEach(element => {
|
| 1389 |
+
const originalElementPlaceholder = element.getAttribute('data-original-placeholder') || element.placeholder;
|
| 1390 |
+
if (originalElementPlaceholder === originalPlaceholder) {
|
| 1391 |
+
element.placeholder = translation;
|
| 1392 |
+
}
|
| 1393 |
+
});
|
| 1394 |
+
});
|
| 1395 |
+
}
|
| 1396 |
+
|
| 1397 |
+
// Translate all UI elements
|
| 1398 |
+
async function translateInterface(targetLanguage) {
|
| 1399 |
+
if (targetLanguage === 'en') {
|
| 1400 |
+
// No translation needed for English
|
| 1401 |
+
return;
|
| 1402 |
+
}
|
| 1403 |
+
|
| 1404 |
+
// Check if translations are cached
|
| 1405 |
+
const cachedTranslations = loadTranslationsFromCache(targetLanguage);
|
| 1406 |
+
if (cachedTranslations) {
|
| 1407 |
+
// Use cached translations
|
| 1408 |
+
console.log('Using cached translations for', targetLanguage);
|
| 1409 |
+
applyCachedTranslations(cachedTranslations);
|
| 1410 |
+
return;
|
| 1411 |
+
}
|
| 1412 |
+
|
| 1413 |
+
// Need to translate via API
|
| 1414 |
+
showTranslationOverlay();
|
| 1415 |
+
|
| 1416 |
+
try {
|
| 1417 |
+
// Get all elements with data-translate attribute
|
| 1418 |
+
const elements = document.querySelectorAll('[data-translate]');
|
| 1419 |
+
const placeholderElements = document.querySelectorAll('[data-translate-placeholder]');
|
| 1420 |
+
|
| 1421 |
+
// Collect all texts to translate
|
| 1422 |
+
const textsToTranslate = [];
|
| 1423 |
+
const placeholdersToTranslate = [];
|
| 1424 |
+
const elementMap = new Map();
|
| 1425 |
+
|
| 1426 |
+
elements.forEach(element => {
|
| 1427 |
+
const originalText = element.getAttribute('data-original-text') || element.textContent;
|
| 1428 |
+
if (!element.getAttribute('data-original-text')) {
|
| 1429 |
+
element.setAttribute('data-original-text', originalText);
|
| 1430 |
+
}
|
| 1431 |
+
textsToTranslate.push(originalText);
|
| 1432 |
+
elementMap.set(originalText, element);
|
| 1433 |
+
});
|
| 1434 |
+
|
| 1435 |
+
placeholderElements.forEach(element => {
|
| 1436 |
+
const originalPlaceholder = element.getAttribute('data-original-placeholder') || element.placeholder;
|
| 1437 |
+
if (!element.getAttribute('data-original-placeholder')) {
|
| 1438 |
+
element.setAttribute('data-original-placeholder', originalPlaceholder);
|
| 1439 |
+
}
|
| 1440 |
+
placeholdersToTranslate.push(originalPlaceholder);
|
| 1441 |
+
elementMap.set(originalPlaceholder, element);
|
| 1442 |
+
});
|
| 1443 |
+
|
| 1444 |
+
// Prepare cache structure
|
| 1445 |
+
const translationsCache = {
|
| 1446 |
+
texts: {},
|
| 1447 |
+
placeholders: {}
|
| 1448 |
+
};
|
| 1449 |
+
|
| 1450 |
+
// Translate texts in batches
|
| 1451 |
+
const batchSize = 10;
|
| 1452 |
+
const allTexts = [...textsToTranslate, ...placeholdersToTranslate];
|
| 1453 |
+
|
| 1454 |
+
for (let i = 0; i < allTexts.length; i += batchSize) {
|
| 1455 |
+
const batch = allTexts.slice(i, i + batchSize);
|
| 1456 |
+
|
| 1457 |
+
// Update progress
|
| 1458 |
+
updateTranslationProgress(i, allTexts.length);
|
| 1459 |
+
|
| 1460 |
+
// Translate batch
|
| 1461 |
+
const translations = await Promise.all(
|
| 1462 |
+
batch.map(text => translateText(text, targetLanguage))
|
| 1463 |
+
);
|
| 1464 |
+
|
| 1465 |
+
// Apply translations and cache them
|
| 1466 |
+
batch.forEach((originalText, index) => {
|
| 1467 |
+
const element = elementMap.get(originalText);
|
| 1468 |
+
const translation = translations[index];
|
| 1469 |
+
|
| 1470 |
+
if (element.hasAttribute('data-translate')) {
|
| 1471 |
+
element.textContent = translation;
|
| 1472 |
+
translationsCache.texts[originalText] = translation;
|
| 1473 |
+
} else if (element.hasAttribute('data-translate-placeholder')) {
|
| 1474 |
+
element.placeholder = translation;
|
| 1475 |
+
translationsCache.placeholders[originalText] = translation;
|
| 1476 |
+
}
|
| 1477 |
+
});
|
| 1478 |
+
}
|
| 1479 |
+
|
| 1480 |
+
// Save translations to cache
|
| 1481 |
+
saveTranslationsToCache(targetLanguage, translationsCache);
|
| 1482 |
+
|
| 1483 |
+
// Update cache status
|
| 1484 |
+
updateCacheStatus(targetLanguage);
|
| 1485 |
+
updateCacheStatusDisplay();
|
| 1486 |
+
|
| 1487 |
+
} catch (error) {
|
| 1488 |
+
console.error('Translation error:', error);
|
| 1489 |
+
showError('Translation failed: ' + error.message);
|
| 1490 |
+
} finally {
|
| 1491 |
+
hideTranslationOverlay();
|
| 1492 |
+
}
|
| 1493 |
+
}
|
| 1494 |
+
|
| 1495 |
+
// Show translation overlay
|
| 1496 |
+
function showTranslationOverlay() {
|
| 1497 |
+
document.getElementById('translationOverlay').style.display = 'flex';
|
| 1498 |
+
}
|
| 1499 |
+
|
| 1500 |
+
// Hide translation overlay
|
| 1501 |
+
function hideTranslationOverlay() {
|
| 1502 |
+
document.getElementById('translationOverlay').style.display = 'none';
|
| 1503 |
+
}
|
| 1504 |
+
|
| 1505 |
+
// Update translation progress
|
| 1506 |
+
function updateTranslationProgress(current, total) {
|
| 1507 |
+
const percentage = Math.round((current / total) * 100);
|
| 1508 |
+
document.getElementById('translationMessage').textContent =
|
| 1509 |
+
`Translating interface... ${percentage}% complete (will be cached for future use)`;
|
| 1510 |
+
}
|
| 1511 |
+
|
| 1512 |
+
// Apply language with API translation or cache
|
| 1513 |
+
async function applyLanguage(language) {
|
| 1514 |
+
applyDirection(language);
|
| 1515 |
+
|
| 1516 |
+
if (language !== 'en') {
|
| 1517 |
+
await translateInterface(language);
|
| 1518 |
+
}
|
| 1519 |
+
}
|
| 1520 |
+
|
| 1521 |
+
// Show language landing page
|
| 1522 |
+
function showLanguageLanding() {
|
| 1523 |
+
document.getElementById('languageLanding').style.display = 'block';
|
| 1524 |
+
document.getElementById('mainApp').style.display = 'none';
|
| 1525 |
+
}
|
| 1526 |
+
|
| 1527 |
+
// Show main application
|
| 1528 |
+
function showMainApp() {
|
| 1529 |
+
document.getElementById('languageLanding').style.display = 'none';
|
| 1530 |
+
document.getElementById('mainApp').style.display = 'block';
|
| 1531 |
+
|
| 1532 |
+
// Set API key in main app
|
| 1533 |
+
document.getElementById('apiKey').value = currentApiKey;
|
| 1534 |
+
}
|
| 1535 |
+
|
| 1536 |
+
// Start button click handler
|
| 1537 |
+
document.getElementById('startBtn').addEventListener('click', async function() {
|
| 1538 |
+
const selectedLanguage = document.getElementById('languageSelect').value;
|
| 1539 |
+
const apiKey = document.getElementById('apiKeyLanding').value.trim();
|
| 1540 |
+
|
| 1541 |
+
if (!apiKey) {
|
| 1542 |
+
alert('Please enter your OpenAI API key');
|
| 1543 |
+
return;
|
| 1544 |
+
}
|
| 1545 |
+
|
| 1546 |
+
currentLanguage = selectedLanguage;
|
| 1547 |
+
currentApiKey = apiKey;
|
| 1548 |
+
|
| 1549 |
+
// Save API key
|
| 1550 |
+
localStorage.setItem('educational_analyzer_api_key', apiKey);
|
| 1551 |
+
|
| 1552 |
+
// Apply language with translation (cached or API)
|
| 1553 |
+
await applyLanguage(selectedLanguage);
|
| 1554 |
+
|
| 1555 |
+
// Show main app
|
| 1556 |
+
showMainApp();
|
| 1557 |
+
});
|
| 1558 |
+
|
| 1559 |
+
// Language selector change handler
|
| 1560 |
+
document.getElementById('languageSelect').addEventListener('change', async function() {
|
| 1561 |
+
const selectedLanguage = this.value;
|
| 1562 |
+
updateCacheStatus(selectedLanguage);
|
| 1563 |
+
|
| 1564 |
+
if (currentApiKey) {
|
| 1565 |
+
await applyLanguage(selectedLanguage);
|
| 1566 |
+
} else {
|
| 1567 |
+
applyDirection(selectedLanguage);
|
| 1568 |
+
}
|
| 1569 |
+
});
|
| 1570 |
+
|
| 1571 |
+
// Clear cache button handler
|
| 1572 |
+
document.getElementById('clearCacheBtn').addEventListener('click', clearAllTranslationCache);
|
| 1573 |
+
|
| 1574 |
+
// API key sync between landing and main app
|
| 1575 |
+
document.getElementById('apiKeyLanding').addEventListener('input', function() {
|
| 1576 |
+
currentApiKey = this.value;
|
| 1577 |
+
localStorage.setItem('educational_analyzer_api_key', this.value);
|
| 1578 |
+
document.getElementById('apiKey').value = this.value;
|
| 1579 |
+
});
|
| 1580 |
+
|
| 1581 |
+
document.getElementById('apiKey').addEventListener('input', function() {
|
| 1582 |
+
currentApiKey = this.value;
|
| 1583 |
+
localStorage.setItem('educational_analyzer_api_key', this.value);
|
| 1584 |
+
document.getElementById('apiKeyLanding').value = this.value;
|
| 1585 |
+
});
|
| 1586 |
+
|
| 1587 |
+
// App Configuration
|
| 1588 |
+
const AppConfig = {
|
| 1589 |
+
API_BASE_URL: 'https://api.openai.com/v1/chat/completions',
|
| 1590 |
+
MODEL: 'gpt-4o-mini',
|
| 1591 |
+
MAX_TOKENS: 2000,
|
| 1592 |
+
TEMPERATURE: 0.7
|
| 1593 |
+
};
|
| 1594 |
+
|
| 1595 |
+
// App State Management
|
| 1596 |
+
const AppState = {
|
| 1597 |
+
apiKey: '',
|
| 1598 |
+
isAnalyzing: false,
|
| 1599 |
+
currentActivity: '',
|
| 1600 |
+
|
| 1601 |
+
setApiKey(key) {
|
| 1602 |
+
this.apiKey = key;
|
| 1603 |
+
this.saveToLocalStorage();
|
| 1604 |
+
},
|
| 1605 |
+
|
| 1606 |
+
setAnalyzing(analyzing) {
|
| 1607 |
+
this.isAnalyzing = analyzing;
|
| 1608 |
+
UIController.updateAnalyzingState(analyzing);
|
| 1609 |
+
},
|
| 1610 |
+
|
| 1611 |
+
saveToLocalStorage() {
|
| 1612 |
+
try {
|
| 1613 |
+
localStorage.setItem('educational_analyzer_api_key', this.apiKey);
|
| 1614 |
+
} catch (e) {
|
| 1615 |
+
console.warn('Could not save to localStorage:', e);
|
| 1616 |
+
}
|
| 1617 |
+
},
|
| 1618 |
+
|
| 1619 |
+
loadFromLocalStorage() {
|
| 1620 |
+
try {
|
| 1621 |
+
this.apiKey = localStorage.getItem('educational_analyzer_api_key') || '';
|
| 1622 |
+
} catch (e) {
|
| 1623 |
+
console.warn('Could not load from localStorage:', e);
|
| 1624 |
+
}
|
| 1625 |
+
}
|
| 1626 |
+
};
|
| 1627 |
+
|
| 1628 |
+
// Agent Prompts - Dynamic functions to use current selected language
|
| 1629 |
+
const agentPrompts = {
|
| 1630 |
+
agent1: function(activity) {
|
| 1631 |
+
const languageName = languageNames[currentLanguage] || 'English';
|
| 1632 |
+
return `
|
| 1633 |
+
You are Agent 1, an educational technology expert. Your task is to conduct a DEEP, STRUCTURED ANALYSIS of the teaching activity described below using the PICRAT model (PIC + RAT) and Bloom's Taxonomy, with a strong emphasis on how effectively the activity fosters critical thinking.
|
| 1634 |
+
|
| 1635 |
+
IMPORTANT: Write your entire response in ${languageName} language.
|
| 1636 |
+
|
| 1637 |
+
Activity Description:
|
| 1638 |
+
${activity}
|
| 1639 |
+
|
| 1640 |
+
OUTPUT FORMAT (use these exact headings in your final response):
|
| 1641 |
+
|
| 1642 |
+
PICRAT Dimensions
|
| 1643 |
+
a. Passive (P)
|
| 1644 |
+
Provide a detailed analysis of the passive element, including examples and implications for student engagement.
|
| 1645 |
+
b. Interactive (I)
|
| 1646 |
+
Provide a detailed analysis of the interactive element, including examples and implications for student engagement.
|
| 1647 |
+
c. Creative (C)
|
| 1648 |
+
Provide a detailed analysis of the creative element, including examples and implications for student engagement.
|
| 1649 |
+
d. Replacement (R)
|
| 1650 |
+
Examine the replacement element thoroughly, highlighting how technology is used to substitute traditional methods.
|
| 1651 |
+
e. Amplification (A)
|
| 1652 |
+
Examine the amplification element thoroughly, highlighting how technology is used to enhance traditional methods.
|
| 1653 |
+
f. Transformation (T)
|
| 1654 |
+
Examine the transformation element thoroughly, highlighting how technology is used to transform learning experiences.
|
| 1655 |
+
|
| 1656 |
+
Bloom's Taxonomy
|
| 1657 |
+
Identify and explain the cognitive level(s) addressed (Remembering, Understanding, Applying, Analyzing, Evaluating, Creating) with specific references to the activity.
|
| 1658 |
+
|
| 1659 |
+
Relationship Between PICRAT & Bloom's
|
| 1660 |
+
Analyze how the chosen PICRAT categories align with or support the identified Bloom's level(s), illustrating their interconnectivity.
|
| 1661 |
+
|
| 1662 |
+
Critical Thinking
|
| 1663 |
+
Assess to what extent this activity fosters critical thinking, providing examples of how students are encouraged to engage in higher-order thinking.
|
| 1664 |
+
|
| 1665 |
+
Overall Comments/Recommendations
|
| 1666 |
+
Summarize key strengths of the activity and suggest actionable improvements to enhance its effectiveness.
|
| 1667 |
+
`.trim();
|
| 1668 |
+
},
|
| 1669 |
+
|
| 1670 |
+
agent2: function(agent1Result) {
|
| 1671 |
+
const languageName = languageNames[currentLanguage] || 'English';
|
| 1672 |
+
return `
|
| 1673 |
+
You are Agent 2, a scenario developer. Based on the analysis from Agent 1, craft practical scenarios or applications that illustrate how the teaching activity can be improved or enhanced. Use Agent 1's insights verbatim as your foundation.
|
| 1674 |
+
|
| 1675 |
+
IMPORTANT: Write your entire response in ${languageName} language.
|
| 1676 |
+
|
| 1677 |
+
Agent 1's Analysis:
|
| 1678 |
+
${agent1Result}
|
| 1679 |
+
|
| 1680 |
+
Instructions:
|
| 1681 |
+
1. Provide realistic classroom or online teaching scenarios.
|
| 1682 |
+
2. Address technology integration, engagement strategies, and cognitive depth.
|
| 1683 |
+
3. Include any potential pitfalls or variations for different subjects or grade levels.
|
| 1684 |
+
|
| 1685 |
+
Output only your final scenarios.
|
| 1686 |
+
`.trim();
|
| 1687 |
+
},
|
| 1688 |
+
|
| 1689 |
+
agent3: function(agent1Result, agent2Result) {
|
| 1690 |
+
const languageName = languageNames[currentLanguage] || 'English';
|
| 1691 |
+
return `
|
| 1692 |
+
You are Agent 3, a meta-reviewer. You have access to the outputs from Agent 1 and Agent 2. Provide overarching feedback and a high-level overview that ties both analyses and scenarios together.
|
| 1693 |
+
|
| 1694 |
+
IMPORTANT: Write your entire response in ${languageName} language.
|
| 1695 |
+
|
| 1696 |
+
Agent 1's Analysis:
|
| 1697 |
+
${agent1Result}
|
| 1698 |
+
|
| 1699 |
+
Agent 2's Scenarios:
|
| 1700 |
+
${agent2Result}
|
| 1701 |
+
|
| 1702 |
+
Instructions:
|
| 1703 |
+
1. Summarize the key insights from Agents 1 and 2.
|
| 1704 |
+
2. Discuss overall alignment with best practices in technology integration and higher-order thinking.
|
| 1705 |
+
3. Suggest any final recommendations or overarching considerations (e.g., accessibility, long-term professional growth).
|
| 1706 |
+
|
| 1707 |
+
Output only your final feedback and overview.
|
| 1708 |
+
`.trim();
|
| 1709 |
+
}
|
| 1710 |
+
};
|
| 1711 |
+
|
| 1712 |
+
// API Service Module
|
| 1713 |
+
const APIService = {
|
| 1714 |
+
async callGPT(prompt, apiKey) {
|
| 1715 |
+
const payload = {
|
| 1716 |
+
model: AppConfig.MODEL,
|
| 1717 |
+
messages: [{ role: 'user', content: prompt }],
|
| 1718 |
+
max_tokens: AppConfig.MAX_TOKENS,
|
| 1719 |
+
temperature: AppConfig.TEMPERATURE
|
| 1720 |
+
};
|
| 1721 |
+
|
| 1722 |
+
const response = await fetch(AppConfig.API_BASE_URL, {
|
| 1723 |
+
method: 'POST',
|
| 1724 |
+
headers: {
|
| 1725 |
+
'Content-Type': 'application/json',
|
| 1726 |
+
'Authorization': `Bearer ${apiKey}`
|
| 1727 |
+
},
|
| 1728 |
+
body: JSON.stringify(payload)
|
| 1729 |
+
});
|
| 1730 |
+
|
| 1731 |
+
if (!response.ok) {
|
| 1732 |
+
const errorData = await response.json();
|
| 1733 |
+
throw new Error(errorData.error?.message || `HTTP ${response.status}: ${response.statusText}`);
|
| 1734 |
+
}
|
| 1735 |
+
|
| 1736 |
+
const data = await response.json();
|
| 1737 |
+
return data.choices?.[0]?.message?.content || 'No output received.';
|
| 1738 |
+
}
|
| 1739 |
+
};
|
| 1740 |
+
|
| 1741 |
+
// Simulation Service for Demo Mode
|
| 1742 |
+
const SimulationService = {
|
| 1743 |
+
getSimulatedResponse(agentName, placeholders) {
|
| 1744 |
+
switch (agentName) {
|
| 1745 |
+
case "agent1":
|
| 1746 |
+
return `
|
| 1747 |
+
1. PICRAT Dimensions
|
| 1748 |
+
a. PIC Classification (Interactive)
|
| 1749 |
+
b. RAT Classification (Amplification)
|
| 1750 |
+
|
| 1751 |
+
2. Bloom's Taxonomy
|
| 1752 |
+
- Applying, Analyzing
|
| 1753 |
+
|
| 1754 |
+
3. Relationship Between PICRAT & Bloom's
|
| 1755 |
+
- Interactive use of tech supports mid-level Bloom's tasks
|
| 1756 |
+
|
| 1757 |
+
4. Critical Thinking
|
| 1758 |
+
- Moderate level; students engage with real-world data but do not create or evaluate complex outputs
|
| 1759 |
+
|
| 1760 |
+
5. Overall Comments/Recommendations
|
| 1761 |
+
- Strength: Encourages active student participation
|
| 1762 |
+
- Recommendation: Incorporate a peer-evaluation component to push into higher Bloom's levels
|
| 1763 |
+
`.trim();
|
| 1764 |
+
case "agent2":
|
| 1765 |
+
return `
|
| 1766 |
+
[SIMULATED Agent 2 Scenarios]
|
| 1767 |
+
1) Students collaborate in groups to apply the analyzed data in a new project, amplifying the original activity.
|
| 1768 |
+
2) Introduce a mini-debate or panel discussion, using technology for real-time data visualization and deeper analysis.
|
| 1769 |
+
`.trim();
|
| 1770 |
+
case "agent3":
|
| 1771 |
+
return `
|
| 1772 |
+
[SIMULATED Agent 3 Feedback & Overview]
|
| 1773 |
+
Overall alignment with best practices: Encourages interactive use of tech and mid-level Bloom's.
|
| 1774 |
+
Recommendation: Integrate a reflection stage to foster higher-order thinking and transform the activity into a more creative endeavor.
|
| 1775 |
+
`.trim();
|
| 1776 |
+
default:
|
| 1777 |
+
return "[No simulation available]";
|
| 1778 |
+
}
|
| 1779 |
+
}
|
| 1780 |
+
};
|
| 1781 |
+
|
| 1782 |
+
// UI Controller Module
|
| 1783 |
+
const UIController = {
|
| 1784 |
+
elements: {},
|
| 1785 |
+
|
| 1786 |
+
init() {
|
| 1787 |
+
this.elements = {
|
| 1788 |
+
apiKeyInput: document.getElementById('apiKey'),
|
| 1789 |
+
analysisForm: document.getElementById('analysisForm'),
|
| 1790 |
+
activityDescription: document.getElementById('activityDescription'),
|
| 1791 |
+
analyzeButton: document.querySelector('.analyze-button'),
|
| 1792 |
+
loadingSpinner: document.getElementById('loadingSpinner'),
|
| 1793 |
+
buttonText: document.querySelector('.button-text'),
|
| 1794 |
+
agent1Card: document.getElementById('agent1Card'),
|
| 1795 |
+
agent2Card: document.getElementById('agent2Card'),
|
| 1796 |
+
agent3Card: document.getElementById('agent3Card'),
|
| 1797 |
+
analysisOutput1: document.getElementById('analysisOutput1'),
|
| 1798 |
+
analysisOutput2: document.getElementById('analysisOutput2'),
|
| 1799 |
+
analysisOutput3: document.getElementById('analysisOutput3')
|
| 1800 |
+
};
|
| 1801 |
+
|
| 1802 |
+
this.setupEventListeners();
|
| 1803 |
+
},
|
| 1804 |
+
|
| 1805 |
+
setupEventListeners() {
|
| 1806 |
+
this.elements.apiKeyInput.addEventListener('input', (e) => {
|
| 1807 |
+
AppState.setApiKey(e.target.value.trim());
|
| 1808 |
+
});
|
| 1809 |
+
|
| 1810 |
+
this.elements.analysisForm.addEventListener('submit', (e) => {
|
| 1811 |
+
e.preventDefault();
|
| 1812 |
+
App.analyzeActivity();
|
| 1813 |
+
});
|
| 1814 |
+
},
|
| 1815 |
+
|
| 1816 |
+
updateAnalyzingState(isAnalyzing) {
|
| 1817 |
+
if (isAnalyzing) {
|
| 1818 |
+
this.elements.analyzeButton.disabled = true;
|
| 1819 |
+
this.elements.buttonText.style.opacity = '0';
|
| 1820 |
+
this.elements.loadingSpinner.style.display = 'block';
|
| 1821 |
+
} else {
|
| 1822 |
+
this.elements.analyzeButton.disabled = false;
|
| 1823 |
+
this.elements.buttonText.style.opacity = '1';
|
| 1824 |
+
this.elements.loadingSpinner.style.display = 'none';
|
| 1825 |
+
}
|
| 1826 |
+
},
|
| 1827 |
+
|
| 1828 |
+
setAgentLoading(agentNumber, isLoading) {
|
| 1829 |
+
const card = this.elements[`agent${agentNumber}Card`];
|
| 1830 |
+
if (isLoading) {
|
| 1831 |
+
card.classList.add('loading');
|
| 1832 |
+
this.elements[`analysisOutput${agentNumber}`].textContent = '';
|
| 1833 |
+
} else {
|
| 1834 |
+
card.classList.remove('loading');
|
| 1835 |
+
}
|
| 1836 |
+
},
|
| 1837 |
+
|
| 1838 |
+
setAgentContent(agentNumber, content) {
|
| 1839 |
+
this.elements[`analysisOutput${agentNumber}`].textContent = content;
|
| 1840 |
+
},
|
| 1841 |
+
|
| 1842 |
+
clearAllOutputs() {
|
| 1843 |
+
for (let i = 1; i <= 3; i++) {
|
| 1844 |
+
this.elements[`analysisOutput${i}`].textContent = '';
|
| 1845 |
+
this.elements[`agent${i}Card`].classList.remove('loading');
|
| 1846 |
+
}
|
| 1847 |
+
},
|
| 1848 |
+
|
| 1849 |
+
showError(message) {
|
| 1850 |
+
const errorHtml = `
|
| 1851 |
+
<div class="error-message">
|
| 1852 |
+
<span class="error-icon">⚠️</span>
|
| 1853 |
+
<span class="error-text">${message}</span>
|
| 1854 |
+
<button class="error-dismiss" onclick="this.parentElement.remove()">×</button>
|
| 1855 |
+
</div>
|
| 1856 |
+
`;
|
| 1857 |
+
|
| 1858 |
+
const inputSection = document.querySelector('.input-section');
|
| 1859 |
+
if (inputSection) {
|
| 1860 |
+
inputSection.insertAdjacentHTML('afterbegin', errorHtml);
|
| 1861 |
+
}
|
| 1862 |
+
}
|
| 1863 |
+
};
|
| 1864 |
+
|
| 1865 |
+
// Error Handler Module
|
| 1866 |
+
const ErrorHandler = {
|
| 1867 |
+
handleError(error, agentNumber = null) {
|
| 1868 |
+
console.error('Application error:', error);
|
| 1869 |
+
|
| 1870 |
+
let userMessage = 'An unexpected error occurred. Please try again.';
|
| 1871 |
+
|
| 1872 |
+
if (error.message.includes('API key')) {
|
| 1873 |
+
userMessage = 'Invalid API key. Please check your OpenAI API key and try again.';
|
| 1874 |
+
} else if (error.message.includes('network') || error.message.includes('fetch')) {
|
| 1875 |
+
userMessage = 'Network error. Please check your internet connection and try again.';
|
| 1876 |
+
} else if (error.message.includes('rate limit')) {
|
| 1877 |
+
userMessage = 'Rate limit exceeded. Please wait a moment before trying again.';
|
| 1878 |
+
} else if (error.message.includes('quota')) {
|
| 1879 |
+
userMessage = 'API quota exceeded. Please check your OpenAI account usage.';
|
| 1880 |
+
}
|
| 1881 |
+
|
| 1882 |
+
if (agentNumber) {
|
| 1883 |
+
UIController.setAgentContent(agentNumber, `Error: ${userMessage}`);
|
| 1884 |
+
} else {
|
| 1885 |
+
UIController.showError(userMessage);
|
| 1886 |
+
}
|
| 1887 |
+
}
|
| 1888 |
+
};
|
| 1889 |
+
|
| 1890 |
+
// Input Validator Module
|
| 1891 |
+
const InputValidator = {
|
| 1892 |
+
validateActivity(activity) {
|
| 1893 |
+
if (!activity || activity.trim().length < 10) {
|
| 1894 |
+
throw new Error('Please provide a more detailed description of your teaching activity (at least 10 characters).');
|
| 1895 |
+
}
|
| 1896 |
+
return true;
|
| 1897 |
+
}
|
| 1898 |
+
};
|
| 1899 |
+
|
| 1900 |
+
// Main App Module
|
| 1901 |
+
const App = {
|
| 1902 |
+
init() {
|
| 1903 |
+
AppState.loadFromLocalStorage();
|
| 1904 |
+
UIController.init();
|
| 1905 |
+
|
| 1906 |
+
// Load saved API key
|
| 1907 |
+
if (AppState.apiKey) {
|
| 1908 |
+
UIController.elements.apiKeyInput.value = AppState.apiKey;
|
| 1909 |
+
}
|
| 1910 |
+
|
| 1911 |
+
console.log('Educational Activity Intelligence Analyzer initialized');
|
| 1912 |
+
},
|
| 1913 |
+
|
| 1914 |
+
async analyzeActivity() {
|
| 1915 |
+
if (AppState.isAnalyzing) return;
|
| 1916 |
+
|
| 1917 |
+
try {
|
| 1918 |
+
const activity = UIController.elements.activityDescription.value.trim();
|
| 1919 |
+
|
| 1920 |
+
// Validate activity description
|
| 1921 |
+
InputValidator.validateActivity(activity);
|
| 1922 |
+
|
| 1923 |
+
// Update state
|
| 1924 |
+
AppState.currentActivity = activity;
|
| 1925 |
+
AppState.setAnalyzing(true);
|
| 1926 |
+
|
| 1927 |
+
// Clear previous outputs
|
| 1928 |
+
UIController.clearAllOutputs();
|
| 1929 |
+
|
| 1930 |
+
// Get API key
|
| 1931 |
+
const apiKey = UIController.elements.apiKeyInput.value.trim();
|
| 1932 |
+
|
| 1933 |
+
// Update API key in state
|
| 1934 |
+
if (apiKey) {
|
| 1935 |
+
AppState.setApiKey(apiKey);
|
| 1936 |
+
}
|
| 1937 |
+
|
| 1938 |
+
// Run agents sequentially
|
| 1939 |
+
await this.runAgent1(activity, apiKey);
|
| 1940 |
+
await this.runAgent2(apiKey);
|
| 1941 |
+
await this.runAgent3(apiKey);
|
| 1942 |
+
|
| 1943 |
+
} catch (error) {
|
| 1944 |
+
ErrorHandler.handleError(error);
|
| 1945 |
+
} finally {
|
| 1946 |
+
AppState.setAnalyzing(false);
|
| 1947 |
+
}
|
| 1948 |
+
},
|
| 1949 |
+
|
| 1950 |
+
async runAgent1(activity, apiKey) {
|
| 1951 |
+
try {
|
| 1952 |
+
UIController.setAgentLoading(1, true);
|
| 1953 |
+
|
| 1954 |
+
const prompt = agentPrompts.agent1(activity);
|
| 1955 |
+
|
| 1956 |
+
let result;
|
| 1957 |
+
if (!apiKey) {
|
| 1958 |
+
// Simulate delay for demo
|
| 1959 |
+
await new Promise(resolve => setTimeout(resolve, 1500));
|
| 1960 |
+
result = SimulationService.getSimulatedResponse('agent1', { ACTIVITY: activity });
|
| 1961 |
+
} else {
|
| 1962 |
+
result = await APIService.callGPT(prompt, apiKey);
|
| 1963 |
+
}
|
| 1964 |
+
|
| 1965 |
+
AppState.agent1Result = result;
|
| 1966 |
+
UIController.setAgentContent(1, result);
|
| 1967 |
+
|
| 1968 |
+
} catch (error) {
|
| 1969 |
+
ErrorHandler.handleError(error, 1);
|
| 1970 |
+
} finally {
|
| 1971 |
+
UIController.setAgentLoading(1, false);
|
| 1972 |
+
}
|
| 1973 |
+
},
|
| 1974 |
+
|
| 1975 |
+
async runAgent2(apiKey) {
|
| 1976 |
+
try {
|
| 1977 |
+
UIController.setAgentLoading(2, true);
|
| 1978 |
+
|
| 1979 |
+
const prompt = agentPrompts.agent2(AppState.agent1Result || '');
|
| 1980 |
+
|
| 1981 |
+
let result;
|
| 1982 |
+
if (!apiKey) {
|
| 1983 |
+
// Simulate delay for demo
|
| 1984 |
+
await new Promise(resolve => setTimeout(resolve, 1200));
|
| 1985 |
+
result = SimulationService.getSimulatedResponse('agent2', { AGENT1_RESULT: AppState.agent1Result });
|
| 1986 |
+
} else {
|
| 1987 |
+
result = await APIService.callGPT(prompt, apiKey);
|
| 1988 |
+
}
|
| 1989 |
+
|
| 1990 |
+
AppState.agent2Result = result;
|
| 1991 |
+
UIController.setAgentContent(2, result);
|
| 1992 |
+
|
| 1993 |
+
} catch (error) {
|
| 1994 |
+
ErrorHandler.handleError(error, 2);
|
| 1995 |
+
} finally {
|
| 1996 |
+
UIController.setAgentLoading(2, false);
|
| 1997 |
+
}
|
| 1998 |
+
},
|
| 1999 |
+
|
| 2000 |
+
async runAgent3(apiKey) {
|
| 2001 |
+
try {
|
| 2002 |
+
UIController.setAgentLoading(3, true);
|
| 2003 |
+
|
| 2004 |
+
const prompt = agentPrompts.agent3(AppState.agent1Result || '', AppState.agent2Result || '');
|
| 2005 |
+
|
| 2006 |
+
let result;
|
| 2007 |
+
if (!apiKey) {
|
| 2008 |
+
// Simulate delay for demo
|
| 2009 |
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
| 2010 |
+
result = SimulationService.getSimulatedResponse('agent3', {
|
| 2011 |
+
AGENT1_RESULT: AppState.agent1Result,
|
| 2012 |
+
AGENT2_RESULT: AppState.agent2Result
|
| 2013 |
+
});
|
| 2014 |
+
} else {
|
| 2015 |
+
result = await APIService.callGPT(prompt, apiKey);
|
| 2016 |
+
}
|
| 2017 |
+
|
| 2018 |
+
UIController.setAgentContent(3, result);
|
| 2019 |
+
|
| 2020 |
+
} catch (error) {
|
| 2021 |
+
ErrorHandler.handleError(error, 3);
|
| 2022 |
+
} finally {
|
| 2023 |
+
UIController.setAgentLoading(3, false);
|
| 2024 |
+
}
|
| 2025 |
+
}
|
| 2026 |
+
};
|
| 2027 |
+
|
| 2028 |
+
// Initialize app when DOM is loaded
|
| 2029 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 2030 |
+
initializeApp();
|
| 2031 |
+
App.init();
|
| 2032 |
+
});
|
| 2033 |
+
</script>
|
| 2034 |
+
</body>
|
| 2035 |
+
</html>
|
| 2036 |
+
|
📘 Educator & Student Guide Educati.txt
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
📘 Educator & Student Guide: Educational Activity Intelligence Analyzer
|
| 2 |
+
1. Purpose & Impact
|
| 3 |
+
This tool enables any teacher, trainer, or researcher to perform a deep, AI-driven analysis of teaching activities—evaluating engagement, technology use, and cognitive demand using evidence-based frameworks (PICRAT, Bloom’s).
|
| 4 |
+
|
| 5 |
+
2. Step-by-Step Instructions
|
| 6 |
+
A. Setup
|
| 7 |
+
Open the tool (local file or Hugging Face Space).
|
| 8 |
+
|
| 9 |
+
Select your preferred language (RTL/LTR and 90+ options).
|
| 10 |
+
|
| 11 |
+
Enter your OpenAI API key (kept private in-browser).
|
| 12 |
+
|
| 13 |
+
B. Input a Teaching Activity
|
| 14 |
+
Type or paste your lesson plan, teaching idea, or classroom scenario (at least 10 characters).
|
| 15 |
+
|
| 16 |
+
Be specific about context, goals, and technology used for the most robust analysis.
|
| 17 |
+
|
| 18 |
+
C. Run Multi-Agent Analysis
|
| 19 |
+
Click “Analyze Activity”.
|
| 20 |
+
|
| 21 |
+
Agent 1:
|
| 22 |
+
|
| 23 |
+
Provides a deep, structured breakdown using the PICRAT model and Bloom’s Taxonomy.
|
| 24 |
+
|
| 25 |
+
Includes critical thinking assessment and actionable recommendations.
|
| 26 |
+
|
| 27 |
+
Agent 2:
|
| 28 |
+
|
| 29 |
+
Generates practical improvement scenarios and strategies based on Agent 1.
|
| 30 |
+
|
| 31 |
+
Agent 3:
|
| 32 |
+
|
| 33 |
+
Offers a high-level synthesis and strategic recommendations.
|
| 34 |
+
|
| 35 |
+
D. Review & Use Output
|
| 36 |
+
Copy/paste any or all outputs for lesson planning, peer review, portfolio, or further reflection.
|
| 37 |
+
|
| 38 |
+
Switch language to instantly translate all UI and output—great for ELLs, bilingual teams, or international training.
|
| 39 |
+
|
| 40 |
+
3. Best Practices & Classroom Ideas
|
| 41 |
+
Lesson Design:
|
| 42 |
+
|
| 43 |
+
Use before or after teaching to refine digital integration and student engagement.
|
| 44 |
+
|
| 45 |
+
Peer Review:
|
| 46 |
+
|
| 47 |
+
Share outputs with colleagues for collaborative improvement.
|
| 48 |
+
|
| 49 |
+
PD Sessions:
|
| 50 |
+
|
| 51 |
+
Analyze sample activities together, compare outputs, and discuss strategies.
|
| 52 |
+
|
| 53 |
+
Student Projects:
|
| 54 |
+
|
| 55 |
+
Have students design activities and run them through the analyzer to see cognitive and tech alignment.
|
| 56 |
+
|
| 57 |
+
4. Advanced Tips
|
| 58 |
+
Be detailed: The richer your activity description, the more valuable the insights.
|
| 59 |
+
|
| 60 |
+
Repeat for growth: Run analyses for different classes or iterations to track improvement.
|
| 61 |
+
|
| 62 |
+
Cache control: Use cache tools to manage translation memory for multilingual settings.
|
| 63 |
+
|
| 64 |
+
5. Troubleshooting & Support
|
| 65 |
+
API Errors:
|
| 66 |
+
|
| 67 |
+
Check your OpenAI API key and quota.
|
| 68 |
+
|
| 69 |
+
Slow translation?
|
| 70 |
+
|
| 71 |
+
First use in a language may take longer (cached for next time).
|
| 72 |
+
|
| 73 |
+
Need help?
|
| 74 |
+
|
| 75 |
+
Email info@shiftmind.io or visit www.shiftmind.io
|
| 76 |
+
|
| 77 |
+
This tool helps educators, students, and researchers unlock the full potential of their teaching activities—across every language, context, and technology.
|
| 78 |
+
|