ChaseHan commited on
Commit
415ceb3
·
verified ·
1 Parent(s): 28e2bf4

Upload 19 files

Browse files
Files changed (7) hide show
  1. README.md +220 -13
  2. app.py +24 -483
  3. assets/script.js +39 -0
  4. assets/style.css +474 -0
  5. requirements.txt +294 -3
  6. style.css +48 -0
  7. visualization.py +1 -1
README.md CHANGED
@@ -1,13 +1,220 @@
1
- ---
2
- title: NexusLearnAI
3
- emoji: 📊
4
- colorFrom: gray
5
- colorTo: gray
6
- sdk: gradio
7
- sdk_version: 5.23.1
8
- app_file: app.py
9
- pinned: false
10
- license: apache-2.0
11
- ---
12
-
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # LLM Educational Assistant Platform
2
+
3
+ An educational assistant platform built on Gradio, utilizing large language models to help students better understand complex concepts. Through concept decomposition and visualization, it provides personalized learning experiences for students.
4
+
5
+ ## Features
6
+
7
+ 1. **User Profile Customization**
8
+ - Input grade, subject, and learning needs
9
+ - Receive personalized learning experiences and explanations
10
+
11
+ 2. **Concept Decomposition and Visualization**
12
+ - Break down complex problems into basic concepts
13
+ - Visualize concept relationships through tree diagrams or network graphs
14
+ - Intuitively display dependencies and connections between concepts
15
+
16
+ 3. **Interactive Learning Experience**
17
+ - Click on any sub-concept to get detailed explanations
18
+ - View targeted examples and exercises
19
+ - Get recommendations for relevant learning resources
20
+
21
+ 4. **Progress Saving and Caching**
22
+ - Cache generated concept explanations to improve response speed
23
+ - Save learning records for easy review and revision
24
+
25
+ ## Installation and Running
26
+
27
+ ### Prerequisites
28
+
29
+ - Python 3.7+
30
+ - pip (Python package manager)
31
+
32
+ ```angular2html
33
+ conda create -n ai_new_dream python=3.11
34
+ pip install -r requirements.txt
35
+ export OPENAI_API_KEY="your-secret-api-key"
36
+ ```
37
+ ### Automatic Installation and Running
38
+
39
+ **Linux/Mac:**
40
+ ```bash
41
+ # Add execution permission
42
+ chmod +x run.sh
43
+
44
+ # Run startup script
45
+ ./run.sh
46
+ ```
47
+
48
+ **Windows:**
49
+ ```
50
+ # Double-click to run, or run in command prompt
51
+ run.bat
52
+ ```
53
+
54
+ ### Manual Installation and Running
55
+
56
+ ```bash
57
+ # Create virtual environment
58
+ python -m venv venv
59
+
60
+ # Activate virtual environment
61
+ # On Windows:
62
+ venv\Scripts\activate
63
+ # On Linux/Mac:
64
+ source venv/bin/activate
65
+
66
+ # Install dependencies
67
+ pip install -r requirements.txt
68
+
69
+ # Run application
70
+ python app.py
71
+ ```
72
+
73
+ ## Project Structure
74
+
75
+ ```
76
+ .
77
+ ├── app.py # Main application file
78
+ ├── prompts.py # LLM prompt templates
79
+ ├── llm_utils.py # LLM utility functions
80
+ ├── visualization.py # Concept graph visualization module
81
+ ├── cache_utils.py # Caching utilities
82
+ ├── concept_handler.js # JavaScript for concept click handling
83
+ ├── requirements.txt # Project dependencies
84
+ ├── run.sh # Linux/Mac startup script
85
+ └── run.bat # Windows startup script
86
+ ```
87
+
88
+ ## Integrated LLM
89
+
90
+ This application is integrated with the OpenAI API using the `gpt4omini` model. The implementation is in the `call_llm` function in the `llm_utils.py` file:
91
+
92
+ ```python
93
+ def call_llm(prompt: str) -> str:
94
+ """Call the OpenAI API with gpt4omini model"""
95
+ try:
96
+ from openai import OpenAI
97
+ client = OpenAI(api_key="YOUR_API_KEY")
98
+ response = client.chat.completions.create(
99
+ model="gpt4omini",
100
+ messages=[
101
+ {"role": "system", "content": "You are a helpful education assistant."},
102
+ {"role": "user", "content": prompt}
103
+ ]
104
+ )
105
+ return response.choices[0].message.content
106
+ except Exception as e:
107
+ # Fallback to mock data if API call fails
108
+ print(f"Error calling OpenAI API: {e}")
109
+ # ...
110
+ ```
111
+
112
+ If the API call fails, the system falls back to mock data to demonstrate functionality.
113
+
114
+ ## Customization and Extension
115
+
116
+ - **Adding New Subjects**: Add new subject options in the `subject_input` options in `app.py`
117
+ - **Adjusting Prompt Templates**: Modify the prompt templates in `prompts.py` to implement specific teaching styles or methods
118
+ - **Enhancing Visualization**: Modify the visualization functions in `visualization.py` to implement richer concept graph representations
119
+ - **Changing LLM Model**: To use a different model, update the `model` parameter in the `call_llm` function in `llm_utils.py`
120
+
121
+ ## Contributions and Feedback
122
+
123
+ Questions, suggestions, or code contributions are welcome to help improve this educational assistant platform!
124
+
125
+ ## 教育LLM应用
126
+
127
+ 这是一个基于大语言模型的教育应用,旨在帮助学生分解和理解复杂的学术概念。
128
+
129
+ ### 功能特点
130
+
131
+ - 根据学生的年级和学科自动调整内容难度
132
+ - 将复杂问题分解为相互关联的子概念
133
+ - 生成可视化的知识图谱
134
+ - 为每个概念提供详细解释、示例、学习资源和练习题
135
+
136
+ ### 如何运行
137
+
138
+ #### 使用脚本运行(推荐)
139
+
140
+ 1. 确保您已安装Python 3.7或更高版本
141
+ 2. 在终端中导航到项目目录
142
+
143
+ 对于Mac/Linux用户:
144
+ ```bash
145
+ chmod +x run.sh # 添加执行权限
146
+ ./run.sh # 运行脚本
147
+ ```
148
+
149
+ 对于Windows用户:
150
+ ```
151
+ run.bat
152
+ ```
153
+
154
+ #### 手动设置
155
+
156
+ 1. 创建并激活虚拟环境:
157
+ ```bash
158
+ python -m venv venv
159
+ source venv/bin/activate # Mac/Linux
160
+ venv\Scripts\activate # Windows
161
+ ```
162
+
163
+ 2. 安装依赖:
164
+ ```bash
165
+ pip install -r requirements.txt
166
+ ```
167
+
168
+ 3. 启动应用:
169
+ ```bash
170
+ python app.py
171
+ ```
172
+
173
+ ### 配置OpenAI API
174
+
175
+ 应用使用OpenAI API进行概念分解和解释。在`config.py`文件中设置您的API密钥:
176
+
177
+ ```python
178
+ OPENAI_API_KEY = "您的API密钥" # 替换为您的实际API密钥
179
+ ```
180
+
181
+ 您也可以调整其他配置参数:
182
+ - `OPENAI_MODEL`: 要使用的OpenAI模型名称
183
+ - `OPENAI_TIMEOUT`: API调用超时时间(秒)
184
+ - `OPENAI_MAX_RETRIES`: 请求失败时的最大重试次数
185
+ - `DEBUG_MODE`: 是否启用调试输出
186
+ - `USE_FALLBACK_DATA`: API失败时是否使用备用数据
187
+ - `CACHE_ENABLED`: 是否启用响应缓存
188
+
189
+ ### 系统架构
190
+
191
+ 应用由以下主要组件组成:
192
+
193
+ 1. **app.py** - 主应用文件,包含Gradio界面
194
+ 2. **llm_utils.py** - LLM调用和处理函数
195
+ 3. **visualization.py** - 知识图谱可视化
196
+ 4. **prompts.py** - LLM提示模板
197
+ 5. **cache_utils.py** - 响应缓存功能
198
+ 6. **config.py** - 应用配置
199
+ 7. **concept_handler.py** - 备用模拟数据(API失败时使用)
200
+
201
+ ### 自定义和扩展
202
+
203
+ 您可以通过以下方式自定义应用:
204
+
205
+ 1. **添加新学科**: 扩展prompts.py中的领域特定提示
206
+ 2. **调整提示模板**: 修改prompts.py中的系统和用户提示
207
+ 3. **增强可视化**: 在visualization.py中调整知识图谱的生成
208
+ 4. **更改模型**: 在config.py中指定不同的OpenAI模型
209
+
210
+ ### 故障排除
211
+
212
+ 如果遇到连接错误:
213
+ 1. 检查您的API密钥是否正确
214
+ 2. 确认您的网络连接正常
215
+ 3. 检查模型名称是否正确(例如:"gpt-4o-mini")
216
+ 4. 查看应用的调试输出(启用DEBUG_MODE)
217
+
218
+ ### 贡献
219
+
220
+ 欢迎提交问题报告和拉取请求来改进这个项目。
app.py CHANGED
@@ -13,483 +13,31 @@ from fastapi import FastAPI
13
  from fastapi.responses import JSONResponse
14
  import json
15
 
16
- # Custom CSS styles
17
- custom_css = """
18
- /* Global styles */
19
- body {
20
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;
21
- color: #333;
22
- background-color: #f7f9fc;
23
- }
24
-
25
- /* Heading styles */
26
- h1 {
27
- color: #2c3e50;
28
- font-weight: 700;
29
- margin-bottom: 1rem;
30
- }
31
-
32
- h2, h3, h4 {
33
- color: #3498db;
34
- font-weight: 600;
35
- }
36
-
37
- /* Button styles */
38
- button.primary {
39
- background: linear-gradient(135deg, #3498db, #2980b9);
40
- border: none;
41
- box-shadow: 0 4px 6px rgba(52, 152, 219, 0.3);
42
- }
43
-
44
- button.secondary {
45
- background: #ecf0f1;
46
- color: #2980b9;
47
- border: 1px solid #bdc3c7;
48
- }
49
-
50
- button:hover {
51
- transform: translateY(-2px);
52
- box-shadow: 0 6px 8px rgba(0, 0, 0, 0.1);
53
- transition: all 0.3s ease;
54
- }
55
-
56
- /* Input fields enhancement */
57
- input, textarea, select {
58
- border: 1px solid #ddd;
59
- border-radius: 8px;
60
- padding: 10px;
61
- box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05);
62
- transition: all 0.3s ease;
63
- }
64
-
65
- input:focus, textarea:focus, select:focus {
66
- border-color: #3498db;
67
- box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.25);
68
- }
69
-
70
- /* Tab styles */
71
- .tabs {
72
- border-bottom: 2px solid #e0e0e0;
73
- }
74
-
75
- .tab-selected {
76
- color: #3498db;
77
- border-bottom: 2px solid #3498db;
78
- }
79
-
80
- /* Concept card styles */
81
- .concept-card {
82
- transition: all 0.3s ease;
83
- border: 1px solid #e0e0e0;
84
- border-radius: 12px;
85
- padding: 16px;
86
- margin-bottom: 16px;
87
- cursor: pointer;
88
- background-color: #fff;
89
- box-shadow: 0 2px 5px rgba(0,0,0,0.05);
90
- }
91
-
92
- .concept-card:hover {
93
- box-shadow: 0 5px 15px rgba(0,0,0,0.1);
94
- transform: translateY(-3px);
95
- border-color: #bdc3c7;
96
- }
97
-
98
- .selected-card {
99
- border-color: #3498db;
100
- background-color: rgba(52, 152, 219, 0.05);
101
- box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.3);
102
- }
103
-
104
- .concept-title {
105
- font-weight: bold;
106
- margin-bottom: 8px;
107
- color: #2c3e50;
108
- font-size: 1.1em;
109
- }
110
-
111
- .concept-desc {
112
- font-size: 0.95em;
113
- color: #7f8c8d;
114
- line-height: 1.5;
115
- }
116
-
117
- /* Knowledge graph styles */
118
- #concept-graph {
119
- background-color: #fff;
120
- border-radius: 12px;
121
- padding: 16px;
122
- box-shadow: 0 2px 10px rgba(0,0,0,0.05);
123
- }
124
-
125
- #concept-graph img {
126
- max-width: 100%;
127
- height: auto;
128
- border-radius: 8px;
129
- box-shadow: 0 4px 15px rgba(0,0,0,0.1);
130
- transition: all 0.3s ease;
131
- }
132
-
133
- #concept-graph img:hover {
134
- box-shadow: 0 8px 25px rgba(0,0,0,0.15);
135
- }
136
-
137
- /* Example box styles */
138
- .example-box {
139
- background-color: #f1f8fe;
140
- border-left: 4px solid #3498db;
141
- padding: 15px;
142
- margin: 15px 0;
143
- border-radius: 0 8px 8px 0;
144
- }
145
-
146
- .example-box h4 {
147
- margin-top: 0;
148
- color: #2980b9;
149
- }
150
-
151
- /* Resource item styles */
152
- .resource-item {
153
- padding: 12px;
154
- margin: 10px 0;
155
- border-bottom: 1px dashed #e0e0e0;
156
- transition: all 0.2s ease;
157
- }
158
-
159
- .resource-item:hover {
160
- background-color: #f9f9f9;
161
- }
162
-
163
- /* Details and answers styles */
164
- details {
165
- margin: 10px 0;
166
- padding: 10px;
167
- border: 1px solid #e0e0e0;
168
- border-radius: 8px;
169
- background-color: #f9f9f9;
170
- }
171
-
172
- summary {
173
- cursor: pointer;
174
- color: #3498db;
175
- font-weight: 600;
176
- padding: 5px;
177
- }
178
-
179
- summary:hover {
180
- color: #2980b9;
181
- }
182
-
183
- /* Layout container styles */
184
- .container {
185
- background-color: #fff;
186
- border-radius: 12px;
187
- padding: 20px;
188
- box-shadow: 0 4px 6px rgba(0,0,0,0.05);
189
- margin-bottom: 20px;
190
- }
191
-
192
- /* Responsive adjustments */
193
- @media (max-width: 768px) {
194
- .concept-card {
195
- padding: 12px;
196
- }
197
 
198
- .example-box {
199
- padding: 12px;
200
- }
201
- }
202
-
203
- /* Answer box styles */
204
- .answer-box {
205
- background-color: #f8f9fa;
206
- border-radius: 12px;
207
- padding: 20px;
208
- margin: 15px 0;
209
- border: 1px solid #e9ecef;
210
- box-shadow: 0 2px 4px rgba(0,0,0,0.05);
211
- }
212
-
213
- .answer-content {
214
- margin-bottom: 15px;
215
- line-height: 1.6;
216
- color: #2c3e50;
217
- }
218
-
219
- .answer-content h4 {
220
- color: #3498db;
221
- margin-top: 0;
222
- margin-bottom: 10px;
223
- }
224
-
225
- .main-concept {
226
- background-color: #e3f2fd;
227
- padding: 10px 15px;
228
- border-radius: 8px;
229
- color: #1976d2;
230
- font-size: 0.95em;
231
- }
232
-
233
- .main-concept strong {
234
- color: #1565c0;
235
- }
236
-
237
- /* Answer section styles */
238
- .answer-section {
239
- margin-top: 20px;
240
- background: white;
241
- border-radius: 15px;
242
- padding: 20px;
243
- }
244
-
245
- .answer-box {
246
- background-color: #f8f9fa;
247
- border-radius: 12px;
248
- padding: 20px;
249
- margin: 15px 0;
250
- border: 1px solid #e9ecef;
251
- box-shadow: 0 2px 4px rgba(0,0,0,0.05);
252
- transition: all 0.3s ease;
253
- }
254
-
255
- .answer-box:hover {
256
- box-shadow: 0 4px 8px rgba(0,0,0,0.1);
257
- }
258
-
259
- .answer-content {
260
- margin-bottom: 15px;
261
- line-height: 1.6;
262
- color: #2c3e50;
263
- font-size: 1.1em;
264
- }
265
-
266
- .main-concept {
267
- background-color: #e3f2fd;
268
- padding: 12px 16px;
269
- border-radius: 8px;
270
- color: #1976d2;
271
- font-size: 0.95em;
272
- margin-top: 15px;
273
- border: 1px solid rgba(25, 118, 210, 0.1);
274
- }
275
-
276
- .main-concept strong {
277
- color: #1565c0;
278
- font-weight: 600;
279
- }
280
-
281
- /* Loading animation styles */
282
- .loading {
283
- padding: 20px;
284
- text-align: center;
285
- color: #666;
286
- font-size: 1.1em;
287
- position: relative;
288
- }
289
-
290
- .loading:after {
291
- content: '...';
292
- position: absolute;
293
- animation: dots 1.5s steps(5, end) infinite;
294
- }
295
-
296
- @keyframes dots {
297
- 0%, 20% { content: '.'; }
298
- 40% { content: '..'; }
299
- 60% { content: '...'; }
300
- 80%, 100% { content: ''; }
301
- }
302
-
303
- .loading::before {
304
- content: '';
305
- display: block;
306
- width: 30px;
307
- height: 30px;
308
- border: 3px solid #3498db;
309
- border-top-color: transparent;
310
- border-radius: 50%;
311
- margin: 0 auto 10px;
312
- animation: spin 1s linear infinite;
313
- }
314
-
315
- @keyframes spin {
316
- to { transform: rotate(360deg); }
317
- }
318
-
319
- /* 概念详解面板样式 */
320
- .concept-explanation {
321
- padding: 20px;
322
- background: white;
323
- border-radius: 12px;
324
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
325
- }
326
-
327
- .explanation-content {
328
- line-height: 1.6;
329
- margin: 15px 0;
330
- color: #2c3e50;
331
- }
332
-
333
- .examples-section {
334
- margin-top: 20px;
335
- }
336
-
337
- .example-box {
338
- background: #f8f9fa;
339
- border-left: 4px solid #3498db;
340
- padding: 15px;
341
- margin: 15px 0;
342
- border-radius: 0 8px 8px 0;
343
- }
344
-
345
- .example-problem {
346
- margin-bottom: 10px;
347
- color: #2c3e50;
348
- }
349
-
350
- .example-solution {
351
- color: #34495e;
352
- padding: 10px;
353
- background: rgba(52, 152, 219, 0.05);
354
- border-radius: 4px;
355
- }
356
-
357
- /* 加载动画样式 */
358
- .loading {
359
- text-align: center;
360
- padding: 20px;
361
- }
362
-
363
- .loading-spinner {
364
- border: 3px solid #f3f3f3;
365
- border-top: 3px solid #3498db;
366
- border-radius: 50%;
367
- width: 30px;
368
- height: 30px;
369
- animation: spin 1s linear infinite;
370
- margin: 0 auto 10px;
371
- }
372
-
373
- @keyframes spin {
374
- 0% { transform: rotate(0deg); }
375
- 100% { transform: rotate(360deg); }
376
- }
377
-
378
- .loading-text {
379
- color: #666;
380
- font-size: 0.9em;
381
- }
382
-
383
- /* 新增的样式 */
384
- .concept-explanation-container {
385
- margin-top: 20px;
386
- padding: 15px;
387
- background: white;
388
- border-radius: 12px;
389
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
390
- transition: all 0.3s ease;
391
- max-height: 600px; /* 固定最大高度 */
392
- overflow-y: auto; /* 添加垂直滚动条 */
393
-
394
- /* 自定义滚动条样式 */
395
- scrollbar-width: thin;
396
- scrollbar-color: #3498db #f1f1f1;
397
- }
398
-
399
- /* Webkit浏览器的滚动条样式 */
400
- .concept-explanation-container::-webkit-scrollbar {
401
- width: 8px;
402
- }
403
-
404
- .concept-explanation-container::-webkit-scrollbar-track {
405
- background: #f1f1f1;
406
- border-radius: 4px;
407
- }
408
-
409
- .concept-explanation-container::-webkit-scrollbar-thumb {
410
- background: #3498db;
411
- border-radius: 4px;
412
- }
413
-
414
- .concept-explanation-container::-webkit-scrollbar-thumb:hover {
415
- background: #2980b9;
416
- }
417
-
418
- .concept-explanation-container h3 {
419
- color: #2c3e50;
420
- margin-bottom: 15px;
421
- position: sticky;
422
- top: 0;
423
- background: white;
424
- padding: 10px 0;
425
- z-index: 1;
426
- }
427
-
428
- /* 内容区域样式 */
429
- .card-explanation {
430
- padding: 20px;
431
- background: white;
432
- border-radius: 12px;
433
- }
434
-
435
- .explanation-section, .key-points-section, .examples-section,
436
- .practice-section, .resources-section {
437
- margin-top: 20px;
438
- padding: 15px;
439
- background: #f8f9fa;
440
- border-radius: 8px;
441
- }
442
-
443
- .explanation-section h4, .key-points-section h4,
444
- .examples-section h4, .practice-section h4,
445
- .resources-section h4 {
446
- color: #2c3e50;
447
- margin-bottom: 10px;
448
- }
449
-
450
- /* 修改generate_card_explanation函数中的标题文本 */
451
- .explanation-section h4:before { content: "📚 Concept Explanation"; }
452
- .key-points-section h4:before { content: "🎯 Key Points"; }
453
- .examples-section h4:before { content: "📝 Example Analysis"; }
454
- .practice-section h4:before { content: "✍️ Practice Problems"; }
455
- .resources-section h4:before { content: "📚 Learning Resources"; }
456
-
457
- /* 加载动画容器 */
458
- .loading-container {
459
- display: flex;
460
- flex-direction: column;
461
- align-items: center;
462
- justify-content: center;
463
- padding: 40px;
464
- background: white;
465
- border-radius: 12px;
466
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
467
- }
468
-
469
- /* 加载动画旋转器 */
470
- .loading-spinner {
471
- width: 50px;
472
- height: 50px;
473
- border: 4px solid #f3f3f3;
474
- border-top: 4px solid #3498db;
475
- border-radius: 50%;
476
- animation: spin 1s linear infinite;
477
- margin-bottom: 20px;
478
- }
479
-
480
- /* 加载文本 */
481
- .loading-text {
482
- color: #666;
483
- font-size: 1.1em;
484
- margin-top: 10px;
485
- }
486
 
487
- /* 旋转动画 */
488
- @keyframes spin {
489
- 0% { transform: rotate(0deg); }
490
- 100% { transform: rotate(360deg); }
491
- }
492
- """
493
 
494
  # Custom JavaScript code
495
  custom_js = """
@@ -1698,11 +1246,4 @@ def create_interface():
1698
  if __name__ == "__main__":
1699
  demo = create_interface()
1700
 
1701
- # 检查是否在Hugging Face空间中运行
1702
- if os.getenv("SPACE_ID"):
1703
- # Hugging Face空间环境
1704
- demo.launch()
1705
- else:
1706
- # 本地环境
1707
- import uvicorn
1708
- uvicorn.run(app, host="0.0.0.0", port=7861)
 
13
  from fastapi.responses import JSONResponse
14
  import json
15
 
16
+ def ensure_assets_directory():
17
+ """确保assets目录存在并包含必要的静态文件"""
18
+ # 创建assets目录
19
+ os.makedirs("assets", exist_ok=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
+ # 将CSS内容写入文件
22
+ css_path = os.path.join("assets", "style.css")
23
+ if not os.path.exists(css_path):
24
+ with open(css_path, "w", encoding="utf-8") as f:
25
+ f.write(custom_css) # 使用之前定义的custom_css内容
26
+
27
+ # 读取CSS文件
28
+ def load_css():
29
+ """读取CSS文件内容"""
30
+ css_path = os.path.join("assets", "style.css")
31
+ try:
32
+ with open(css_path, "r", encoding="utf-8") as f:
33
+ return f.read()
34
+ except Exception as e:
35
+ print(f"读取CSS文件失败: {str(e)}")
36
+ return "" # 如果读取失败,返回空字符串
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
+ # 在应用启动时初始化
39
+ ensure_assets_directory()
40
+ custom_css = load_css()
 
 
 
41
 
42
  # Custom JavaScript code
43
  custom_js = """
 
1246
  if __name__ == "__main__":
1247
  demo = create_interface()
1248
 
1249
+ demo.launch()
 
 
 
 
 
 
 
assets/script.js ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Handle concept card clicks
2
+ function conceptClick(conceptId) {
3
+ // Find the hidden input field and update its value
4
+ const conceptSelection = document.getElementById('concept-selection');
5
+ if (conceptSelection) {
6
+ conceptSelection.value = conceptId;
7
+ conceptSelection.dispatchEvent(new Event('input', { bubbles: true }));
8
+
9
+ // Highlight the selected card
10
+ document.querySelectorAll('.concept-card').forEach(card => {
11
+ card.classList.remove('selected-card');
12
+ if (card.getAttribute('data-concept-id') === conceptId) {
13
+ card.classList.add('selected-card');
14
+ }
15
+ });
16
+ }
17
+ }
18
+
19
+ // Enhance image display after loading
20
+ document.addEventListener('DOMContentLoaded', function() {
21
+ const graphContainer = document.getElementById('concept-graph');
22
+ if (graphContainer) {
23
+ const observer = new MutationObserver(function(mutations) {
24
+ mutations.forEach(function(mutation) {
25
+ if (mutation.addedNodes && mutation.addedNodes.length > 0) {
26
+ const img = graphContainer.querySelector('img');
27
+ if (img) {
28
+ img.style.maxWidth = '100%';
29
+ img.style.height = 'auto';
30
+ img.style.borderRadius = '8px';
31
+ img.style.boxShadow = '0 4px 8px rgba(0,0,0,0.1)';
32
+ }
33
+ }
34
+ });
35
+ });
36
+
37
+ observer.observe(graphContainer, { childList: true, subtree: true });
38
+ }
39
+ });
assets/style.css ADDED
@@ -0,0 +1,474 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Global styles */
2
+ body {
3
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;
4
+ color: #333;
5
+ background-color: #f7f9fc;
6
+ }
7
+
8
+ /* Heading styles */
9
+ h1 {
10
+ color: #2c3e50;
11
+ font-weight: 700;
12
+ margin-bottom: 1rem;
13
+ }
14
+
15
+ h2, h3, h4 {
16
+ color: #3498db;
17
+ font-weight: 600;
18
+ }
19
+
20
+ /* Button styles */
21
+ button.primary {
22
+ background: linear-gradient(135deg, #3498db, #2980b9);
23
+ border: none;
24
+ box-shadow: 0 4px 6px rgba(52, 152, 219, 0.3);
25
+ }
26
+
27
+ button.secondary {
28
+ background: #ecf0f1;
29
+ color: #2980b9;
30
+ border: 1px solid #bdc3c7;
31
+ }
32
+
33
+ button:hover {
34
+ transform: translateY(-2px);
35
+ box-shadow: 0 6px 8px rgba(0, 0, 0, 0.1);
36
+ transition: all 0.3s ease;
37
+ }
38
+
39
+ /* Input fields enhancement */
40
+ input, textarea, select {
41
+ border: 1px solid #ddd;
42
+ border-radius: 8px;
43
+ padding: 10px;
44
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05);
45
+ transition: all 0.3s ease;
46
+ }
47
+
48
+ input:focus, textarea:focus, select:focus {
49
+ border-color: #3498db;
50
+ box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.25);
51
+ }
52
+
53
+ /* Tab styles */
54
+ .tabs {
55
+ border-bottom: 2px solid #e0e0e0;
56
+ }
57
+
58
+ .tab-selected {
59
+ color: #3498db;
60
+ border-bottom: 2px solid #3498db;
61
+ }
62
+
63
+ /* Concept card styles */
64
+ .concept-card {
65
+ transition: all 0.3s ease;
66
+ border: 1px solid #e0e0e0;
67
+ border-radius: 12px;
68
+ padding: 16px;
69
+ margin-bottom: 16px;
70
+ cursor: pointer;
71
+ background-color: #fff;
72
+ box-shadow: 0 2px 5px rgba(0,0,0,0.05);
73
+ }
74
+
75
+ .concept-card:hover {
76
+ box-shadow: 0 5px 15px rgba(0,0,0,0.1);
77
+ transform: translateY(-3px);
78
+ border-color: #bdc3c7;
79
+ }
80
+
81
+ .selected-card {
82
+ border-color: #3498db;
83
+ background-color: rgba(52, 152, 219, 0.05);
84
+ box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.3);
85
+ }
86
+
87
+ .concept-title {
88
+ font-weight: bold;
89
+ margin-bottom: 8px;
90
+ color: #2c3e50;
91
+ font-size: 1.1em;
92
+ }
93
+
94
+ .concept-desc {
95
+ font-size: 0.95em;
96
+ color: #7f8c8d;
97
+ line-height: 1.5;
98
+ }
99
+
100
+ /* Knowledge graph styles */
101
+ #concept-graph {
102
+ background-color: #fff;
103
+ border-radius: 12px;
104
+ padding: 16px;
105
+ box-shadow: 0 2px 10px rgba(0,0,0,0.05);
106
+ }
107
+
108
+ #concept-graph img {
109
+ max-width: 100%;
110
+ height: auto;
111
+ border-radius: 8px;
112
+ box-shadow: 0 4px 15px rgba(0,0,0,0.1);
113
+ transition: all 0.3s ease;
114
+ }
115
+
116
+ #concept-graph img:hover {
117
+ box-shadow: 0 8px 25px rgba(0,0,0,0.15);
118
+ }
119
+
120
+ /* Example box styles */
121
+ .example-box {
122
+ background-color: #f1f8fe;
123
+ border-left: 4px solid #3498db;
124
+ padding: 15px;
125
+ margin: 15px 0;
126
+ border-radius: 0 8px 8px 0;
127
+ }
128
+
129
+ .example-box h4 {
130
+ margin-top: 0;
131
+ color: #2980b9;
132
+ }
133
+
134
+ /* Resource item styles */
135
+ .resource-item {
136
+ padding: 12px;
137
+ margin: 10px 0;
138
+ border-bottom: 1px dashed #e0e0e0;
139
+ transition: all 0.2s ease;
140
+ }
141
+
142
+ .resource-item:hover {
143
+ background-color: #f9f9f9;
144
+ }
145
+
146
+ /* Details and answers styles */
147
+ details {
148
+ margin: 10px 0;
149
+ padding: 10px;
150
+ border: 1px solid #e0e0e0;
151
+ border-radius: 8px;
152
+ background-color: #f9f9f9;
153
+ }
154
+
155
+ summary {
156
+ cursor: pointer;
157
+ color: #3498db;
158
+ font-weight: 600;
159
+ padding: 5px;
160
+ }
161
+
162
+ summary:hover {
163
+ color: #2980b9;
164
+ }
165
+
166
+ /* Layout container styles */
167
+ .container {
168
+ background-color: #fff;
169
+ border-radius: 12px;
170
+ padding: 20px;
171
+ box-shadow: 0 4px 6px rgba(0,0,0,0.05);
172
+ margin-bottom: 20px;
173
+ }
174
+
175
+ /* Responsive adjustments */
176
+ @media (max-width: 768px) {
177
+ .concept-card {
178
+ padding: 12px;
179
+ }
180
+
181
+ .example-box {
182
+ padding: 12px;
183
+ }
184
+ }
185
+
186
+ /* Answer box styles */
187
+ .answer-box {
188
+ background-color: #f8f9fa;
189
+ border-radius: 12px;
190
+ padding: 20px;
191
+ margin: 15px 0;
192
+ border: 1px solid #e9ecef;
193
+ box-shadow: 0 2px 4px rgba(0,0,0,0.05);
194
+ }
195
+
196
+ .answer-content {
197
+ margin-bottom: 15px;
198
+ line-height: 1.6;
199
+ color: #2c3e50;
200
+ }
201
+
202
+ .answer-content h4 {
203
+ color: #3498db;
204
+ margin-top: 0;
205
+ margin-bottom: 10px;
206
+ }
207
+
208
+ .main-concept {
209
+ background-color: #e3f2fd;
210
+ padding: 10px 15px;
211
+ border-radius: 8px;
212
+ color: #1976d2;
213
+ font-size: 0.95em;
214
+ }
215
+
216
+ .main-concept strong {
217
+ color: #1565c0;
218
+ }
219
+
220
+ /* Answer section styles */
221
+ .answer-section {
222
+ margin-top: 20px;
223
+ background: white;
224
+ border-radius: 15px;
225
+ padding: 20px;
226
+ }
227
+
228
+ .answer-box {
229
+ background-color: #f8f9fa;
230
+ border-radius: 12px;
231
+ padding: 20px;
232
+ margin: 15px 0;
233
+ border: 1px solid #e9ecef;
234
+ box-shadow: 0 2px 4px rgba(0,0,0,0.05);
235
+ transition: all 0.3s ease;
236
+ }
237
+
238
+ .answer-box:hover {
239
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);
240
+ }
241
+
242
+ .answer-content {
243
+ margin-bottom: 15px;
244
+ line-height: 1.6;
245
+ color: #2c3e50;
246
+ font-size: 1.1em;
247
+ }
248
+
249
+ .main-concept {
250
+ background-color: #e3f2fd;
251
+ padding: 12px 16px;
252
+ border-radius: 8px;
253
+ color: #1976d2;
254
+ font-size: 0.95em;
255
+ margin-top: 15px;
256
+ border: 1px solid rgba(25, 118, 210, 0.1);
257
+ }
258
+
259
+ .main-concept strong {
260
+ color: #1565c0;
261
+ font-weight: 600;
262
+ }
263
+
264
+ /* Loading animation styles */
265
+ .loading {
266
+ padding: 20px;
267
+ text-align: center;
268
+ color: #666;
269
+ font-size: 1.1em;
270
+ position: relative;
271
+ }
272
+
273
+ .loading:after {
274
+ content: '...';
275
+ position: absolute;
276
+ animation: dots 1.5s steps(5, end) infinite;
277
+ }
278
+
279
+ @keyframes dots {
280
+ 0%, 20% { content: '.'; }
281
+ 40% { content: '..'; }
282
+ 60% { content: '...'; }
283
+ 80%, 100% { content: ''; }
284
+ }
285
+
286
+ .loading::before {
287
+ content: '';
288
+ display: block;
289
+ width: 30px;
290
+ height: 30px;
291
+ border: 3px solid #3498db;
292
+ border-top-color: transparent;
293
+ border-radius: 50%;
294
+ margin: 0 auto 10px;
295
+ animation: spin 1s linear infinite;
296
+ }
297
+
298
+ @keyframes spin {
299
+ to { transform: rotate(360deg); }
300
+ }
301
+
302
+ /* 概念详解面板样式 */
303
+ .concept-explanation {
304
+ padding: 20px;
305
+ background: white;
306
+ border-radius: 12px;
307
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
308
+ }
309
+
310
+ .explanation-content {
311
+ line-height: 1.6;
312
+ margin: 15px 0;
313
+ color: #2c3e50;
314
+ }
315
+
316
+ .examples-section {
317
+ margin-top: 20px;
318
+ }
319
+
320
+ .example-box {
321
+ background: #f8f9fa;
322
+ border-left: 4px solid #3498db;
323
+ padding: 15px;
324
+ margin: 15px 0;
325
+ border-radius: 0 8px 8px 0;
326
+ }
327
+
328
+ .example-problem {
329
+ margin-bottom: 10px;
330
+ color: #2c3e50;
331
+ }
332
+
333
+ .example-solution {
334
+ color: #34495e;
335
+ padding: 10px;
336
+ background: rgba(52, 152, 219, 0.05);
337
+ border-radius: 4px;
338
+ }
339
+
340
+ /* 加载动画样式 */
341
+ .loading {
342
+ text-align: center;
343
+ padding: 20px;
344
+ }
345
+
346
+ .loading-spinner {
347
+ border: 3px solid #f3f3f3;
348
+ border-top: 3px solid #3498db;
349
+ border-radius: 50%;
350
+ width: 30px;
351
+ height: 30px;
352
+ animation: spin 1s linear infinite;
353
+ margin: 0 auto 10px;
354
+ }
355
+
356
+ @keyframes spin {
357
+ 0% { transform: rotate(0deg); }
358
+ 100% { transform: rotate(360deg); }
359
+ }
360
+
361
+ .loading-text {
362
+ color: #666;
363
+ font-size: 0.9em;
364
+ }
365
+
366
+ /* 新增的样式 */
367
+ .concept-explanation-container {
368
+ margin-top: 20px;
369
+ padding: 15px;
370
+ background: white;
371
+ border-radius: 12px;
372
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
373
+ transition: all 0.3s ease;
374
+ max-height: 600px; /* 固定最大高度 */
375
+ overflow-y: auto; /* 添加垂直滚动条 */
376
+
377
+ /* 自定义滚动条样式 */
378
+ scrollbar-width: thin;
379
+ scrollbar-color: #3498db #f1f1f1;
380
+ }
381
+
382
+ /* Webkit浏览器的滚动条样式 */
383
+ .concept-explanation-container::-webkit-scrollbar {
384
+ width: 8px;
385
+ }
386
+
387
+ .concept-explanation-container::-webkit-scrollbar-track {
388
+ background: #f1f1f1;
389
+ border-radius: 4px;
390
+ }
391
+
392
+ .concept-explanation-container::-webkit-scrollbar-thumb {
393
+ background: #3498db;
394
+ border-radius: 4px;
395
+ }
396
+
397
+ .concept-explanation-container::-webkit-scrollbar-thumb:hover {
398
+ background: #2980b9;
399
+ }
400
+
401
+ .concept-explanation-container h3 {
402
+ color: #2c3e50;
403
+ margin-bottom: 15px;
404
+ position: sticky;
405
+ top: 0;
406
+ background: white;
407
+ padding: 10px 0;
408
+ z-index: 1;
409
+ }
410
+
411
+ /* 内容区域样式 */
412
+ .card-explanation {
413
+ padding: 20px;
414
+ background: white;
415
+ border-radius: 12px;
416
+ }
417
+
418
+ .explanation-section, .key-points-section, .examples-section,
419
+ .practice-section, .resources-section {
420
+ margin-top: 20px;
421
+ padding: 15px;
422
+ background: #f8f9fa;
423
+ border-radius: 8px;
424
+ }
425
+
426
+ .explanation-section h4, .key-points-section h4,
427
+ .examples-section h4, .practice-section h4,
428
+ .resources-section h4 {
429
+ color: #2c3e50;
430
+ margin-bottom: 10px;
431
+ }
432
+
433
+ /* 修改generate_card_explanation函数中的标题文本 */
434
+ .explanation-section h4:before { content: "📚 Concept Explanation"; }
435
+ .key-points-section h4:before { content: "🎯 Key Points"; }
436
+ .examples-section h4:before { content: "📝 Example Analysis"; }
437
+ .practice-section h4:before { content: "✍️ Practice Problems"; }
438
+ .resources-section h4:before { content: "📚 Learning Resources"; }
439
+
440
+ /* 加载动画容器 */
441
+ .loading-container {
442
+ display: flex;
443
+ flex-direction: column;
444
+ align-items: center;
445
+ justify-content: center;
446
+ padding: 40px;
447
+ background: white;
448
+ border-radius: 12px;
449
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
450
+ }
451
+
452
+ /* 加载动画旋转器 */
453
+ .loading-spinner {
454
+ width: 50px;
455
+ height: 50px;
456
+ border: 4px solid #f3f3f3;
457
+ border-top: 4px solid #3498db;
458
+ border-radius: 50%;
459
+ animation: spin 1s linear infinite;
460
+ margin-bottom: 20px;
461
+ }
462
+
463
+ /* 加载文本 */
464
+ .loading-text {
465
+ color: #666;
466
+ font-size: 1.1em;
467
+ margin-top: 10px;
468
+ }
469
+
470
+ /* 旋转动画 */
471
+ @keyframes spin {
472
+ 0% { transform: rotate(0deg); }
473
+ 100% { transform: rotate(360deg); }
474
+ }
requirements.txt CHANGED
@@ -1,8 +1,299 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  fastapi==0.115.12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  gradio==5.23.1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  langchain==0.0.352
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  matplotlib==3.7.3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  networkx==3.1
6
- openai==1.68.2
7
- pydantic==2.10.6
8
- uvicorn==0.34.0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ accelerate==0.25.0
2
+ acres==0.1.0
3
+ aiofiles==23.2.1
4
+ aiohttp==3.9.1
5
+ aiosignal==1.3.1
6
+ altair==5.5.0
7
+ amightygirl.paapi5-python-sdk==1.0.0
8
+ annotated-types==0.6.0
9
+ anyio==3.7.1
10
+ anytree==2.12.1
11
+ APScheduler==3.10.4
12
+ asttokens==3.0.0
13
+ async-timeout==4.0.3
14
+ attrs==23.1.0
15
+ Authlib==1.3.2
16
+ backcall==0.2.0
17
+ bcrypt==4.2.0
18
+ beautifulsoup4==4.12.2
19
+ BingImageCreator==0.5.0
20
+ bleach==6.2.0
21
+ blinker==1.8.2
22
+ blis==1.0.1
23
+ boto3==1.35.52
24
+ botocore==1.35.52
25
+ cachelib==0.9.0
26
+ catalogue==2.0.10
27
+ certifi==2024.8.30
28
+ cffi==1.16.0
29
+ chardet==5.2.0
30
+ charset-normalizer==3.3.2
31
+ ci-info==0.3.0
32
+ click==8.1.7
33
+ cloudpathlib==0.20.0
34
+ command-not-found==0.3
35
+ confection==0.1.5
36
+ configobj==5.0.9
37
+ configparser==7.1.0
38
+ contourpy==1.3.1
39
+ cryptography==3.4.8
40
+ curl-cffi==0.5.10
41
+ cycler==0.12.1
42
+ cymem==2.0.10
43
+ dataclasses-json==0.5.14
44
+ dbus-python==1.2.18
45
+ decorator==5.1.1
46
+ defusedxml==0.7.1
47
+ Deprecated==1.2.14
48
+ diffusers==0.24.0
49
+ distro==1.7.0
50
+ distro-info===1.1build1
51
+ docopt==0.6.2
52
+ duckduckgo-search==4.1.0
53
+ EdgeGPT==0.6.10
54
+ et_xmlfile==2.0.0
55
+ etelemetry==0.3.1
56
+ exceptiongroup==1.2.0
57
+ executing==2.2.0
58
+ faiss-cpu==1.7.4
59
+ faiss-gpu==1.7.2
60
  fastapi==0.115.12
61
+ fastjsonschema==2.21.1
62
+ ffmpy==0.5.0
63
+ filelock==3.13.1
64
+ fitz==0.0.1.dev2
65
+ Flask==3.0.3
66
+ Flask-APScheduler==1.13.1
67
+ Flask-Caching==2.3.0
68
+ Flask-Cors==5.0.0
69
+ Flask-JWT-Extended==4.6.0
70
+ Flask-Limiter==3.8.0
71
+ Flask-WTF==1.2.2
72
+ fonttools==4.55.0
73
+ frontend==0.0.3
74
+ frozenlist==1.4.1
75
+ fsspec==2023.12.2
76
+ GoogleBard==2.1.0
77
+ gpt4-openai-api==0.9.0
78
  gradio==5.23.1
79
+ gradio_client==1.8.0
80
+ greenlet==3.0.1
81
+ groovy==0.1.2
82
+ gunicorn==23.0.0
83
+ gyp==0.1
84
+ h11==0.14.0
85
+ httpcore==1.0.2
86
+ httplib2==0.20.2
87
+ httpx==0.25.2
88
+ hugchat==0.3.8
89
+ huggingface-hub==0.29.3
90
+ idna==3.8
91
+ importlib-metadata==4.6.4
92
+ importlib_resources==6.4.5
93
+ iniconfig==2.0.0
94
+ ipython==8.12.3
95
+ isodate==0.6.1
96
+ itsdangerous==2.2.0
97
+ jedi==0.19.2
98
+ jeepney==0.7.1
99
+ Jinja2==3.1.2
100
+ jmespath==1.0.1
101
+ joblib==1.4.2
102
+ jsonpatch==1.33
103
+ jsonpointer==2.4
104
+ jsonschema==4.23.0
105
+ jsonschema-specifications==2024.10.1
106
+ jupyter_client==8.6.3
107
+ jupyter_core==5.7.2
108
+ jupyterlab_pygments==0.3.0
109
+ keyring==23.5.0
110
+ kiwisolver==1.4.7
111
  langchain==0.0.352
112
+ langchain-community==0.0.3
113
+ langchain-core==0.1.1
114
+ langchain-experimental==0.0.47
115
+ langcodes==3.5.0
116
+ langsmith==0.0.71
117
+ language_data==1.3.0
118
+ lark==1.1.8
119
+ # Editable install with no version control (latex_marker==0.1)
120
+ -e /mnt/d/知识库/Obsidian Vault/Upenn学习资源/Upenn 课程/HW 8000/tex2bbox
121
+ launchpadlib==1.10.16
122
+ lazr.restfulclient==0.14.4
123
+ lazr.uri==1.0.6
124
+ limits==3.13.0
125
+ looseversion==1.3.0
126
+ lxml==4.9.3
127
+ marisa-trie==1.2.1
128
+ markdown-it-py==3.0.0
129
+ markdownify==0.11.6
130
+ MarkupSafe==2.1.3
131
+ marshmallow==3.20.1
132
  matplotlib==3.7.3
133
+ matplotlib-inline==0.1.7
134
+ mdurl==0.1.2
135
+ mistune==3.1.3
136
+ more-itertools==8.10.0
137
+ mpmath==1.3.0
138
+ multidict==6.0.4
139
+ murmurhash==1.0.11
140
+ mypy-extensions==1.0.0
141
+ narwhals==1.32.0
142
+ nbclient==0.10.2
143
+ nbconvert==7.16.6
144
+ nbformat==5.10.4
145
+ nest-asyncio==1.5.8
146
+ netifaces==0.11.0
147
  networkx==3.1
148
+ nibabel==5.3.2
149
+ nipype==1.9.1
150
+ nltk==3.9.1
151
+ numexpr==2.8.8
152
+ numpy==1.26.0
153
+ nvidia-cublas-cu12==12.1.3.1
154
+ nvidia-cuda-cupti-cu12==12.1.105
155
+ nvidia-cuda-nvrtc-cu12==12.1.105
156
+ nvidia-cuda-runtime-cu12==12.1.105
157
+ nvidia-cudnn-cu12==8.9.2.26
158
+ nvidia-cufft-cu12==11.0.2.54
159
+ nvidia-curand-cu12==10.3.2.106
160
+ nvidia-cusolver-cu12==11.4.5.107
161
+ nvidia-cusparse-cu12==12.1.0.106
162
+ nvidia-nccl-cu12==2.18.1
163
+ nvidia-nvjitlink-cu12==12.3.101
164
+ nvidia-nvtx-cu12==12.1.105
165
+ oauthlib==3.2.0
166
+ openai==1.12.0
167
+ openapi-schema-pydantic==1.2.4
168
+ openpyxl==3.1.5
169
+ ordered-set==4.1.0
170
+ orjson==3.10.16
171
+ outcome==1.3.0.post0
172
+ packaging==23.2
173
+ pandas==2.1.4
174
+ pandocfilters==1.5.1
175
+ parso==0.8.4
176
+ pathlib==1.0.1
177
+ pexpect==4.9.0
178
+ pickleshare==0.7.5
179
+ Pillow==10.0.0
180
+ pipreqs==0.5.0
181
+ platformdirs==4.3.7
182
+ playwright==1.40.0
183
+ pluggy==1.3.0
184
+ preshed==3.0.9
185
+ prompt-toolkit==3.0.43
186
+ prov==2.0.1
187
+ psutil==5.9.6
188
+ ptyprocess==0.7.0
189
+ pure_eval==0.2.3
190
+ puremagic==1.28
191
+ py==1.11.0
192
+ pycparser==2.21
193
+ pydantic==2.4.2
194
+ pydantic_core==2.10.1
195
+ pydot==3.0.3
196
+ pydub==0.25.1
197
+ pyee==11.0.1
198
+ Pygments==2.17.2
199
+ PyGObject==3.42.1
200
+ PyJWT==2.3.0
201
+ PyLaTeX==1.4.2
202
+ pylatexenc==2.10
203
+ PyMuPDF==1.25.0
204
+ PyMySQL==1.1.1
205
+ pyparsing==3.2.0
206
+ PySocks==1.7.1
207
+ pytest==7.4.3
208
+ pytest-base-url==2.0.0
209
+ pytest-playwright==0.4.3
210
+ python-apt==2.4.0+ubuntu1
211
+ python-dateutil==2.9.0.post0
212
+ python-dotenv==1.0.0
213
+ python-multipart==0.0.20
214
+ python-slugify==8.0.1
215
+ pytz==2023.3.post1
216
+ pyxnat==1.6.2
217
+ PyYAML==5.4.1
218
+ pyzmq==26.3.0
219
+ rdflib==6.3.2
220
+ redis==5.2.0
221
+ referencing==0.36.2
222
+ regex==2023.10.3
223
+ requests==2.31.0
224
+ requests-toolbelt==1.0.0
225
+ retry==0.9.2
226
+ rich==13.7.0
227
+ rpds-py==0.23.1
228
+ ruff==0.11.2
229
+ s3transfer==0.10.3
230
+ safehttpx==0.1.6
231
+ safetensors==0.4.1
232
+ scikit-learn==1.5.2
233
+ scipy==1.14.1
234
+ seaborn==0.13.2
235
+ SecretStorage==3.3.1
236
+ selenium==4.16.0
237
+ semantic-version==2.10.0
238
+ sentence-transformers==3.3.0
239
+ shellingham==1.5.4
240
+ simplejson==3.19.3
241
+ six==1.16.0
242
+ smart-open==7.0.5
243
+ sniffio==1.3.0
244
+ socksio==1.0.0
245
+ sortedcontainers==2.4.0
246
+ soupsieve==2.5
247
+ spacy==3.8.2
248
+ spacy-legacy==3.0.12
249
+ spacy-loggers==1.0.5
250
+ SQLAlchemy==2.0.23
251
+ srsly==2.4.8
252
+ stack-data==0.6.3
253
+ starlette==0.46.1
254
+ sympy==1.12
255
+ systemd-python==234
256
+ tabulate==0.9.0
257
+ tenacity==8.2.3
258
+ text-unidecode==1.3
259
+ thinc==8.3.2
260
+ threadpoolctl==3.5.0
261
+ tiktoken==0.8.0
262
+ tinycss2==1.4.0
263
+ tokenizers==0.20.3
264
+ tomli==2.0.1
265
+ tomlkit==0.12.0
266
+ torch==2.1.2
267
+ tornado==6.4.2
268
+ tqdm==4.66.1
269
+ traitlets==5.14.3
270
+ traits==6.4.3
271
+ transformers==4.46.2
272
+ trio==0.23.2
273
+ trio-websocket==0.11.1
274
+ triton==2.1.0
275
+ typer==0.14.0
276
+ typing-inspect==0.9.0
277
+ typing_extensions==4.12.2
278
+ tzdata==2023.3
279
+ tzlocal==5.2
280
+ ubuntu-advantage-tools==8001
281
+ ufw==0.36.1
282
+ unattended-upgrades==0.1
283
+ undetected-chromedriver==3.5.4
284
+ urllib3==2.2.2
285
+ uvicorn==0.23.2
286
+ wadllib==1.3.6
287
+ wasabi==1.1.3
288
+ wcwidth==0.2.12
289
+ weasel==0.4.1
290
+ webencodings==0.5.1
291
+ websockets==11.0.3
292
+ Werkzeug==3.0.4
293
+ wikipedia==1.4.0
294
+ wrapt==1.16.0
295
+ wsproto==1.2.0
296
+ WTForms==3.2.1
297
+ yarg==0.1.9
298
+ yarl==1.9.4
299
+ zipp==1.0.0
style.css ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Global styles */
2
+ :root {
3
+ --primary-color: #3498db;
4
+ --secondary-color: #2c3e50;
5
+ --background-color: #f7f9fc;
6
+ --border-color: #e0e0e0;
7
+ --shadow-color: rgba(0,0,0,0.1);
8
+ }
9
+
10
+ body {
11
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif !important;
12
+ color: #333 !important;
13
+ background-color: var(--background-color) !important;
14
+ }
15
+
16
+ /* 强制应用容器样式 */
17
+ .gradio-container {
18
+ max-width: 100% !important;
19
+ padding: 0 !important;
20
+ }
21
+
22
+ /* 确保section样式 */
23
+ .section {
24
+ background: white !important;
25
+ border-radius: 15px !important;
26
+ padding: 20px !important;
27
+ margin-bottom: 20px !important;
28
+ box-shadow: 0 2px 4px var(--shadow-color) !important;
29
+ }
30
+
31
+ /* 确保卡片样式 */
32
+ .concept-card {
33
+ transition: all 0.3s ease !important;
34
+ border: 1px solid var(--border-color) !important;
35
+ border-radius: 12px !important;
36
+ padding: 16px !important;
37
+ margin-bottom: 16px !important;
38
+ cursor: pointer !important;
39
+ background-color: white !important;
40
+ box-shadow: 0 2px 5px var(--shadow-color) !important;
41
+ }
42
+
43
+ .concept-card:hover {
44
+ box-shadow: 0 5px 15px var(--shadow-color) !important;
45
+ transform: translateY(-3px) !important;
46
+ }
47
+
48
+ /* 其他样式保持不变,但添加 !important */
visualization.py CHANGED
@@ -16,7 +16,7 @@ matplotlib.use('Agg')
16
  # Set up Chinese font support
17
  # Try to find suitable Chinese fonts
18
  font_found = False
19
- chinese_fonts = ['DejaVu Sans', 'SimHei', 'Microsoft YaHei', 'WenQuanYi Micro Hei', 'AR PL UMing CN', 'STSong', 'NSimSun', 'FangSong', 'KaiTi']
20
  for font in chinese_fonts:
21
  try:
22
  matplotlib.font_manager.findfont(font)
 
16
  # Set up Chinese font support
17
  # Try to find suitable Chinese fonts
18
  font_found = False
19
+ chinese_fonts = ['SimHei', 'Microsoft YaHei', 'WenQuanYi Micro Hei', 'AR PL UMing CN', 'STSong', 'NSimSun', 'FangSong', 'KaiTi']
20
  for font in chinese_fonts:
21
  try:
22
  matplotlib.font_manager.findfont(font)